Document-f89a2614.js 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783
  1. 'use strict';
  2. var _rollupPluginBabelHelpers = require('./_rollupPluginBabelHelpers-eed30217.js');
  3. var parseCst = require('./parse-3997f544.js');
  4. var stringifyNumber = require('./stringifyNumber-dea1120c.js');
  5. var Schema = require('./Schema-807430ba.js');
  6. const defaultOptions = {
  7. anchorPrefix: 'a',
  8. customTags: null,
  9. indent: 2,
  10. indentSeq: true,
  11. keepCstNodes: false,
  12. keepNodeTypes: true,
  13. keepUndefined: false,
  14. mapAsMap: false,
  15. maxAliasCount: 100,
  16. prettyErrors: true,
  17. simpleKeys: false,
  18. version: '1.2'
  19. };
  20. const scalarOptions = {
  21. get binary() {
  22. return stringifyNumber.binaryOptions;
  23. },
  24. set binary(opt) {
  25. Object.assign(stringifyNumber.binaryOptions, opt);
  26. },
  27. get bool() {
  28. return stringifyNumber.boolOptions;
  29. },
  30. set bool(opt) {
  31. Object.assign(stringifyNumber.boolOptions, opt);
  32. },
  33. get int() {
  34. return stringifyNumber.intOptions;
  35. },
  36. set int(opt) {
  37. Object.assign(stringifyNumber.intOptions, opt);
  38. },
  39. get null() {
  40. return stringifyNumber.nullOptions;
  41. },
  42. set null(opt) {
  43. Object.assign(stringifyNumber.nullOptions, opt);
  44. },
  45. get str() {
  46. return stringifyNumber.strOptions;
  47. },
  48. set str(opt) {
  49. Object.assign(stringifyNumber.strOptions, opt);
  50. }
  51. };
  52. const documentOptions = {
  53. '1.0': {
  54. schema: 'yaml-1.1',
  55. merge: true,
  56. tagPrefixes: [{
  57. handle: '!',
  58. prefix: _rollupPluginBabelHelpers.defaultTagPrefix
  59. }, {
  60. handle: '!!',
  61. prefix: 'tag:private.yaml.org,2002:'
  62. }]
  63. },
  64. '1.1': {
  65. schema: 'yaml-1.1',
  66. merge: true,
  67. tagPrefixes: [{
  68. handle: '!',
  69. prefix: '!'
  70. }, {
  71. handle: '!!',
  72. prefix: _rollupPluginBabelHelpers.defaultTagPrefix
  73. }]
  74. },
  75. '1.2': {
  76. schema: 'core',
  77. merge: false,
  78. resolveKnownTags: true,
  79. tagPrefixes: [{
  80. handle: '!',
  81. prefix: '!'
  82. }, {
  83. handle: '!!',
  84. prefix: _rollupPluginBabelHelpers.defaultTagPrefix
  85. }]
  86. }
  87. };
  88. function stringifyTag(doc, tag) {
  89. if ((doc.version || doc.options.version) === '1.0') {
  90. const priv = tag.match(/^tag:private\.yaml\.org,2002:([^:/]+)$/);
  91. if (priv) return '!' + priv[1];
  92. const vocab = tag.match(/^tag:([a-zA-Z0-9-]+)\.yaml\.org,2002:(.*)/);
  93. return vocab ? `!${vocab[1]}/${vocab[2]}` : `!${tag.replace(/^tag:/, '')}`;
  94. }
  95. let p = doc.tagPrefixes.find(p => tag.indexOf(p.prefix) === 0);
  96. if (!p) {
  97. const dtp = doc.getDefaults().tagPrefixes;
  98. p = dtp && dtp.find(p => tag.indexOf(p.prefix) === 0);
  99. }
  100. if (!p) return tag[0] === '!' ? tag : `!<${tag}>`;
  101. const suffix = tag.substr(p.prefix.length).replace(/[!,[\]{}]/g, ch => ({
  102. '!': '%21',
  103. ',': '%2C',
  104. '[': '%5B',
  105. ']': '%5D',
  106. '{': '%7B',
  107. '}': '%7D'
  108. })[ch]);
  109. return p.handle + suffix;
  110. }
  111. function getTagObject(tags, item) {
  112. if (item instanceof stringifyNumber.Alias) return stringifyNumber.Alias;
  113. if (item.tag) {
  114. const match = tags.filter(t => t.tag === item.tag);
  115. if (match.length > 0) return match.find(t => t.format === item.format) || match[0];
  116. }
  117. let tagObj, obj;
  118. if (item instanceof stringifyNumber.Scalar) {
  119. obj = item.value;
  120. const match = tags.filter(t => t.identify && t.identify(obj));
  121. tagObj = match.find(t => t.format === item.format) || match.find(t => !t.format);
  122. } else {
  123. obj = item;
  124. tagObj = tags.find(t => t.nodeClass && obj instanceof t.nodeClass);
  125. }
  126. if (!tagObj) {
  127. const name = obj && obj.constructor ? obj.constructor.name : typeof obj;
  128. throw new Error(`Tag not resolved for ${name} value`);
  129. }
  130. return tagObj;
  131. } // needs to be called before value stringifier to allow for circular anchor refs
  132. function stringifyProps(node, tagObj, {
  133. anchors,
  134. doc
  135. }) {
  136. const props = [];
  137. const anchor = doc.anchors.getName(node);
  138. if (anchor) {
  139. anchors[anchor] = node;
  140. props.push(`&${anchor}`);
  141. }
  142. if (node.tag) {
  143. props.push(stringifyTag(doc, node.tag));
  144. } else if (!tagObj.default) {
  145. props.push(stringifyTag(doc, tagObj.tag));
  146. }
  147. return props.join(' ');
  148. }
  149. function stringify(item, ctx, onComment, onChompKeep) {
  150. const {
  151. schema
  152. } = ctx.doc;
  153. let tagObj;
  154. if (!(item instanceof stringifyNumber.Node)) {
  155. item = ctx.doc.createNode(item, {
  156. onTagObj: o => tagObj = o,
  157. wrapScalars: true
  158. });
  159. }
  160. if (item instanceof stringifyNumber.Pair) return item.toString(ctx, onComment, onChompKeep);
  161. if (!tagObj) tagObj = getTagObject(schema.tags, item);
  162. const props = stringifyProps(item, tagObj, ctx);
  163. if (props.length > 0) ctx.indentAtStart = (ctx.indentAtStart || 0) + props.length + 1;
  164. const str = typeof tagObj.stringify === 'function' ? tagObj.stringify(item, ctx, onComment, onChompKeep) : item instanceof stringifyNumber.Scalar ? stringifyNumber.stringifyString(item, ctx, onComment, onChompKeep) : item.toString(ctx, onComment, onChompKeep);
  165. if (!props) return str;
  166. return item instanceof stringifyNumber.Scalar || str[0] === '{' || str[0] === '[' ? `${props} ${str}` : `${props}\n${ctx.indent}${str}`;
  167. }
  168. class Anchors {
  169. static validAnchorNode(node) {
  170. return node instanceof stringifyNumber.Scalar || node instanceof stringifyNumber.YAMLSeq || node instanceof stringifyNumber.YAMLMap;
  171. }
  172. constructor(prefix) {
  173. _rollupPluginBabelHelpers._defineProperty(this, "map", Object.create(null));
  174. this.prefix = prefix;
  175. }
  176. createAlias(node, name) {
  177. this.setAnchor(node, name);
  178. return new stringifyNumber.Alias(node);
  179. }
  180. createMergePair(...sources) {
  181. const merge = new Schema.Merge();
  182. merge.value.items = sources.map(s => {
  183. if (s instanceof stringifyNumber.Alias) {
  184. if (s.source instanceof stringifyNumber.YAMLMap) return s;
  185. } else if (s instanceof stringifyNumber.YAMLMap) {
  186. return this.createAlias(s);
  187. }
  188. throw new Error('Merge sources must be Map nodes or their Aliases');
  189. });
  190. return merge;
  191. }
  192. getName(node) {
  193. const {
  194. map
  195. } = this;
  196. return Object.keys(map).find(a => map[a] === node);
  197. }
  198. getNames() {
  199. return Object.keys(this.map);
  200. }
  201. getNode(name) {
  202. return this.map[name];
  203. }
  204. newName(prefix) {
  205. if (!prefix) prefix = this.prefix;
  206. const names = Object.keys(this.map);
  207. for (let i = 1; true; ++i) {
  208. const name = `${prefix}${i}`;
  209. if (!names.includes(name)) return name;
  210. }
  211. } // During parsing, map & aliases contain CST nodes
  212. resolveNodes() {
  213. const {
  214. map,
  215. _cstAliases
  216. } = this;
  217. Object.keys(map).forEach(a => {
  218. map[a] = map[a].resolved;
  219. });
  220. _cstAliases.forEach(a => {
  221. a.source = a.source.resolved;
  222. });
  223. delete this._cstAliases;
  224. }
  225. setAnchor(node, name) {
  226. if (node != null && !Anchors.validAnchorNode(node)) {
  227. throw new Error('Anchors may only be set for Scalar, Seq and Map nodes');
  228. }
  229. if (name && /[\x00-\x19\s,[\]{}]/.test(name)) {
  230. throw new Error('Anchor names must not contain whitespace or control characters');
  231. }
  232. const {
  233. map
  234. } = this;
  235. const prev = node && Object.keys(map).find(a => map[a] === node);
  236. if (prev) {
  237. if (!name) {
  238. return prev;
  239. } else if (prev !== name) {
  240. delete map[prev];
  241. map[name] = node;
  242. }
  243. } else {
  244. if (!name) {
  245. if (!node) return null;
  246. name = this.newName();
  247. }
  248. map[name] = node;
  249. }
  250. return name;
  251. }
  252. }
  253. /**
  254. * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,
  255. * in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the
  256. * 2021 edition: https://tc39.es/ecma262/#sec-json.parse
  257. *
  258. * Includes extensions for handling Map and Set objects.
  259. */
  260. function applyReviver(reviver, obj, key, val) {
  261. if (val && typeof val === 'object') {
  262. if (Array.isArray(val)) {
  263. for (let i = 0, len = val.length; i < len; ++i) {
  264. const v0 = val[i];
  265. const v1 = applyReviver(reviver, val, String(i), v0);
  266. if (v1 === undefined) delete val[i];else if (v1 !== v0) val[i] = v1;
  267. }
  268. } else if (val instanceof Map) {
  269. for (const k of Array.from(val.keys())) {
  270. const v0 = val.get(k);
  271. const v1 = applyReviver(reviver, val, k, v0);
  272. if (v1 === undefined) val.delete(k);else if (v1 !== v0) val.set(k, v1);
  273. }
  274. } else if (val instanceof Set) {
  275. for (const v0 of Array.from(val)) {
  276. const v1 = applyReviver(reviver, val, v0, v0);
  277. if (v1 === undefined) val.delete(v0);else if (v1 !== v0) {
  278. val.delete(v0);
  279. val.add(v1);
  280. }
  281. }
  282. } else {
  283. for (const [k, v0] of Object.entries(val)) {
  284. const v1 = applyReviver(reviver, val, k, v0);
  285. if (v1 === undefined) delete val[k];else if (v1 !== v0) val[k] = v1;
  286. }
  287. }
  288. }
  289. return reviver.call(obj, key, val);
  290. }
  291. const visit = (node, tags) => {
  292. if (node && typeof node === 'object') {
  293. const {
  294. tag
  295. } = node;
  296. if (node instanceof stringifyNumber.Collection) {
  297. if (tag) tags[tag] = true;
  298. node.items.forEach(n => visit(n, tags));
  299. } else if (node instanceof stringifyNumber.Pair) {
  300. visit(node.key, tags);
  301. visit(node.value, tags);
  302. } else if (node instanceof stringifyNumber.Scalar) {
  303. if (tag) tags[tag] = true;
  304. }
  305. }
  306. return tags;
  307. };
  308. const listTagNames = node => Object.keys(visit(node, {}));
  309. function resolveTagHandle(doc, node) {
  310. const {
  311. handle,
  312. suffix
  313. } = node.tag;
  314. let prefix = doc.tagPrefixes.find(p => p.handle === handle);
  315. if (!prefix) {
  316. const dtp = doc.getDefaults().tagPrefixes;
  317. if (dtp) prefix = dtp.find(p => p.handle === handle);
  318. if (!prefix) throw new _rollupPluginBabelHelpers.YAMLSemanticError(node, `The ${handle} tag handle is non-default and was not declared.`);
  319. }
  320. if (!suffix) throw new _rollupPluginBabelHelpers.YAMLSemanticError(node, `The ${handle} tag has no suffix.`);
  321. if (handle === '!' && (doc.version || doc.options.version) === '1.0') {
  322. if (suffix[0] === '^') {
  323. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(node, 'YAML 1.0 ^ tag expansion is not supported'));
  324. return suffix;
  325. }
  326. if (/[:/]/.test(suffix)) {
  327. // word/foo -> tag:word.yaml.org,2002:foo
  328. const vocab = suffix.match(/^([a-z0-9-]+)\/(.*)/i);
  329. return vocab ? `tag:${vocab[1]}.yaml.org,2002:${vocab[2]}` : `tag:${suffix}`;
  330. }
  331. }
  332. return prefix.prefix + decodeURIComponent(suffix);
  333. }
  334. function resolveTagName(doc, node) {
  335. const {
  336. tag,
  337. type
  338. } = node;
  339. let nonSpecific = false;
  340. if (tag) {
  341. const {
  342. handle,
  343. suffix,
  344. verbatim
  345. } = tag;
  346. if (verbatim) {
  347. if (verbatim !== '!' && verbatim !== '!!') return verbatim;
  348. const msg = `Verbatim tags aren't resolved, so ${verbatim} is invalid.`;
  349. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, msg));
  350. } else if (handle === '!' && !suffix) {
  351. nonSpecific = true;
  352. } else {
  353. try {
  354. return resolveTagHandle(doc, node);
  355. } catch (error) {
  356. doc.errors.push(error);
  357. }
  358. }
  359. }
  360. switch (type) {
  361. case _rollupPluginBabelHelpers.Type.BLOCK_FOLDED:
  362. case _rollupPluginBabelHelpers.Type.BLOCK_LITERAL:
  363. case _rollupPluginBabelHelpers.Type.QUOTE_DOUBLE:
  364. case _rollupPluginBabelHelpers.Type.QUOTE_SINGLE:
  365. return _rollupPluginBabelHelpers.defaultTags.STR;
  366. case _rollupPluginBabelHelpers.Type.FLOW_MAP:
  367. case _rollupPluginBabelHelpers.Type.MAP:
  368. return _rollupPluginBabelHelpers.defaultTags.MAP;
  369. case _rollupPluginBabelHelpers.Type.FLOW_SEQ:
  370. case _rollupPluginBabelHelpers.Type.SEQ:
  371. return _rollupPluginBabelHelpers.defaultTags.SEQ;
  372. case _rollupPluginBabelHelpers.Type.PLAIN:
  373. return nonSpecific ? _rollupPluginBabelHelpers.defaultTags.STR : null;
  374. default:
  375. return null;
  376. }
  377. }
  378. function checkFlowCollectionEnd(errors, cst) {
  379. let char, name;
  380. switch (cst.type) {
  381. case _rollupPluginBabelHelpers.Type.FLOW_MAP:
  382. char = '}';
  383. name = 'flow map';
  384. break;
  385. case _rollupPluginBabelHelpers.Type.FLOW_SEQ:
  386. char = ']';
  387. name = 'flow sequence';
  388. break;
  389. default:
  390. errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(cst, 'Not a flow collection!?'));
  391. return;
  392. }
  393. let lastItem;
  394. for (let i = cst.items.length - 1; i >= 0; --i) {
  395. const item = cst.items[i];
  396. if (!item || item.type !== _rollupPluginBabelHelpers.Type.COMMENT) {
  397. lastItem = item;
  398. break;
  399. }
  400. }
  401. if (lastItem && lastItem.char !== char) {
  402. const msg = `Expected ${name} to end with ${char}`;
  403. let err;
  404. if (typeof lastItem.offset === 'number') {
  405. err = new _rollupPluginBabelHelpers.YAMLSemanticError(cst, msg);
  406. err.offset = lastItem.offset + 1;
  407. } else {
  408. err = new _rollupPluginBabelHelpers.YAMLSemanticError(lastItem, msg);
  409. if (lastItem.range && lastItem.range.end) err.offset = lastItem.range.end - lastItem.range.start;
  410. }
  411. errors.push(err);
  412. }
  413. }
  414. function checkFlowCommentSpace(errors, comment) {
  415. const prev = comment.context.src[comment.range.start - 1];
  416. if (prev !== '\n' && prev !== '\t' && prev !== ' ') {
  417. const msg = 'Comments must be separated from other tokens by white space characters';
  418. errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(comment, msg));
  419. }
  420. }
  421. function getLongKeyError(source, key) {
  422. const sk = String(key);
  423. const k = sk.substr(0, 8) + '...' + sk.substr(-8);
  424. return new _rollupPluginBabelHelpers.YAMLSemanticError(source, `The "${k}" key is too long`);
  425. }
  426. function resolveComments(collection, comments) {
  427. for (const {
  428. afterKey,
  429. before,
  430. comment
  431. } of comments) {
  432. let item = collection.items[before];
  433. if (!item) {
  434. if (comment !== undefined) {
  435. if (collection.comment) collection.comment += '\n' + comment;else collection.comment = comment;
  436. }
  437. } else {
  438. if (afterKey && item.value) item = item.value;
  439. if (comment === undefined) {
  440. if (afterKey || !item.commentBefore) item.spaceBefore = true;
  441. } else {
  442. if (item.commentBefore) item.commentBefore += '\n' + comment;else item.commentBefore = comment;
  443. }
  444. }
  445. }
  446. }
  447. function resolveMap(doc, cst) {
  448. const {
  449. comments,
  450. items
  451. } = cst.type === _rollupPluginBabelHelpers.Type.FLOW_MAP ? resolveFlowMapItems(doc, cst) : resolveBlockMapItems(doc, cst);
  452. const map = new stringifyNumber.YAMLMap(doc.schema);
  453. map.items = items;
  454. resolveComments(map, comments);
  455. let hasCollectionKey = false;
  456. for (let i = 0; i < items.length; ++i) {
  457. const {
  458. key: iKey
  459. } = items[i];
  460. if (iKey instanceof stringifyNumber.Collection) hasCollectionKey = true;
  461. if (doc.schema.merge && iKey && iKey.value === Schema.MERGE_KEY) {
  462. items[i] = new Schema.Merge(items[i]);
  463. const sources = items[i].value.items;
  464. let error = null;
  465. sources.some(node => {
  466. if (node instanceof stringifyNumber.Alias) {
  467. // During parsing, alias sources are CST nodes; to account for
  468. // circular references their resolved values can't be used here.
  469. const {
  470. type
  471. } = node.source;
  472. if (type === _rollupPluginBabelHelpers.Type.MAP || type === _rollupPluginBabelHelpers.Type.FLOW_MAP) return false;
  473. return error = 'Merge nodes aliases can only point to maps';
  474. }
  475. return error = 'Merge nodes can only have Alias nodes as values';
  476. });
  477. if (error) doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(cst, error));
  478. } else {
  479. for (let j = i + 1; j < items.length; ++j) {
  480. const {
  481. key: jKey
  482. } = items[j];
  483. if (iKey === jKey || iKey && jKey && Object.prototype.hasOwnProperty.call(iKey, 'value') && iKey.value === jKey.value) {
  484. const msg = `Map keys must be unique; "${iKey}" is repeated`;
  485. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(cst, msg));
  486. break;
  487. }
  488. }
  489. }
  490. }
  491. if (hasCollectionKey && !doc.options.mapAsMap) {
  492. const warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';
  493. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(cst, warn));
  494. }
  495. cst.resolved = map;
  496. return map;
  497. }
  498. const valueHasPairComment = ({
  499. context: {
  500. lineStart,
  501. node,
  502. src
  503. },
  504. props
  505. }) => {
  506. if (props.length === 0) return false;
  507. const {
  508. start
  509. } = props[0];
  510. if (node && start > node.valueRange.start) return false;
  511. if (src[start] !== _rollupPluginBabelHelpers.Char.COMMENT) return false;
  512. for (let i = lineStart; i < start; ++i) if (src[i] === '\n') return false;
  513. return true;
  514. };
  515. function resolvePairComment(item, pair) {
  516. if (!valueHasPairComment(item)) return;
  517. const comment = item.getPropValue(0, _rollupPluginBabelHelpers.Char.COMMENT, true);
  518. let found = false;
  519. const cb = pair.value.commentBefore;
  520. if (cb && cb.startsWith(comment)) {
  521. pair.value.commentBefore = cb.substr(comment.length + 1);
  522. found = true;
  523. } else {
  524. const cc = pair.value.comment;
  525. if (!item.node && cc && cc.startsWith(comment)) {
  526. pair.value.comment = cc.substr(comment.length + 1);
  527. found = true;
  528. }
  529. }
  530. if (found) pair.comment = comment;
  531. }
  532. function resolveBlockMapItems(doc, cst) {
  533. const comments = [];
  534. const items = [];
  535. let key = undefined;
  536. let keyStart = null;
  537. for (let i = 0; i < cst.items.length; ++i) {
  538. const item = cst.items[i];
  539. switch (item.type) {
  540. case _rollupPluginBabelHelpers.Type.BLANK_LINE:
  541. comments.push({
  542. afterKey: !!key,
  543. before: items.length
  544. });
  545. break;
  546. case _rollupPluginBabelHelpers.Type.COMMENT:
  547. comments.push({
  548. afterKey: !!key,
  549. before: items.length,
  550. comment: item.comment
  551. });
  552. break;
  553. case _rollupPluginBabelHelpers.Type.MAP_KEY:
  554. if (key !== undefined) items.push(new stringifyNumber.Pair(key));
  555. if (item.error) doc.errors.push(item.error);
  556. key = resolveNode(doc, item.node);
  557. keyStart = null;
  558. break;
  559. case _rollupPluginBabelHelpers.Type.MAP_VALUE:
  560. {
  561. if (key === undefined) key = null;
  562. if (item.error) doc.errors.push(item.error);
  563. if (!item.context.atLineStart && item.node && item.node.type === _rollupPluginBabelHelpers.Type.MAP && !item.node.context.atLineStart) {
  564. const msg = 'Nested mappings are not allowed in compact mappings';
  565. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item.node, msg));
  566. }
  567. let valueNode = item.node;
  568. if (!valueNode && item.props.length > 0) {
  569. // Comments on an empty mapping value need to be preserved, so we
  570. // need to construct a minimal empty node here to use instead of the
  571. // missing `item.node`. -- eemeli/yaml#19
  572. valueNode = new parseCst.PlainValue(_rollupPluginBabelHelpers.Type.PLAIN, []);
  573. valueNode.context = {
  574. parent: item,
  575. src: item.context.src
  576. };
  577. const pos = item.range.start + 1;
  578. valueNode.range = {
  579. start: pos,
  580. end: pos
  581. };
  582. valueNode.valueRange = {
  583. start: pos,
  584. end: pos
  585. };
  586. if (typeof item.range.origStart === 'number') {
  587. const origPos = item.range.origStart + 1;
  588. valueNode.range.origStart = valueNode.range.origEnd = origPos;
  589. valueNode.valueRange.origStart = valueNode.valueRange.origEnd = origPos;
  590. }
  591. }
  592. const pair = new stringifyNumber.Pair(key, resolveNode(doc, valueNode));
  593. resolvePairComment(item, pair);
  594. items.push(pair);
  595. if (key && typeof keyStart === 'number') {
  596. if (item.range.start > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key));
  597. }
  598. key = undefined;
  599. keyStart = null;
  600. }
  601. break;
  602. default:
  603. if (key !== undefined) items.push(new stringifyNumber.Pair(key));
  604. key = resolveNode(doc, item);
  605. keyStart = item.range.start;
  606. if (item.error) doc.errors.push(item.error);
  607. next: for (let j = i + 1;; ++j) {
  608. const nextItem = cst.items[j];
  609. switch (nextItem && nextItem.type) {
  610. case _rollupPluginBabelHelpers.Type.BLANK_LINE:
  611. case _rollupPluginBabelHelpers.Type.COMMENT:
  612. continue next;
  613. case _rollupPluginBabelHelpers.Type.MAP_VALUE:
  614. break next;
  615. default:
  616. {
  617. const msg = 'Implicit map keys need to be followed by map values';
  618. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, msg));
  619. break next;
  620. }
  621. }
  622. }
  623. if (item.valueRangeContainsNewline) {
  624. const msg = 'Implicit map keys need to be on a single line';
  625. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, msg));
  626. }
  627. }
  628. }
  629. if (key !== undefined) items.push(new stringifyNumber.Pair(key));
  630. return {
  631. comments,
  632. items
  633. };
  634. }
  635. function resolveFlowMapItems(doc, cst) {
  636. const comments = [];
  637. const items = [];
  638. let key = undefined;
  639. let explicitKey = false;
  640. let next = '{';
  641. for (let i = 0; i < cst.items.length; ++i) {
  642. const item = cst.items[i];
  643. if (typeof item.char === 'string') {
  644. const {
  645. char,
  646. offset
  647. } = item;
  648. if (char === '?' && key === undefined && !explicitKey) {
  649. explicitKey = true;
  650. next = ':';
  651. continue;
  652. }
  653. if (char === ':') {
  654. if (key === undefined) key = null;
  655. if (next === ':') {
  656. next = ',';
  657. continue;
  658. }
  659. } else {
  660. if (explicitKey) {
  661. if (key === undefined && char !== ',') key = null;
  662. explicitKey = false;
  663. }
  664. if (key !== undefined) {
  665. items.push(new stringifyNumber.Pair(key));
  666. key = undefined;
  667. if (char === ',') {
  668. next = ':';
  669. continue;
  670. }
  671. }
  672. }
  673. if (char === '}') {
  674. if (i === cst.items.length - 1) continue;
  675. } else if (char === next) {
  676. next = ':';
  677. continue;
  678. }
  679. const msg = `Flow map contains an unexpected ${char}`;
  680. const err = new _rollupPluginBabelHelpers.YAMLSyntaxError(cst, msg);
  681. err.offset = offset;
  682. doc.errors.push(err);
  683. } else if (item.type === _rollupPluginBabelHelpers.Type.BLANK_LINE) {
  684. comments.push({
  685. afterKey: !!key,
  686. before: items.length
  687. });
  688. } else if (item.type === _rollupPluginBabelHelpers.Type.COMMENT) {
  689. checkFlowCommentSpace(doc.errors, item);
  690. comments.push({
  691. afterKey: !!key,
  692. before: items.length,
  693. comment: item.comment
  694. });
  695. } else if (key === undefined) {
  696. if (next === ',') doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, 'Separator , missing in flow map'));
  697. key = resolveNode(doc, item);
  698. } else {
  699. if (next !== ',') doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, 'Indicator : missing in flow map entry'));
  700. items.push(new stringifyNumber.Pair(key, resolveNode(doc, item)));
  701. key = undefined;
  702. explicitKey = false;
  703. }
  704. }
  705. checkFlowCollectionEnd(doc.errors, cst);
  706. if (key !== undefined) items.push(new stringifyNumber.Pair(key));
  707. return {
  708. comments,
  709. items
  710. };
  711. }
  712. function resolveSeq(doc, cst) {
  713. const {
  714. comments,
  715. items
  716. } = cst.type === _rollupPluginBabelHelpers.Type.FLOW_SEQ ? resolveFlowSeqItems(doc, cst) : resolveBlockSeqItems(doc, cst);
  717. const seq = new stringifyNumber.YAMLSeq(doc.schema);
  718. seq.items = items;
  719. resolveComments(seq, comments);
  720. if (!doc.options.mapAsMap && items.some(it => it instanceof stringifyNumber.Pair && it.key instanceof stringifyNumber.Collection)) {
  721. const warn = 'Keys with collection values will be stringified as YAML due to JS Object restrictions. Use mapAsMap: true to avoid this.';
  722. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(cst, warn));
  723. }
  724. cst.resolved = seq;
  725. return seq;
  726. }
  727. function resolveBlockSeqItems(doc, cst) {
  728. const comments = [];
  729. const items = [];
  730. for (let i = 0; i < cst.items.length; ++i) {
  731. const item = cst.items[i];
  732. switch (item.type) {
  733. case _rollupPluginBabelHelpers.Type.BLANK_LINE:
  734. comments.push({
  735. before: items.length
  736. });
  737. break;
  738. case _rollupPluginBabelHelpers.Type.COMMENT:
  739. comments.push({
  740. comment: item.comment,
  741. before: items.length
  742. });
  743. break;
  744. case _rollupPluginBabelHelpers.Type.SEQ_ITEM:
  745. if (item.error) doc.errors.push(item.error);
  746. items.push(resolveNode(doc, item.node));
  747. if (item.hasProps) {
  748. const msg = 'Sequence items cannot have tags or anchors before the - indicator';
  749. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, msg));
  750. }
  751. break;
  752. default:
  753. if (item.error) doc.errors.push(item.error);
  754. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSyntaxError(item, `Unexpected ${item.type} node in sequence`));
  755. }
  756. }
  757. return {
  758. comments,
  759. items
  760. };
  761. }
  762. function resolveFlowSeqItems(doc, cst) {
  763. const comments = [];
  764. const items = [];
  765. let explicitKey = false;
  766. let key = undefined;
  767. let keyStart = null;
  768. let next = '[';
  769. let prevItem = null;
  770. for (let i = 0; i < cst.items.length; ++i) {
  771. const item = cst.items[i];
  772. if (typeof item.char === 'string') {
  773. const {
  774. char,
  775. offset
  776. } = item;
  777. if (char !== ':' && (explicitKey || key !== undefined)) {
  778. if (explicitKey && key === undefined) key = next ? items.pop() : null;
  779. items.push(new stringifyNumber.Pair(key));
  780. explicitKey = false;
  781. key = undefined;
  782. keyStart = null;
  783. }
  784. if (char === next) {
  785. next = null;
  786. } else if (!next && char === '?') {
  787. explicitKey = true;
  788. } else if (next !== '[' && char === ':' && key === undefined) {
  789. if (next === ',') {
  790. key = items.pop();
  791. if (key instanceof stringifyNumber.Pair) {
  792. const msg = 'Chaining flow sequence pairs is invalid';
  793. const err = new _rollupPluginBabelHelpers.YAMLSemanticError(cst, msg);
  794. err.offset = offset;
  795. doc.errors.push(err);
  796. }
  797. if (!explicitKey && typeof keyStart === 'number') {
  798. const keyEnd = item.range ? item.range.start : item.offset;
  799. if (keyEnd > keyStart + 1024) doc.errors.push(getLongKeyError(cst, key));
  800. const {
  801. src
  802. } = prevItem.context;
  803. for (let i = keyStart; i < keyEnd; ++i) if (src[i] === '\n') {
  804. const msg = 'Implicit keys of flow sequence pairs need to be on a single line';
  805. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(prevItem, msg));
  806. break;
  807. }
  808. }
  809. } else {
  810. key = null;
  811. }
  812. keyStart = null;
  813. explicitKey = false;
  814. next = null;
  815. } else if (next === '[' || char !== ']' || i < cst.items.length - 1) {
  816. const msg = `Flow sequence contains an unexpected ${char}`;
  817. const err = new _rollupPluginBabelHelpers.YAMLSyntaxError(cst, msg);
  818. err.offset = offset;
  819. doc.errors.push(err);
  820. }
  821. } else if (item.type === _rollupPluginBabelHelpers.Type.BLANK_LINE) {
  822. comments.push({
  823. before: items.length
  824. });
  825. } else if (item.type === _rollupPluginBabelHelpers.Type.COMMENT) {
  826. checkFlowCommentSpace(doc.errors, item);
  827. comments.push({
  828. comment: item.comment,
  829. before: items.length
  830. });
  831. } else {
  832. if (next) {
  833. const msg = `Expected a ${next} in flow sequence`;
  834. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(item, msg));
  835. }
  836. const value = resolveNode(doc, item);
  837. if (key === undefined) {
  838. items.push(value);
  839. prevItem = item;
  840. } else {
  841. items.push(new stringifyNumber.Pair(key, value));
  842. key = undefined;
  843. }
  844. keyStart = item.range.start;
  845. next = ',';
  846. }
  847. }
  848. checkFlowCollectionEnd(doc.errors, cst);
  849. if (key !== undefined) items.push(new stringifyNumber.Pair(key));
  850. return {
  851. comments,
  852. items
  853. };
  854. }
  855. function resolveByTagName({
  856. knownTags,
  857. tags
  858. }, tagName, value, onError) {
  859. const matchWithTest = [];
  860. for (const tag of tags) {
  861. if (tag.tag === tagName) {
  862. if (tag.test) {
  863. if (typeof value === 'string') matchWithTest.push(tag);else onError(`The tag ${tagName} cannot be applied to a collection`);
  864. } else {
  865. const res = tag.resolve(value, onError);
  866. return res instanceof stringifyNumber.Collection ? res : new stringifyNumber.Scalar(res);
  867. }
  868. }
  869. }
  870. if (matchWithTest.length > 0) return stringifyNumber.resolveScalar(value, matchWithTest);
  871. const kt = knownTags[tagName];
  872. if (kt) {
  873. tags.push(Object.assign({}, kt, {
  874. default: false,
  875. test: undefined
  876. }));
  877. const res = kt.resolve(value, onError);
  878. return res instanceof stringifyNumber.Collection ? res : new stringifyNumber.Scalar(res);
  879. }
  880. return null;
  881. }
  882. function resolveTag(doc, node, tagName) {
  883. const {
  884. MAP,
  885. SEQ,
  886. STR
  887. } = _rollupPluginBabelHelpers.defaultTags;
  888. let value, fallback;
  889. const onError = message => doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, message));
  890. try {
  891. switch (node.type) {
  892. case _rollupPluginBabelHelpers.Type.FLOW_MAP:
  893. case _rollupPluginBabelHelpers.Type.MAP:
  894. value = resolveMap(doc, node);
  895. fallback = MAP;
  896. if (tagName === SEQ || tagName === STR) onError(`The tag ${tagName} cannot be applied to a mapping`);
  897. break;
  898. case _rollupPluginBabelHelpers.Type.FLOW_SEQ:
  899. case _rollupPluginBabelHelpers.Type.SEQ:
  900. value = resolveSeq(doc, node);
  901. fallback = SEQ;
  902. if (tagName === MAP || tagName === STR) onError(`The tag ${tagName} cannot be applied to a sequence`);
  903. break;
  904. default:
  905. value = node.strValue || '';
  906. if (typeof value !== 'string') {
  907. value.errors.forEach(error => doc.errors.push(error));
  908. value = value.str;
  909. }
  910. if (tagName === MAP || tagName === SEQ) onError(`The tag ${tagName} cannot be applied to a scalar`);
  911. fallback = STR;
  912. }
  913. const res = resolveByTagName(doc.schema, tagName, value, onError);
  914. if (res) {
  915. if (tagName && node.tag) res.tag = tagName;
  916. return res;
  917. }
  918. } catch (error) {
  919. /* istanbul ignore if */
  920. if (!error.source) error.source = node;
  921. doc.errors.push(error);
  922. return null;
  923. }
  924. try {
  925. if (!fallback) throw new Error(`The tag ${tagName} is unavailable`);
  926. const msg = `The tag ${tagName} is unavailable, falling back to ${fallback}`;
  927. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(node, msg));
  928. const res = resolveByTagName(doc.schema, fallback, value, onError);
  929. res.tag = tagName;
  930. return res;
  931. } catch (error) {
  932. const refError = new _rollupPluginBabelHelpers.YAMLReferenceError(node, error.message);
  933. refError.stack = error.stack;
  934. doc.errors.push(refError);
  935. return null;
  936. }
  937. }
  938. const isCollectionItem = node => {
  939. if (!node) return false;
  940. const {
  941. type
  942. } = node;
  943. return type === _rollupPluginBabelHelpers.Type.MAP_KEY || type === _rollupPluginBabelHelpers.Type.MAP_VALUE || type === _rollupPluginBabelHelpers.Type.SEQ_ITEM;
  944. };
  945. function resolveNodeProps(errors, node) {
  946. const comments = {
  947. before: [],
  948. after: []
  949. };
  950. let hasAnchor = false;
  951. let hasTag = false;
  952. const props = isCollectionItem(node.context.parent) ? node.context.parent.props.concat(node.props) : node.props;
  953. for (const {
  954. start,
  955. end
  956. } of props) {
  957. switch (node.context.src[start]) {
  958. case _rollupPluginBabelHelpers.Char.COMMENT:
  959. {
  960. if (!node.commentHasRequiredWhitespace(start)) {
  961. const msg = 'Comments must be separated from other tokens by white space characters';
  962. errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, msg));
  963. }
  964. const {
  965. header,
  966. valueRange
  967. } = node;
  968. const cc = valueRange && (start > valueRange.start || header && start > header.start) ? comments.after : comments.before;
  969. cc.push(node.context.src.slice(start + 1, end));
  970. break;
  971. }
  972. // Actual anchor & tag resolution is handled by schema, here we just complain
  973. case _rollupPluginBabelHelpers.Char.ANCHOR:
  974. if (hasAnchor) {
  975. const msg = 'A node can have at most one anchor';
  976. errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, msg));
  977. }
  978. hasAnchor = true;
  979. break;
  980. case _rollupPluginBabelHelpers.Char.TAG:
  981. if (hasTag) {
  982. const msg = 'A node can have at most one tag';
  983. errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, msg));
  984. }
  985. hasTag = true;
  986. break;
  987. }
  988. }
  989. return {
  990. comments,
  991. hasAnchor,
  992. hasTag
  993. };
  994. }
  995. function resolveNodeValue(doc, node) {
  996. const {
  997. anchors,
  998. errors,
  999. schema
  1000. } = doc;
  1001. if (node.type === _rollupPluginBabelHelpers.Type.ALIAS) {
  1002. const name = node.rawValue;
  1003. const src = anchors.getNode(name);
  1004. if (!src) {
  1005. const msg = `Aliased anchor not found: ${name}`;
  1006. errors.push(new _rollupPluginBabelHelpers.YAMLReferenceError(node, msg));
  1007. return null;
  1008. } // Lazy resolution for circular references
  1009. const res = new stringifyNumber.Alias(src);
  1010. anchors._cstAliases.push(res);
  1011. return res;
  1012. }
  1013. const tagName = resolveTagName(doc, node);
  1014. if (tagName) return resolveTag(doc, node, tagName);
  1015. if (node.type !== _rollupPluginBabelHelpers.Type.PLAIN) {
  1016. const msg = `Failed to resolve ${node.type} node here`;
  1017. errors.push(new _rollupPluginBabelHelpers.YAMLSyntaxError(node, msg));
  1018. return null;
  1019. }
  1020. try {
  1021. let str = node.strValue || '';
  1022. if (typeof str !== 'string') {
  1023. str.errors.forEach(error => doc.errors.push(error));
  1024. str = str.str;
  1025. }
  1026. return stringifyNumber.resolveScalar(str, schema.tags);
  1027. } catch (error) {
  1028. if (!error.source) error.source = node;
  1029. errors.push(error);
  1030. return null;
  1031. }
  1032. } // sets node.resolved on success
  1033. function resolveNode(doc, node) {
  1034. if (!node) return null;
  1035. if (node.error) doc.errors.push(node.error);
  1036. const {
  1037. comments,
  1038. hasAnchor,
  1039. hasTag
  1040. } = resolveNodeProps(doc.errors, node);
  1041. if (hasAnchor) {
  1042. const {
  1043. anchors
  1044. } = doc;
  1045. const name = node.anchor;
  1046. const prev = anchors.getNode(name); // At this point, aliases for any preceding node with the same anchor
  1047. // name have already been resolved, so it may safely be renamed.
  1048. if (prev) anchors.map[anchors.newName(name)] = prev; // During parsing, we need to store the CST node in anchors.map as
  1049. // anchors need to be available during resolution to allow for
  1050. // circular references.
  1051. anchors.map[name] = node;
  1052. }
  1053. if (node.type === _rollupPluginBabelHelpers.Type.ALIAS && (hasAnchor || hasTag)) {
  1054. const msg = 'An alias node must not specify any properties';
  1055. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(node, msg));
  1056. }
  1057. const res = resolveNodeValue(doc, node);
  1058. if (res) {
  1059. res.range = [node.range.start, node.range.end];
  1060. if (doc.options.keepCstNodes) res.cstNode = node;
  1061. if (doc.options.keepNodeTypes) res.type = node.type;
  1062. const cb = comments.before.join('\n');
  1063. if (cb) {
  1064. res.commentBefore = res.commentBefore ? `${res.commentBefore}\n${cb}` : cb;
  1065. }
  1066. const ca = comments.after.join('\n');
  1067. if (ca) res.comment = res.comment ? `${res.comment}\n${ca}` : ca;
  1068. }
  1069. return node.resolved = res;
  1070. }
  1071. function parseContents(doc, contents) {
  1072. const comments = {
  1073. before: [],
  1074. after: []
  1075. };
  1076. let body = undefined;
  1077. let spaceBefore = false;
  1078. for (const node of contents) {
  1079. if (node.valueRange) {
  1080. if (body !== undefined) {
  1081. const msg = 'Document contains trailing content not separated by a ... or --- line';
  1082. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSyntaxError(node, msg));
  1083. break;
  1084. }
  1085. const res = resolveNode(doc, node);
  1086. if (spaceBefore) {
  1087. res.spaceBefore = true;
  1088. spaceBefore = false;
  1089. }
  1090. body = res;
  1091. } else if (node.comment !== null) {
  1092. const cc = body === undefined ? comments.before : comments.after;
  1093. cc.push(node.comment);
  1094. } else if (node.type === _rollupPluginBabelHelpers.Type.BLANK_LINE) {
  1095. spaceBefore = true;
  1096. if (body === undefined && comments.before.length > 0 && !doc.commentBefore) {
  1097. // space-separated comments at start are parsed as document comments
  1098. doc.commentBefore = comments.before.join('\n');
  1099. comments.before = [];
  1100. }
  1101. }
  1102. }
  1103. doc.contents = body || null;
  1104. if (!body) {
  1105. doc.comment = comments.before.concat(comments.after).join('\n') || null;
  1106. } else {
  1107. const cb = comments.before.join('\n');
  1108. if (cb) {
  1109. const cbNode = body instanceof stringifyNumber.Collection && body.items[0] ? body.items[0] : body;
  1110. cbNode.commentBefore = cbNode.commentBefore ? `${cb}\n${cbNode.commentBefore}` : cb;
  1111. }
  1112. doc.comment = comments.after.join('\n') || null;
  1113. }
  1114. }
  1115. function resolveTagDirective({
  1116. tagPrefixes
  1117. }, directive) {
  1118. const [handle, prefix] = directive.parameters;
  1119. if (!handle || !prefix) {
  1120. const msg = 'Insufficient parameters given for %TAG directive';
  1121. throw new _rollupPluginBabelHelpers.YAMLSemanticError(directive, msg);
  1122. }
  1123. if (tagPrefixes.some(p => p.handle === handle)) {
  1124. const msg = 'The %TAG directive must only be given at most once per handle in the same document.';
  1125. throw new _rollupPluginBabelHelpers.YAMLSemanticError(directive, msg);
  1126. }
  1127. return {
  1128. handle,
  1129. prefix
  1130. };
  1131. }
  1132. function resolveYamlDirective(doc, directive) {
  1133. let [version] = directive.parameters;
  1134. if (directive.name === 'YAML:1.0') version = '1.0';
  1135. if (!version) {
  1136. const msg = 'Insufficient parameters given for %YAML directive';
  1137. throw new _rollupPluginBabelHelpers.YAMLSemanticError(directive, msg);
  1138. }
  1139. if (!documentOptions[version]) {
  1140. const v0 = doc.version || doc.options.version;
  1141. const msg = `Document will be parsed as YAML ${v0} rather than YAML ${version}`;
  1142. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(directive, msg));
  1143. }
  1144. return version;
  1145. }
  1146. function parseDirectives(doc, directives, prevDoc) {
  1147. const directiveComments = [];
  1148. let hasDirectives = false;
  1149. for (const directive of directives) {
  1150. const {
  1151. comment,
  1152. name
  1153. } = directive;
  1154. switch (name) {
  1155. case 'TAG':
  1156. try {
  1157. doc.tagPrefixes.push(resolveTagDirective(doc, directive));
  1158. } catch (error) {
  1159. doc.errors.push(error);
  1160. }
  1161. hasDirectives = true;
  1162. break;
  1163. case 'YAML':
  1164. case 'YAML:1.0':
  1165. if (doc.version) {
  1166. const msg = 'The %YAML directive must only be given at most once per document.';
  1167. doc.errors.push(new _rollupPluginBabelHelpers.YAMLSemanticError(directive, msg));
  1168. }
  1169. try {
  1170. doc.version = resolveYamlDirective(doc, directive);
  1171. } catch (error) {
  1172. doc.errors.push(error);
  1173. }
  1174. hasDirectives = true;
  1175. break;
  1176. default:
  1177. if (name) {
  1178. const msg = `YAML only supports %TAG and %YAML directives, and not %${name}`;
  1179. doc.warnings.push(new _rollupPluginBabelHelpers.YAMLWarning(directive, msg));
  1180. }
  1181. }
  1182. if (comment) directiveComments.push(comment);
  1183. }
  1184. if (prevDoc && !hasDirectives && '1.1' === (doc.version || prevDoc.version || doc.options.version)) {
  1185. const copyTagPrefix = ({
  1186. handle,
  1187. prefix
  1188. }) => ({
  1189. handle,
  1190. prefix
  1191. });
  1192. doc.tagPrefixes = prevDoc.tagPrefixes.map(copyTagPrefix);
  1193. doc.version = prevDoc.version;
  1194. }
  1195. doc.commentBefore = directiveComments.join('\n') || null;
  1196. }
  1197. function assertCollection(contents) {
  1198. if (contents instanceof stringifyNumber.Collection) return true;
  1199. throw new Error('Expected a YAML collection as document contents');
  1200. }
  1201. class Document {
  1202. constructor(value, replacer, options) {
  1203. if (options === undefined && replacer && typeof replacer === 'object' && !Array.isArray(replacer)) {
  1204. options = replacer;
  1205. replacer = undefined;
  1206. }
  1207. this.options = Object.assign({}, defaultOptions, options);
  1208. this.anchors = new Anchors(this.options.anchorPrefix);
  1209. this.commentBefore = null;
  1210. this.comment = null;
  1211. this.directivesEndMarker = null;
  1212. this.errors = [];
  1213. this.schema = null;
  1214. this.tagPrefixes = [];
  1215. this.version = null;
  1216. this.warnings = [];
  1217. if (value === undefined) {
  1218. // note that this.schema is left as null here
  1219. this.contents = null;
  1220. } else if (value instanceof parseCst.Document) {
  1221. this.parse(value);
  1222. } else {
  1223. this.contents = this.createNode(value, {
  1224. replacer
  1225. });
  1226. }
  1227. }
  1228. add(value) {
  1229. assertCollection(this.contents);
  1230. return this.contents.add(value);
  1231. }
  1232. addIn(path, value) {
  1233. assertCollection(this.contents);
  1234. this.contents.addIn(path, value);
  1235. }
  1236. createNode(value, {
  1237. keepUndefined,
  1238. onTagObj,
  1239. replacer,
  1240. tag,
  1241. wrapScalars
  1242. } = {}) {
  1243. this.setSchema();
  1244. if (typeof replacer === 'function') value = replacer.call({
  1245. '': value
  1246. }, '', value);else if (Array.isArray(replacer)) {
  1247. const keyToStr = v => typeof v === 'number' || v instanceof String || v instanceof Number;
  1248. const asStr = replacer.filter(keyToStr).map(String);
  1249. if (asStr.length > 0) replacer = replacer.concat(asStr);
  1250. }
  1251. if (typeof keepUndefined !== 'boolean') keepUndefined = !!this.options.keepUndefined;
  1252. const aliasNodes = [];
  1253. const ctx = {
  1254. keepUndefined,
  1255. onAlias(source) {
  1256. const alias = new stringifyNumber.Alias(source);
  1257. aliasNodes.push(alias);
  1258. return alias;
  1259. },
  1260. onTagObj,
  1261. prevObjects: new Map(),
  1262. replacer,
  1263. schema: this.schema,
  1264. wrapScalars: wrapScalars !== false
  1265. };
  1266. const node = stringifyNumber.createNode(value, tag, ctx);
  1267. for (const alias of aliasNodes) {
  1268. // With circular references, the source node is only resolved after all of
  1269. // its child nodes are. This is why anchors are set only after all of the
  1270. // nodes have been created.
  1271. alias.source = alias.source.node;
  1272. let name = this.anchors.getName(alias.source);
  1273. if (!name) {
  1274. name = this.anchors.newName();
  1275. this.anchors.map[name] = alias.source;
  1276. }
  1277. }
  1278. return node;
  1279. }
  1280. createPair(key, value, options = {}) {
  1281. const k = this.createNode(key, options);
  1282. const v = this.createNode(value, options);
  1283. return new stringifyNumber.Pair(k, v);
  1284. }
  1285. delete(key) {
  1286. assertCollection(this.contents);
  1287. return this.contents.delete(key);
  1288. }
  1289. deleteIn(path) {
  1290. if (stringifyNumber.isEmptyPath(path)) {
  1291. if (this.contents == null) return false;
  1292. this.contents = null;
  1293. return true;
  1294. }
  1295. assertCollection(this.contents);
  1296. return this.contents.deleteIn(path);
  1297. }
  1298. getDefaults() {
  1299. return Document.defaults[this.version] || Document.defaults[this.options.version] || {};
  1300. }
  1301. get(key, keepScalar) {
  1302. return this.contents instanceof stringifyNumber.Collection ? this.contents.get(key, keepScalar) : undefined;
  1303. }
  1304. getIn(path, keepScalar) {
  1305. if (stringifyNumber.isEmptyPath(path)) return !keepScalar && this.contents instanceof stringifyNumber.Scalar ? this.contents.value : this.contents;
  1306. return this.contents instanceof stringifyNumber.Collection ? this.contents.getIn(path, keepScalar) : undefined;
  1307. }
  1308. has(key) {
  1309. return this.contents instanceof stringifyNumber.Collection ? this.contents.has(key) : false;
  1310. }
  1311. hasIn(path) {
  1312. if (stringifyNumber.isEmptyPath(path)) return this.contents !== undefined;
  1313. return this.contents instanceof stringifyNumber.Collection ? this.contents.hasIn(path) : false;
  1314. }
  1315. set(key, value) {
  1316. if (this.contents == null) {
  1317. this.setSchema();
  1318. this.contents = stringifyNumber.collectionFromPath(this.schema, [key], value);
  1319. } else {
  1320. assertCollection(this.contents);
  1321. this.contents.set(key, value);
  1322. }
  1323. }
  1324. setIn(path, value) {
  1325. if (stringifyNumber.isEmptyPath(path)) this.contents = value;else if (this.contents == null) {
  1326. this.setSchema();
  1327. this.contents = stringifyNumber.collectionFromPath(this.schema, path, value);
  1328. } else {
  1329. assertCollection(this.contents);
  1330. this.contents.setIn(path, value);
  1331. }
  1332. }
  1333. setSchema(id, customTags) {
  1334. if (!id && !customTags && this.schema) return;
  1335. if (typeof id === 'number') id = id.toFixed(1);
  1336. if (id === '1.0' || id === '1.1' || id === '1.2') {
  1337. if (this.version) this.version = id;else this.options.version = id;
  1338. delete this.options.schema;
  1339. } else if (id && typeof id === 'string') {
  1340. this.options.schema = id;
  1341. }
  1342. if (Array.isArray(customTags)) this.options.customTags = customTags;
  1343. const opt = Object.assign({}, this.getDefaults(), this.options);
  1344. this.schema = new Schema.Schema(opt);
  1345. }
  1346. parse(node, prevDoc) {
  1347. if (this.options.keepCstNodes) this.cstNode = node;
  1348. if (this.options.keepNodeTypes) this.type = 'DOCUMENT';
  1349. const {
  1350. directives = [],
  1351. contents = [],
  1352. directivesEndMarker,
  1353. error,
  1354. valueRange
  1355. } = node;
  1356. if (error) {
  1357. if (!error.source) error.source = this;
  1358. this.errors.push(error);
  1359. }
  1360. parseDirectives(this, directives, prevDoc);
  1361. if (directivesEndMarker) this.directivesEndMarker = true;
  1362. this.range = valueRange ? [valueRange.start, valueRange.end] : null;
  1363. this.setSchema();
  1364. this.anchors._cstAliases = [];
  1365. parseContents(this, contents);
  1366. this.anchors.resolveNodes();
  1367. if (this.options.prettyErrors) {
  1368. for (const error of this.errors) if (error instanceof _rollupPluginBabelHelpers.YAMLError) error.makePretty();
  1369. for (const warn of this.warnings) if (warn instanceof _rollupPluginBabelHelpers.YAMLError) warn.makePretty();
  1370. }
  1371. return this;
  1372. }
  1373. listNonDefaultTags() {
  1374. return listTagNames(this.contents).filter(t => t.indexOf(_rollupPluginBabelHelpers.defaultTagPrefix) !== 0);
  1375. }
  1376. setTagPrefix(handle, prefix) {
  1377. if (handle[0] !== '!' || handle[handle.length - 1] !== '!') throw new Error('Handle must start and end with !');
  1378. if (prefix) {
  1379. const prev = this.tagPrefixes.find(p => p.handle === handle);
  1380. if (prev) prev.prefix = prefix;else this.tagPrefixes.push({
  1381. handle,
  1382. prefix
  1383. });
  1384. } else {
  1385. this.tagPrefixes = this.tagPrefixes.filter(p => p.handle !== handle);
  1386. }
  1387. }
  1388. toJS({
  1389. json,
  1390. jsonArg,
  1391. mapAsMap,
  1392. onAnchor,
  1393. reviver
  1394. } = {}) {
  1395. const anchorNodes = Object.values(this.anchors.map).map(node => [node, {
  1396. alias: [],
  1397. aliasCount: 0,
  1398. count: 1
  1399. }]);
  1400. const anchors = anchorNodes.length > 0 ? new Map(anchorNodes) : null;
  1401. const ctx = {
  1402. anchors,
  1403. doc: this,
  1404. indentStep: ' ',
  1405. keep: !json,
  1406. mapAsMap: typeof mapAsMap === 'boolean' ? mapAsMap : !!this.options.mapAsMap,
  1407. maxAliasCount: this.options.maxAliasCount,
  1408. stringify // Requiring directly in Pair would create circular dependencies
  1409. };
  1410. const res = stringifyNumber.toJS(this.contents, jsonArg || '', ctx);
  1411. if (typeof onAnchor === 'function' && anchors) for (const {
  1412. count,
  1413. res
  1414. } of anchors.values()) onAnchor(res, count);
  1415. return typeof reviver === 'function' ? applyReviver(reviver, {
  1416. '': res
  1417. }, '', res) : res;
  1418. }
  1419. toJSON(jsonArg, onAnchor) {
  1420. return this.toJS({
  1421. json: true,
  1422. jsonArg,
  1423. mapAsMap: false,
  1424. onAnchor
  1425. });
  1426. }
  1427. toString() {
  1428. if (this.errors.length > 0) throw new Error('Document with errors cannot be stringified');
  1429. const indentSize = this.options.indent;
  1430. if (!Number.isInteger(indentSize) || indentSize <= 0) {
  1431. const s = JSON.stringify(indentSize);
  1432. throw new Error(`"indent" option must be a positive integer, not ${s}`);
  1433. }
  1434. this.setSchema();
  1435. const lines = [];
  1436. let hasDirectives = false;
  1437. if (this.version) {
  1438. let vd = '%YAML 1.2';
  1439. if (this.schema.name === 'yaml-1.1') {
  1440. if (this.version === '1.0') vd = '%YAML:1.0';else if (this.version === '1.1') vd = '%YAML 1.1';
  1441. }
  1442. lines.push(vd);
  1443. hasDirectives = true;
  1444. }
  1445. const tagNames = this.listNonDefaultTags();
  1446. this.tagPrefixes.forEach(({
  1447. handle,
  1448. prefix
  1449. }) => {
  1450. if (tagNames.some(t => t.indexOf(prefix) === 0)) {
  1451. lines.push(`%TAG ${handle} ${prefix}`);
  1452. hasDirectives = true;
  1453. }
  1454. });
  1455. if (hasDirectives || this.directivesEndMarker) lines.push('---');
  1456. if (this.commentBefore) {
  1457. if (hasDirectives || !this.directivesEndMarker) lines.unshift('');
  1458. lines.unshift(this.commentBefore.replace(/^/gm, '#'));
  1459. }
  1460. const ctx = {
  1461. anchors: Object.create(null),
  1462. doc: this,
  1463. indent: '',
  1464. indentStep: ' '.repeat(indentSize),
  1465. stringify // Requiring directly in nodes would create circular dependencies
  1466. };
  1467. let chompKeep = false;
  1468. let contentComment = null;
  1469. if (this.contents) {
  1470. if (this.contents instanceof stringifyNumber.Node) {
  1471. if (this.contents.spaceBefore && (hasDirectives || this.directivesEndMarker)) lines.push('');
  1472. if (this.contents.commentBefore) lines.push(this.contents.commentBefore.replace(/^/gm, '#')); // top-level block scalars need to be indented if followed by a comment
  1473. ctx.forceBlockIndent = !!this.comment;
  1474. contentComment = this.contents.comment;
  1475. }
  1476. const onChompKeep = contentComment ? null : () => chompKeep = true;
  1477. const body = stringify(this.contents, ctx, () => contentComment = null, onChompKeep);
  1478. lines.push(stringifyNumber.addComment(body, '', contentComment));
  1479. } else {
  1480. lines.push(stringify(this.contents, ctx));
  1481. }
  1482. if (this.comment) {
  1483. if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '') lines.push('');
  1484. lines.push(this.comment.replace(/^/gm, '#'));
  1485. }
  1486. return lines.join('\n') + '\n';
  1487. }
  1488. }
  1489. _rollupPluginBabelHelpers._defineProperty(Document, "defaults", documentOptions);
  1490. exports.Document = Document;
  1491. exports.defaultOptions = defaultOptions;
  1492. exports.scalarOptions = scalarOptions;