| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- function appendPropertyInAstObject(recorder, node, propertyName, value, indent) {
- const indentStr = _buildIndent(indent);
- let index = node.start.offset + 1;
- if (node.properties.length > 0) {
- // Insert comma.
- const last = node.properties[node.properties.length - 1];
- const { text, end } = last;
- const commaIndex = text.endsWith('\n') ? end.offset - 1 : end.offset;
- recorder.insertRight(commaIndex, ',');
- index = end.offset;
- }
- const content = _stringifyContent(value, indentStr);
- recorder.insertRight(index, (node.properties.length === 0 && indent ? '\n' : '')
- + ' '.repeat(indent)
- + `"${propertyName}":${indent ? ' ' : ''}${content}`
- + indentStr.slice(0, -indent));
- }
- exports.appendPropertyInAstObject = appendPropertyInAstObject;
- function insertPropertyInAstObjectInOrder(recorder, node, propertyName, value, indent) {
- if (node.properties.length === 0) {
- appendPropertyInAstObject(recorder, node, propertyName, value, indent);
- return;
- }
- // Find insertion info.
- let insertAfterProp = null;
- let prev = null;
- let isLastProp = false;
- const last = node.properties[node.properties.length - 1];
- for (const prop of node.properties) {
- if (prop.key.value > propertyName) {
- if (prev) {
- insertAfterProp = prev;
- }
- break;
- }
- if (prop === last) {
- isLastProp = true;
- insertAfterProp = last;
- }
- prev = prop;
- }
- if (isLastProp) {
- appendPropertyInAstObject(recorder, node, propertyName, value, indent);
- return;
- }
- const indentStr = _buildIndent(indent);
- const insertIndex = insertAfterProp === null
- ? node.start.offset + 1
- : insertAfterProp.end.offset + 1;
- const content = _stringifyContent(value, indentStr);
- recorder.insertRight(insertIndex, indentStr
- + `"${propertyName}":${indent ? ' ' : ''}${content}`
- + ',');
- }
- exports.insertPropertyInAstObjectInOrder = insertPropertyInAstObjectInOrder;
- function removePropertyInAstObject(recorder, node, propertyName) {
- // Find the property inside the object.
- const propIdx = node.properties.findIndex(prop => prop.key.value === propertyName);
- if (propIdx === -1) {
- // There's nothing to remove.
- return;
- }
- if (node.properties.length === 1) {
- // This is a special case. Everything should be removed, including indentation.
- recorder.remove(node.start.offset, node.end.offset - node.start.offset);
- recorder.insertRight(node.start.offset, '{}');
- return;
- }
- // The AST considers commas and indentation to be part of the preceding property.
- // To get around messy comma and identation management, we can work over the range between
- // two properties instead.
- const previousProp = node.properties[propIdx - 1];
- const targetProp = node.properties[propIdx];
- const nextProp = node.properties[propIdx + 1];
- let start, end;
- if (previousProp) {
- // Given the object below, and intending to remove the `m` property:
- // "{\n \"a\": \"a\",\n \"m\": \"m\",\n \"z\": \"z\"\n}"
- // ^---------------^
- // Removing the range above results in:
- // "{\n \"a\": \"a\",\n \"z\": \"z\"\n}"
- start = previousProp.end;
- end = targetProp.end;
- }
- else {
- // If there's no previousProp there is a nextProp, since we've specialcased the 1 length case.
- // Given the object below, and intending to remove the `a` property:
- // "{\n \"a\": \"a\",\n \"m\": \"m\",\n \"z\": \"z\"\n}"
- // ^---------------^
- // Removing the range above results in:
- // "{\n \"m\": \"m\",\n \"z\": \"z\"\n}"
- start = targetProp.start;
- end = nextProp.start;
- }
- recorder.remove(start.offset, end.offset - start.offset);
- if (!nextProp) {
- recorder.insertRight(start.offset, '\n');
- }
- }
- exports.removePropertyInAstObject = removePropertyInAstObject;
- function appendValueInAstArray(recorder, node, value, indent = 4) {
- let indentStr = _buildIndent(indent);
- let index = node.start.offset + 1;
- // tslint:disable-next-line: no-any
- let newNodes;
- if (node.elements.length > 0) {
- // Insert comma.
- const { end } = node.elements[node.elements.length - 1];
- const isClosingOnSameLine = node.end.offset - end.offset === 1;
- if (isClosingOnSameLine && indent) {
- // Reformat the entire array
- recorder.remove(node.start.offset, node.end.offset - node.start.offset);
- newNodes = [
- ...node.elements.map(({ value }) => value),
- value,
- ];
- index = node.start.offset;
- // In case we are generating the entire node we need to reduce the spacing as
- // otherwise we'd end up having incorrect double spacing
- indent = indent - 2;
- indentStr = _buildIndent(indent);
- }
- else {
- recorder.insertRight(end.offset, ',');
- index = end.offset;
- }
- }
- recorder.insertRight(index, (newNodes ? '' : indentStr)
- + _stringifyContent(newNodes || value, indentStr)
- + (node.elements.length === 0 && indent ? indentStr.substr(0, -indent) + '\n' : ''));
- }
- exports.appendValueInAstArray = appendValueInAstArray;
- function findPropertyInAstObject(node, propertyName) {
- let maybeNode = null;
- for (const property of node.properties) {
- if (property.key.value == propertyName) {
- maybeNode = property.value;
- }
- }
- return maybeNode;
- }
- exports.findPropertyInAstObject = findPropertyInAstObject;
- function _buildIndent(count) {
- return count ? '\n' + ' '.repeat(count) : '';
- }
- function _stringifyContent(value, indentStr) {
- // TODO: Add snapshot tests
- // The 'space' value is 2, because we want to add 2 additional
- // indents from the 'key' node.
- // If we use the indent provided we will have double indents:
- // "budgets": [
- // {
- // "type": "initial",
- // "maximumWarning": "2mb",
- // "maximumError": "5mb"
- // },
- // {
- // "type": "anyComponentStyle",
- // 'maximumWarning": "5kb"
- // }
- // ]
- return JSON.stringify(value, null, 2).replace(/\n/g, indentStr);
- }
|