types.d.ts 11 KB

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