1 | (function (factory) {
|
2 | if (typeof module === "object" && typeof module.exports === "object") {
|
3 | var v = factory(require, exports);
|
4 | if (v !== undefined) module.exports = v;
|
5 | }
|
6 | else if (typeof define === "function" && define.amd) {
|
7 | define(["require", "exports", "./format", "./parser"], factory);
|
8 | }
|
9 | })(function (require, exports) {
|
10 | |
11 |
|
12 |
|
13 |
|
14 | 'use strict';
|
15 | Object.defineProperty(exports, "__esModule", { value: true });
|
16 | var format_1 = require("./format");
|
17 | var parser_1 = require("./parser");
|
18 | function removeProperty(text, path, formattingOptions) {
|
19 | return setProperty(text, path, void 0, formattingOptions);
|
20 | }
|
21 | exports.removeProperty = removeProperty;
|
22 | function setProperty(text, originalPath, value, formattingOptions, getInsertionIndex) {
|
23 | var _a;
|
24 | var path = originalPath.slice();
|
25 | var errors = [];
|
26 | var root = parser_1.parseTree(text, errors);
|
27 | var parent = void 0;
|
28 | var lastSegment = void 0;
|
29 | while (path.length > 0) {
|
30 | lastSegment = path.pop();
|
31 | parent = parser_1.findNodeAtLocation(root, path);
|
32 | if (parent === void 0 && value !== void 0) {
|
33 | if (typeof lastSegment === 'string') {
|
34 | value = (_a = {}, _a[lastSegment] = value, _a);
|
35 | }
|
36 | else {
|
37 | value = [value];
|
38 | }
|
39 | }
|
40 | else {
|
41 | break;
|
42 | }
|
43 | }
|
44 | if (!parent) {
|
45 |
|
46 | if (value === void 0) {
|
47 | throw new Error('Can not delete in empty document');
|
48 | }
|
49 | return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions);
|
50 | }
|
51 | else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
|
52 | var existing = parser_1.findNodeAtLocation(parent, [lastSegment]);
|
53 | if (existing !== void 0) {
|
54 | if (value === void 0) {
|
55 | if (!existing.parent) {
|
56 | throw new Error('Malformed AST');
|
57 | }
|
58 | var propertyIndex = parent.children.indexOf(existing.parent);
|
59 | var removeBegin = void 0;
|
60 | var removeEnd = existing.parent.offset + existing.parent.length;
|
61 | if (propertyIndex > 0) {
|
62 |
|
63 | var previous = parent.children[propertyIndex - 1];
|
64 | removeBegin = previous.offset + previous.length;
|
65 | }
|
66 | else {
|
67 | removeBegin = parent.offset + 1;
|
68 | if (parent.children.length > 1) {
|
69 |
|
70 | var next = parent.children[1];
|
71 | removeEnd = next.offset;
|
72 | }
|
73 | }
|
74 | return withFormatting(text, { offset: removeBegin, length: removeEnd - removeBegin, content: '' }, formattingOptions);
|
75 | }
|
76 | else {
|
77 |
|
78 | return withFormatting(text, { offset: existing.offset, length: existing.length, content: JSON.stringify(value) }, formattingOptions);
|
79 | }
|
80 | }
|
81 | else {
|
82 | if (value === void 0) {
|
83 | return [];
|
84 | }
|
85 | var newProperty = JSON.stringify(lastSegment) + ": " + JSON.stringify(value);
|
86 | var index = getInsertionIndex ? getInsertionIndex(parent.children.map(function (p) { return p.children[0].value; })) : parent.children.length;
|
87 | var edit = void 0;
|
88 | if (index > 0) {
|
89 | var previous = parent.children[index - 1];
|
90 | edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
91 | }
|
92 | else if (parent.children.length === 0) {
|
93 | edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
94 | }
|
95 | else {
|
96 | edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
|
97 | }
|
98 | return withFormatting(text, edit, formattingOptions);
|
99 | }
|
100 | }
|
101 | else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
|
102 | var insertIndex = lastSegment;
|
103 | if (insertIndex === -1) {
|
104 |
|
105 | var newProperty = "" + JSON.stringify(value);
|
106 | var edit = void 0;
|
107 | if (parent.children.length === 0) {
|
108 | edit = { offset: parent.offset + 1, length: 0, content: newProperty };
|
109 | }
|
110 | else {
|
111 | var previous = parent.children[parent.children.length - 1];
|
112 | edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
|
113 | }
|
114 | return withFormatting(text, edit, formattingOptions);
|
115 | }
|
116 | else {
|
117 | if (value === void 0 && parent.children.length >= 0) {
|
118 |
|
119 | var removalIndex = lastSegment;
|
120 | var toRemove = parent.children[removalIndex];
|
121 | var edit = void 0;
|
122 | if (parent.children.length === 1) {
|
123 |
|
124 | edit = { offset: parent.offset + 1, length: parent.length - 2, content: '' };
|
125 | }
|
126 | else if (parent.children.length - 1 === removalIndex) {
|
127 |
|
128 | var previous = parent.children[removalIndex - 1];
|
129 | var offset = previous.offset + previous.length;
|
130 | var parentEndOffset = parent.offset + parent.length;
|
131 | edit = { offset: offset, length: parentEndOffset - 2 - offset, content: '' };
|
132 | }
|
133 | else {
|
134 | edit = { offset: toRemove.offset, length: parent.children[removalIndex + 1].offset - toRemove.offset, content: '' };
|
135 | }
|
136 | return withFormatting(text, edit, formattingOptions);
|
137 | }
|
138 | else {
|
139 | throw new Error('Array modification not supported yet');
|
140 | }
|
141 | }
|
142 | }
|
143 | else {
|
144 | throw new Error("Can not add " + (typeof lastSegment !== 'number' ? 'index' : 'property') + " to parent of type " + parent.type);
|
145 | }
|
146 | }
|
147 | exports.setProperty = setProperty;
|
148 | function withFormatting(text, edit, formattingOptions) {
|
149 |
|
150 | var newText = applyEdit(text, edit);
|
151 |
|
152 | var begin = edit.offset;
|
153 | var end = edit.offset + edit.content.length;
|
154 | if (edit.length === 0 || edit.content.length === 0) {
|
155 | while (begin > 0 && !format_1.isEOL(newText, begin - 1)) {
|
156 | begin--;
|
157 | }
|
158 | while (end < newText.length && !format_1.isEOL(newText, end)) {
|
159 | end++;
|
160 | }
|
161 | }
|
162 | var edits = format_1.format(newText, { offset: begin, length: end - begin }, formattingOptions);
|
163 |
|
164 | for (var i = edits.length - 1; i >= 0; i--) {
|
165 | var edit_1 = edits[i];
|
166 | newText = applyEdit(newText, edit_1);
|
167 | begin = Math.min(begin, edit_1.offset);
|
168 | end = Math.max(end, edit_1.offset + edit_1.length);
|
169 | end += edit_1.content.length - edit_1.length;
|
170 | }
|
171 |
|
172 | var editLength = text.length - (newText.length - end) - begin;
|
173 | return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
|
174 | }
|
175 | function applyEdit(text, edit) {
|
176 | return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
|
177 | }
|
178 | exports.applyEdit = applyEdit;
|
179 | function isWS(text, offset) {
|
180 | return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
|
181 | }
|
182 | exports.isWS = isWS;
|
183 | });
|