| ; | |
| var resolveBlockScalar = require('../compose/resolve-block-scalar.js'); | |
| var resolveFlowScalar = require('../compose/resolve-flow-scalar.js'); | |
| var errors = require('../errors.js'); | |
| var stringifyString = require('../stringify/stringifyString.js'); | |
| function resolveAsScalar(token, strict = true, onError) { | |
| if (token) { | |
| const _onError = (pos, code, message) => { | |
| const offset = typeof pos === 'number' ? pos : Array.isArray(pos) ? pos[0] : pos.offset; | |
| if (onError) | |
| onError(offset, code, message); | |
| else | |
| throw new errors.YAMLParseError([offset, offset + 1], code, message); | |
| }; | |
| switch (token.type) { | |
| case 'scalar': | |
| case 'single-quoted-scalar': | |
| case 'double-quoted-scalar': | |
| return resolveFlowScalar.resolveFlowScalar(token, strict, _onError); | |
| case 'block-scalar': | |
| return resolveBlockScalar.resolveBlockScalar({ options: { strict } }, token, _onError); | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * Create a new scalar token with `value` | |
| * | |
| * Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`, | |
| * as this function does not support any schema operations and won't check for such conflicts. | |
| * | |
| * @param value The string representation of the value, which will have its content properly indented. | |
| * @param context.end Comments and whitespace after the end of the value, or after the block scalar header. If undefined, a newline will be added. | |
| * @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value. | |
| * @param context.indent The indent level of the token. | |
| * @param context.inFlow Is this scalar within a flow collection? This may affect the resolved type of the token's value. | |
| * @param context.offset The offset position of the token. | |
| * @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`. | |
| */ | |
| function createScalarToken(value, context) { | |
| const { implicitKey = false, indent, inFlow = false, offset = -1, type = 'PLAIN' } = context; | |
| const source = stringifyString.stringifyString({ type, value }, { | |
| implicitKey, | |
| indent: indent > 0 ? ' '.repeat(indent) : '', | |
| inFlow, | |
| options: { blockQuote: true, lineWidth: -1 } | |
| }); | |
| const end = context.end ?? [ | |
| { type: 'newline', offset: -1, indent, source: '\n' } | |
| ]; | |
| switch (source[0]) { | |
| case '|': | |
| case '>': { | |
| const he = source.indexOf('\n'); | |
| const head = source.substring(0, he); | |
| const body = source.substring(he + 1) + '\n'; | |
| const props = [ | |
| { type: 'block-scalar-header', offset, indent, source: head } | |
| ]; | |
| if (!addEndtoBlockProps(props, end)) | |
| props.push({ type: 'newline', offset: -1, indent, source: '\n' }); | |
| return { type: 'block-scalar', offset, indent, props, source: body }; | |
| } | |
| case '"': | |
| return { type: 'double-quoted-scalar', offset, indent, source, end }; | |
| case "'": | |
| return { type: 'single-quoted-scalar', offset, indent, source, end }; | |
| default: | |
| return { type: 'scalar', offset, indent, source, end }; | |
| } | |
| } | |
| /** | |
| * Set the value of `token` to the given string `value`, overwriting any previous contents and type that it may have. | |
| * | |
| * Best efforts are made to retain any comments previously associated with the `token`, | |
| * though all contents within a collection's `items` will be overwritten. | |
| * | |
| * Values that represent an actual string but may be parsed as a different type should use a `type` other than `'PLAIN'`, | |
| * as this function does not support any schema operations and won't check for such conflicts. | |
| * | |
| * @param token Any token. If it does not include an `indent` value, the value will be stringified as if it were an implicit key. | |
| * @param value The string representation of the value, which will have its content properly indented. | |
| * @param context.afterKey In most cases, values after a key should have an additional level of indentation. | |
| * @param context.implicitKey Being within an implicit key may affect the resolved type of the token's value. | |
| * @param context.inFlow Being within a flow collection may affect the resolved type of the token's value. | |
| * @param context.type The preferred type of the scalar token. If undefined, the previous type of the `token` will be used, defaulting to `'PLAIN'`. | |
| */ | |
| function setScalarValue(token, value, context = {}) { | |
| let { afterKey = false, implicitKey = false, inFlow = false, type } = context; | |
| let indent = 'indent' in token ? token.indent : null; | |
| if (afterKey && typeof indent === 'number') | |
| indent += 2; | |
| if (!type) | |
| switch (token.type) { | |
| case 'single-quoted-scalar': | |
| type = 'QUOTE_SINGLE'; | |
| break; | |
| case 'double-quoted-scalar': | |
| type = 'QUOTE_DOUBLE'; | |
| break; | |
| case 'block-scalar': { | |
| const header = token.props[0]; | |
| if (header.type !== 'block-scalar-header') | |
| throw new Error('Invalid block scalar header'); | |
| type = header.source[0] === '>' ? 'BLOCK_FOLDED' : 'BLOCK_LITERAL'; | |
| break; | |
| } | |
| default: | |
| type = 'PLAIN'; | |
| } | |
| const source = stringifyString.stringifyString({ type, value }, { | |
| implicitKey: implicitKey || indent === null, | |
| indent: indent !== null && indent > 0 ? ' '.repeat(indent) : '', | |
| inFlow, | |
| options: { blockQuote: true, lineWidth: -1 } | |
| }); | |
| switch (source[0]) { | |
| case '|': | |
| case '>': | |
| setBlockScalarValue(token, source); | |
| break; | |
| case '"': | |
| setFlowScalarValue(token, source, 'double-quoted-scalar'); | |
| break; | |
| case "'": | |
| setFlowScalarValue(token, source, 'single-quoted-scalar'); | |
| break; | |
| default: | |
| setFlowScalarValue(token, source, 'scalar'); | |
| } | |
| } | |
| function setBlockScalarValue(token, source) { | |
| const he = source.indexOf('\n'); | |
| const head = source.substring(0, he); | |
| const body = source.substring(he + 1) + '\n'; | |
| if (token.type === 'block-scalar') { | |
| const header = token.props[0]; | |
| if (header.type !== 'block-scalar-header') | |
| throw new Error('Invalid block scalar header'); | |
| header.source = head; | |
| token.source = body; | |
| } | |
| else { | |
| const { offset } = token; | |
| const indent = 'indent' in token ? token.indent : -1; | |
| const props = [ | |
| { type: 'block-scalar-header', offset, indent, source: head } | |
| ]; | |
| if (!addEndtoBlockProps(props, 'end' in token ? token.end : undefined)) | |
| props.push({ type: 'newline', offset: -1, indent, source: '\n' }); | |
| for (const key of Object.keys(token)) | |
| if (key !== 'type' && key !== 'offset') | |
| delete token[key]; | |
| Object.assign(token, { type: 'block-scalar', indent, props, source: body }); | |
| } | |
| } | |
| /** @returns `true` if last token is a newline */ | |
| function addEndtoBlockProps(props, end) { | |
| if (end) | |
| for (const st of end) | |
| switch (st.type) { | |
| case 'space': | |
| case 'comment': | |
| props.push(st); | |
| break; | |
| case 'newline': | |
| props.push(st); | |
| return true; | |
| } | |
| return false; | |
| } | |
| function setFlowScalarValue(token, source, type) { | |
| switch (token.type) { | |
| case 'scalar': | |
| case 'double-quoted-scalar': | |
| case 'single-quoted-scalar': | |
| token.type = type; | |
| token.source = source; | |
| break; | |
| case 'block-scalar': { | |
| const end = token.props.slice(1); | |
| let oa = source.length; | |
| if (token.props[0].type === 'block-scalar-header') | |
| oa -= token.props[0].source.length; | |
| for (const tok of end) | |
| tok.offset += oa; | |
| delete token.props; | |
| Object.assign(token, { type, source, end }); | |
| break; | |
| } | |
| case 'block-map': | |
| case 'block-seq': { | |
| const offset = token.offset + source.length; | |
| const nl = { type: 'newline', offset, indent: token.indent, source: '\n' }; | |
| delete token.items; | |
| Object.assign(token, { type, source, end: [nl] }); | |
| break; | |
| } | |
| default: { | |
| const indent = 'indent' in token ? token.indent : -1; | |
| const end = 'end' in token && Array.isArray(token.end) | |
| ? token.end.filter(st => st.type === 'space' || | |
| st.type === 'comment' || | |
| st.type === 'newline') | |
| : []; | |
| for (const key of Object.keys(token)) | |
| if (key !== 'type' && key !== 'offset') | |
| delete token[key]; | |
| Object.assign(token, { type, indent, source, end }); | |
| } | |
| } | |
| } | |
| exports.createScalarToken = createScalarToken; | |
| exports.resolveAsScalar = resolveAsScalar; | |
| exports.setScalarValue = setScalarValue; | |
Xet Storage Details
- Size:
- 9.38 kB
- Xet hash:
- 284cd841aa144c5ea0a0867aaae3411b769a966b63bd54725029a361b25c3e33
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.