[6a3a178] | 1 | import { Document, scalarOptions } from './index'
|
---|
| 2 | import { CST } from './parse-cst'
|
---|
| 3 | import { Type } from './util'
|
---|
| 4 |
|
---|
| 5 | export const binaryOptions: scalarOptions.Binary
|
---|
| 6 | export const boolOptions: scalarOptions.Bool
|
---|
| 7 | export const intOptions: scalarOptions.Int
|
---|
| 8 | export const nullOptions: scalarOptions.Null
|
---|
| 9 | export const strOptions: scalarOptions.Str
|
---|
| 10 |
|
---|
| 11 | export class Schema {
|
---|
| 12 | /** Default: `'tag:yaml.org,2002:'` */
|
---|
| 13 | static defaultPrefix: string
|
---|
| 14 | static defaultTags: {
|
---|
| 15 | /** Default: `'tag:yaml.org,2002:map'` */
|
---|
| 16 | MAP: string
|
---|
| 17 | /** Default: `'tag:yaml.org,2002:seq'` */
|
---|
| 18 | SEQ: string
|
---|
| 19 | /** Default: `'tag:yaml.org,2002:str'` */
|
---|
| 20 | STR: string
|
---|
| 21 | }
|
---|
| 22 | constructor(options: Schema.Options)
|
---|
| 23 | /**
|
---|
| 24 | * Convert any value into a `Node` using this schema, recursively turning
|
---|
| 25 | * objects into collections.
|
---|
| 26 | *
|
---|
| 27 | * @param wrapScalars If `true`, also wraps plain values in `Scalar` objects;
|
---|
| 28 | * if undefined or `false` and `value` is not an object, it will be returned
|
---|
| 29 | * directly.
|
---|
| 30 | * @param tag Use to specify the collection type, e.g. `"!!omap"`. Note that
|
---|
| 31 | * this requires the corresponding tag to be available in this schema.
|
---|
| 32 | */
|
---|
| 33 | createNode(
|
---|
| 34 | value: any,
|
---|
| 35 | wrapScalars?: boolean,
|
---|
| 36 | tag?: string,
|
---|
| 37 | ctx?: Schema.CreateNodeContext
|
---|
| 38 | ): Node
|
---|
| 39 | /**
|
---|
| 40 | * Convert a key and a value into a `Pair` using this schema, recursively
|
---|
| 41 | * wrapping all values as `Scalar` or `Collection` nodes.
|
---|
| 42 | *
|
---|
| 43 | * @param ctx To not wrap scalars, use a context `{ wrapScalars: false }`
|
---|
| 44 | */
|
---|
| 45 | createPair(key: any, value: any, ctx?: Schema.CreateNodeContext): Pair
|
---|
| 46 | merge: boolean
|
---|
| 47 | name: Schema.Name
|
---|
| 48 | sortMapEntries: ((a: Pair, b: Pair) => number) | null
|
---|
| 49 | tags: Schema.Tag[]
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | export namespace Schema {
|
---|
| 53 | type Name = 'core' | 'failsafe' | 'json' | 'yaml-1.1'
|
---|
| 54 |
|
---|
| 55 | interface Options {
|
---|
| 56 | /**
|
---|
| 57 | * Array of additional tags to include in the schema, or a function that may
|
---|
| 58 | * modify the schema's base tag array.
|
---|
| 59 | */
|
---|
| 60 | customTags?: (TagId | Tag)[] | ((tags: Tag[]) => Tag[])
|
---|
| 61 | /**
|
---|
| 62 | * Enable support for `<<` merge keys.
|
---|
| 63 | *
|
---|
| 64 | * Default: `false` for YAML 1.2, `true` for earlier versions
|
---|
| 65 | */
|
---|
| 66 | merge?: boolean
|
---|
| 67 | /**
|
---|
| 68 | * The base schema to use.
|
---|
| 69 | *
|
---|
| 70 | * Default: `"core"` for YAML 1.2, `"yaml-1.1"` for earlier versions
|
---|
| 71 | */
|
---|
| 72 | schema?: Name
|
---|
| 73 | /**
|
---|
| 74 | * When stringifying, sort map entries. If `true`, sort by comparing key values with `<`.
|
---|
| 75 | *
|
---|
| 76 | * Default: `false`
|
---|
| 77 | */
|
---|
| 78 | sortMapEntries?: boolean | ((a: Pair, b: Pair) => number)
|
---|
| 79 | /**
|
---|
| 80 | * @deprecated Use `customTags` instead.
|
---|
| 81 | */
|
---|
| 82 | tags?: Options['customTags']
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | interface CreateNodeContext {
|
---|
| 86 | wrapScalars?: boolean
|
---|
| 87 | [key: string]: any
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | interface StringifyContext {
|
---|
| 91 | forceBlockIndent?: boolean
|
---|
| 92 | implicitKey?: boolean
|
---|
| 93 | indent?: string
|
---|
| 94 | indentAtStart?: number
|
---|
| 95 | inFlow?: boolean
|
---|
| 96 | [key: string]: any
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | type TagId =
|
---|
| 100 | | 'binary'
|
---|
| 101 | | 'bool'
|
---|
| 102 | | 'float'
|
---|
| 103 | | 'floatExp'
|
---|
| 104 | | 'floatNaN'
|
---|
| 105 | | 'floatTime'
|
---|
| 106 | | 'int'
|
---|
| 107 | | 'intHex'
|
---|
| 108 | | 'intOct'
|
---|
| 109 | | 'intTime'
|
---|
| 110 | | 'null'
|
---|
| 111 | | 'omap'
|
---|
| 112 | | 'pairs'
|
---|
| 113 | | 'set'
|
---|
| 114 | | 'timestamp'
|
---|
| 115 |
|
---|
| 116 | type Tag = CustomTag | DefaultTag
|
---|
| 117 |
|
---|
| 118 | interface BaseTag {
|
---|
| 119 | /**
|
---|
| 120 | * An optional factory function, used e.g. by collections when wrapping JS objects as AST nodes.
|
---|
| 121 | */
|
---|
| 122 | createNode?: (
|
---|
| 123 | schema: Schema,
|
---|
| 124 | value: any,
|
---|
| 125 | ctx: Schema.CreateNodeContext
|
---|
| 126 | ) => YAMLMap | YAMLSeq | Scalar
|
---|
| 127 | /**
|
---|
| 128 | * If a tag has multiple forms that should be parsed and/or stringified differently, use `format` to identify them.
|
---|
| 129 | */
|
---|
| 130 | format?: string
|
---|
| 131 | /**
|
---|
| 132 | * Used by `YAML.createNode` to detect your data type, e.g. using `typeof` or
|
---|
| 133 | * `instanceof`.
|
---|
| 134 | */
|
---|
| 135 | identify(value: any): boolean
|
---|
| 136 | /**
|
---|
| 137 | * The `Node` child class that implements this tag. Required for collections and tags that have overlapping JS representations.
|
---|
| 138 | */
|
---|
| 139 | nodeClass?: new () => any
|
---|
| 140 | /**
|
---|
| 141 | * Used by some tags to configure their stringification, where applicable.
|
---|
| 142 | */
|
---|
| 143 | options?: object
|
---|
| 144 | /**
|
---|
| 145 | * Optional function stringifying the AST node in the current context. If your
|
---|
| 146 | * data includes a suitable `.toString()` method, you can probably leave this
|
---|
| 147 | * undefined and use the default stringifier.
|
---|
| 148 | *
|
---|
| 149 | * @param item The node being stringified.
|
---|
| 150 | * @param ctx Contains the stringifying context variables.
|
---|
| 151 | * @param onComment Callback to signal that the stringifier includes the
|
---|
| 152 | * item's comment in its output.
|
---|
| 153 | * @param onChompKeep Callback to signal that the output uses a block scalar
|
---|
| 154 | * type with the `+` chomping indicator.
|
---|
| 155 | */
|
---|
| 156 | stringify?: (
|
---|
| 157 | item: Node,
|
---|
| 158 | ctx: Schema.StringifyContext,
|
---|
| 159 | onComment?: () => void,
|
---|
| 160 | onChompKeep?: () => void
|
---|
| 161 | ) => string
|
---|
| 162 | /**
|
---|
| 163 | * The identifier for your data type, with which its stringified form will be
|
---|
| 164 | * prefixed. Should either be a !-prefixed local `!tag`, or a fully qualified
|
---|
| 165 | * `tag:domain,date:foo`.
|
---|
| 166 | */
|
---|
| 167 | tag: string
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | interface CustomTag extends BaseTag {
|
---|
| 171 | /**
|
---|
| 172 | * A JavaScript class that should be matched to this tag, e.g. `Date` for `!!timestamp`.
|
---|
| 173 | * @deprecated Use `Tag.identify` instead
|
---|
| 174 | */
|
---|
| 175 | class?: new () => any
|
---|
| 176 | /**
|
---|
| 177 | * Turns a CST node into an AST node. If returning a non-`Node` value, the
|
---|
| 178 | * output will be wrapped as a `Scalar`.
|
---|
| 179 | */
|
---|
| 180 | resolve(doc: Document, cstNode: CST.Node): Node | any
|
---|
| 181 | }
|
---|
| 182 |
|
---|
| 183 | interface DefaultTag extends BaseTag {
|
---|
| 184 | /**
|
---|
| 185 | * If `true`, together with `test` allows for values to be stringified without
|
---|
| 186 | * an explicit tag. For most cases, it's unlikely that you'll actually want to
|
---|
| 187 | * use this, even if you first think you do.
|
---|
| 188 | */
|
---|
| 189 | default: true
|
---|
| 190 | /**
|
---|
| 191 | * Alternative form used by default tags; called with `test` match results.
|
---|
| 192 | */
|
---|
| 193 | resolve(...match: string[]): Node | any
|
---|
| 194 | /**
|
---|
| 195 | * Together with `default` allows for values to be stringified without an
|
---|
| 196 | * explicit tag and detected using a regular expression. For most cases, it's
|
---|
| 197 | * unlikely that you'll actually want to use these, even if you first think
|
---|
| 198 | * you do.
|
---|
| 199 | */
|
---|
| 200 | test: RegExp
|
---|
| 201 | }
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | export class Node {
|
---|
| 205 | /** A comment on or immediately after this */
|
---|
| 206 | comment?: string | null
|
---|
| 207 | /** A comment before this */
|
---|
| 208 | commentBefore?: string | null
|
---|
| 209 | /** Only available when `keepCstNodes` is set to `true` */
|
---|
| 210 | cstNode?: CST.Node
|
---|
| 211 | /**
|
---|
| 212 | * The [start, end] range of characters of the source parsed
|
---|
| 213 | * into this node (undefined for pairs or if not parsed)
|
---|
| 214 | */
|
---|
| 215 | range?: [number, number] | null
|
---|
| 216 | /** A blank line before this node and its commentBefore */
|
---|
| 217 | spaceBefore?: boolean
|
---|
| 218 | /** A fully qualified tag, if required */
|
---|
| 219 | tag?: string
|
---|
| 220 | /** A plain JS representation of this node */
|
---|
| 221 | toJSON(arg?: any): any
|
---|
| 222 | /** The type of this node */
|
---|
| 223 | type?: Type | Pair.Type
|
---|
| 224 | }
|
---|
| 225 |
|
---|
| 226 | export class Scalar extends Node {
|
---|
| 227 | constructor(value: any)
|
---|
| 228 | type?: Scalar.Type
|
---|
| 229 | /**
|
---|
| 230 | * By default (undefined), numbers use decimal notation.
|
---|
| 231 | * The YAML 1.2 core schema only supports 'HEX' and 'OCT'.
|
---|
| 232 | */
|
---|
| 233 | format?: 'BIN' | 'HEX' | 'OCT' | 'TIME'
|
---|
| 234 | value: any
|
---|
| 235 | toJSON(arg?: any, ctx?: AST.NodeToJsonContext): any
|
---|
| 236 | toString(): string
|
---|
| 237 | }
|
---|
| 238 | export namespace Scalar {
|
---|
| 239 | type Type =
|
---|
| 240 | | Type.BLOCK_FOLDED
|
---|
| 241 | | Type.BLOCK_LITERAL
|
---|
| 242 | | Type.PLAIN
|
---|
| 243 | | Type.QUOTE_DOUBLE
|
---|
| 244 | | Type.QUOTE_SINGLE
|
---|
| 245 | }
|
---|
| 246 |
|
---|
| 247 | export class Alias extends Node {
|
---|
| 248 | type: Type.ALIAS
|
---|
| 249 | source: Node
|
---|
| 250 | cstNode?: CST.Alias
|
---|
| 251 | toString(ctx: Schema.StringifyContext): string
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | export class Pair extends Node {
|
---|
| 255 | constructor(key: any, value?: any)
|
---|
| 256 | type: Pair.Type.PAIR | Pair.Type.MERGE_PAIR
|
---|
| 257 | /** Always Node or null when parsed, but can be set to anything. */
|
---|
| 258 | key: any
|
---|
| 259 | /** Always Node or null when parsed, but can be set to anything. */
|
---|
| 260 | value: any
|
---|
| 261 | cstNode?: never // no corresponding cstNode
|
---|
| 262 | toJSON(arg?: any, ctx?: AST.NodeToJsonContext): object | Map<any, any>
|
---|
| 263 | toString(
|
---|
| 264 | ctx?: Schema.StringifyContext,
|
---|
| 265 | onComment?: () => void,
|
---|
| 266 | onChompKeep?: () => void
|
---|
| 267 | ): string
|
---|
| 268 | }
|
---|
| 269 | export namespace Pair {
|
---|
| 270 | enum Type {
|
---|
| 271 | PAIR = 'PAIR',
|
---|
| 272 | MERGE_PAIR = 'MERGE_PAIR'
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 |
|
---|
| 276 | export class Merge extends Pair {
|
---|
| 277 | type: Pair.Type.MERGE_PAIR
|
---|
| 278 | /** Always Scalar('<<'), defined by the type specification */
|
---|
| 279 | key: AST.PlainValue
|
---|
| 280 | /** Always YAMLSeq<Alias(Map)>, stringified as *A if length = 1 */
|
---|
| 281 | value: YAMLSeq
|
---|
| 282 | toString(ctx?: Schema.StringifyContext, onComment?: () => void): string
|
---|
| 283 | }
|
---|
| 284 |
|
---|
| 285 | export class Collection extends Node {
|
---|
| 286 | type?: Type.MAP | Type.FLOW_MAP | Type.SEQ | Type.FLOW_SEQ | Type.DOCUMENT
|
---|
| 287 | items: any[]
|
---|
| 288 | schema?: Schema
|
---|
| 289 |
|
---|
| 290 | /**
|
---|
| 291 | * Adds a value to the collection. For `!!map` and `!!omap` the value must
|
---|
| 292 | * be a Pair instance or a `{ key, value }` object, which may not have a key
|
---|
| 293 | * that already exists in the map.
|
---|
| 294 | */
|
---|
| 295 | add(value: any): void
|
---|
| 296 | addIn(path: Iterable<any>, value: any): void
|
---|
| 297 | /**
|
---|
| 298 | * Removes a value from the collection.
|
---|
| 299 | * @returns `true` if the item was found and removed.
|
---|
| 300 | */
|
---|
| 301 | delete(key: any): boolean
|
---|
| 302 | deleteIn(path: Iterable<any>): boolean
|
---|
| 303 | /**
|
---|
| 304 | * Returns item at `key`, or `undefined` if not found. By default unwraps
|
---|
| 305 | * scalar values from their surrounding node; to disable set `keepScalar` to
|
---|
| 306 | * `true` (collections are always returned intact).
|
---|
| 307 | */
|
---|
| 308 | get(key: any, keepScalar?: boolean): any
|
---|
| 309 | getIn(path: Iterable<any>, keepScalar?: boolean): any
|
---|
| 310 | /**
|
---|
| 311 | * Checks if the collection includes a value with the key `key`.
|
---|
| 312 | */
|
---|
| 313 | has(key: any): boolean
|
---|
| 314 | hasIn(path: Iterable<any>): boolean
|
---|
| 315 | /**
|
---|
| 316 | * Sets a value in this collection. For `!!set`, `value` needs to be a
|
---|
| 317 | * boolean to add/remove the item from the set.
|
---|
| 318 | */
|
---|
| 319 | set(key: any, value: any): void
|
---|
| 320 | setIn(path: Iterable<any>, value: any): void
|
---|
| 321 | }
|
---|
| 322 |
|
---|
| 323 | export class YAMLMap extends Collection {
|
---|
| 324 | type?: Type.FLOW_MAP | Type.MAP
|
---|
| 325 | items: Array<Pair>
|
---|
| 326 | hasAllNullValues(): boolean
|
---|
| 327 | toJSON(arg?: any, ctx?: AST.NodeToJsonContext): object | Map<any, any>
|
---|
| 328 | toString(
|
---|
| 329 | ctx?: Schema.StringifyContext,
|
---|
| 330 | onComment?: () => void,
|
---|
| 331 | onChompKeep?: () => void
|
---|
| 332 | ): string
|
---|
| 333 | }
|
---|
| 334 |
|
---|
| 335 | export class YAMLSeq extends Collection {
|
---|
| 336 | type?: Type.FLOW_SEQ | Type.SEQ
|
---|
| 337 | delete(key: number | string | Scalar): boolean
|
---|
| 338 | get(key: number | string | Scalar, keepScalar?: boolean): any
|
---|
| 339 | has(key: number | string | Scalar): boolean
|
---|
| 340 | set(key: number | string | Scalar, value: any): void
|
---|
| 341 | hasAllNullValues(): boolean
|
---|
| 342 | toJSON(arg?: any, ctx?: AST.NodeToJsonContext): any[]
|
---|
| 343 | toString(
|
---|
| 344 | ctx?: Schema.StringifyContext,
|
---|
| 345 | onComment?: () => void,
|
---|
| 346 | onChompKeep?: () => void
|
---|
| 347 | ): string
|
---|
| 348 | }
|
---|
| 349 |
|
---|
| 350 | export namespace AST {
|
---|
| 351 | interface NodeToJsonContext {
|
---|
| 352 | anchors?: any[]
|
---|
| 353 | doc: Document
|
---|
| 354 | keep?: boolean
|
---|
| 355 | mapAsMap?: boolean
|
---|
| 356 | maxAliasCount?: number
|
---|
| 357 | onCreate?: (node: Node) => void
|
---|
| 358 | [key: string]: any
|
---|
| 359 | }
|
---|
| 360 |
|
---|
| 361 | interface BlockFolded extends Scalar {
|
---|
| 362 | type: Type.BLOCK_FOLDED
|
---|
| 363 | cstNode?: CST.BlockFolded
|
---|
| 364 | }
|
---|
| 365 |
|
---|
| 366 | interface BlockLiteral extends Scalar {
|
---|
| 367 | type: Type.BLOCK_LITERAL
|
---|
| 368 | cstNode?: CST.BlockLiteral
|
---|
| 369 | }
|
---|
| 370 |
|
---|
| 371 | interface PlainValue extends Scalar {
|
---|
| 372 | type: Type.PLAIN
|
---|
| 373 | cstNode?: CST.PlainValue
|
---|
| 374 | }
|
---|
| 375 |
|
---|
| 376 | interface QuoteDouble extends Scalar {
|
---|
| 377 | type: Type.QUOTE_DOUBLE
|
---|
| 378 | cstNode?: CST.QuoteDouble
|
---|
| 379 | }
|
---|
| 380 |
|
---|
| 381 | interface QuoteSingle extends Scalar {
|
---|
| 382 | type: Type.QUOTE_SINGLE
|
---|
| 383 | cstNode?: CST.QuoteSingle
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | interface FlowMap extends YAMLMap {
|
---|
| 387 | type: Type.FLOW_MAP
|
---|
| 388 | cstNode?: CST.FlowMap
|
---|
| 389 | }
|
---|
| 390 |
|
---|
| 391 | interface BlockMap extends YAMLMap {
|
---|
| 392 | type: Type.MAP
|
---|
| 393 | cstNode?: CST.Map
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 | interface FlowSeq extends YAMLSeq {
|
---|
| 397 | type: Type.FLOW_SEQ
|
---|
| 398 | items: Array<Node>
|
---|
| 399 | cstNode?: CST.FlowSeq
|
---|
| 400 | }
|
---|
| 401 |
|
---|
| 402 | interface BlockSeq extends YAMLSeq {
|
---|
| 403 | type: Type.SEQ
|
---|
| 404 | items: Array<Node | null>
|
---|
| 405 | cstNode?: CST.Seq
|
---|
| 406 | }
|
---|
| 407 | }
|
---|