1 | "use strict";
|
2 | var fs = require('fs');
|
3 | var denodeify = require('denodeify');
|
4 | var readFile = denodeify(fs.readFile);
|
5 | var writeFile = denodeify(fs.writeFile);
|
6 | exports.NodeHost = {
|
7 | write: function (path, content) { return writeFile(path, content, 'utf8'); },
|
8 | read: function (path) { return readFile(path, 'utf8'); }
|
9 | };
|
10 |
|
11 |
|
12 |
|
13 | var NoopChange = (function () {
|
14 | function NoopChange() {
|
15 | this.description = 'No operation.';
|
16 | this.order = Infinity;
|
17 | this.path = null;
|
18 | }
|
19 | NoopChange.prototype.apply = function () { return Promise.resolve(); };
|
20 | return NoopChange;
|
21 | }());
|
22 | exports.NoopChange = NoopChange;
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | var MultiChange = (function () {
|
29 | function MultiChange() {
|
30 | var _this = this;
|
31 | var changes = [];
|
32 | for (var _i = 0; _i < arguments.length; _i++) {
|
33 | changes[_i - 0] = arguments[_i];
|
34 | }
|
35 | this._changes = [];
|
36 | (_a = []).concat.apply(_a, changes).forEach(function (change) { return _this.appendChange(change); });
|
37 | var _a;
|
38 | }
|
39 | MultiChange.prototype.appendChange = function (change) {
|
40 |
|
41 | if (change instanceof NoopChange) {
|
42 | return;
|
43 | }
|
44 |
|
45 | if (this._path === undefined) {
|
46 | this._path = change.path;
|
47 | }
|
48 | else if (change.path !== this._path) {
|
49 | throw new Error('Cannot apply a change to a different path.');
|
50 | }
|
51 | this._changes.push(change);
|
52 | };
|
53 | Object.defineProperty(MultiChange.prototype, "description", {
|
54 | get: function () {
|
55 | return "Changes:\n " + this._changes.map(function (x) { return x.description; }).join('\n ');
|
56 | },
|
57 | enumerable: true,
|
58 | configurable: true
|
59 | });
|
60 | Object.defineProperty(MultiChange.prototype, "order", {
|
61 |
|
62 | get: function () { return Math.max.apply(Math, this._changes.map(function (c) { return c.order; })); },
|
63 | enumerable: true,
|
64 | configurable: true
|
65 | });
|
66 | Object.defineProperty(MultiChange.prototype, "path", {
|
67 | get: function () { return this._path; },
|
68 | enumerable: true,
|
69 | configurable: true
|
70 | });
|
71 | MultiChange.prototype.apply = function (host) {
|
72 | return this._changes
|
73 | .sort(function (a, b) { return b.order - a.order; })
|
74 | .reduce(function (promise, change) {
|
75 | return promise.then(function () { return change.apply(host); });
|
76 | }, Promise.resolve());
|
77 | };
|
78 | return MultiChange;
|
79 | }());
|
80 | exports.MultiChange = MultiChange;
|
81 |
|
82 |
|
83 |
|
84 | var InsertChange = (function () {
|
85 | function InsertChange(path, pos, toAdd) {
|
86 | this.path = path;
|
87 | this.pos = pos;
|
88 | this.toAdd = toAdd;
|
89 | if (pos < 0) {
|
90 | throw new Error('Negative positions are invalid');
|
91 | }
|
92 | this.description = "Inserted " + toAdd + " into position " + pos + " of " + path;
|
93 | this.order = pos;
|
94 | }
|
95 | |
96 |
|
97 |
|
98 | InsertChange.prototype.apply = function (host) {
|
99 | var _this = this;
|
100 | return host.read(this.path).then(function (content) {
|
101 | var prefix = content.substring(0, _this.pos);
|
102 | var suffix = content.substring(_this.pos);
|
103 | return host.write(_this.path, "" + prefix + _this.toAdd + suffix);
|
104 | });
|
105 | };
|
106 | return InsertChange;
|
107 | }());
|
108 | exports.InsertChange = InsertChange;
|
109 |
|
110 |
|
111 |
|
112 | var RemoveChange = (function () {
|
113 | function RemoveChange(path, pos, toRemove) {
|
114 | this.path = path;
|
115 | this.pos = pos;
|
116 | this.toRemove = toRemove;
|
117 | if (pos < 0) {
|
118 | throw new Error('Negative positions are invalid');
|
119 | }
|
120 | this.description = "Removed " + toRemove + " into position " + pos + " of " + path;
|
121 | this.order = pos;
|
122 | }
|
123 | RemoveChange.prototype.apply = function (host) {
|
124 | var _this = this;
|
125 | return host.read(this.path).then(function (content) {
|
126 | var prefix = content.substring(0, _this.pos);
|
127 | var suffix = content.substring(_this.pos + _this.toRemove.length);
|
128 |
|
129 | return host.write(_this.path, "" + prefix + suffix);
|
130 | });
|
131 | };
|
132 | return RemoveChange;
|
133 | }());
|
134 | exports.RemoveChange = RemoveChange;
|
135 |
|
136 |
|
137 |
|
138 | var ReplaceChange = (function () {
|
139 | function ReplaceChange(path, pos, oldText, newText) {
|
140 | this.path = path;
|
141 | this.pos = pos;
|
142 | this.oldText = oldText;
|
143 | this.newText = newText;
|
144 | if (pos < 0) {
|
145 | throw new Error('Negative positions are invalid');
|
146 | }
|
147 | this.description = "Replaced " + oldText + " into position " + pos + " of " + path + " with " + newText;
|
148 | this.order = pos;
|
149 | }
|
150 | ReplaceChange.prototype.apply = function (host) {
|
151 | var _this = this;
|
152 | return host.read(this.path).then(function (content) {
|
153 | var prefix = content.substring(0, _this.pos);
|
154 | var suffix = content.substring(_this.pos + _this.oldText.length);
|
155 | var text = content.substring(_this.pos, _this.pos + _this.oldText.length);
|
156 | if (text !== _this.oldText) {
|
157 | return Promise.reject(new Error("Invalid replace: \"" + text + "\" != \"" + _this.oldText + "\"."));
|
158 | }
|
159 |
|
160 | return host.write(_this.path, "" + prefix + _this.newText + suffix);
|
161 | });
|
162 | };
|
163 | return ReplaceChange;
|
164 | }());
|
165 | exports.ReplaceChange = ReplaceChange;
|
166 |
|
\ | No newline at end of file |