kni 4.0.3 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +9 -7
- package/console.js +33 -35
- package/describe.js +54 -89
- package/document.js +103 -72
- package/engine.js +436 -407
- package/entry.js +88 -0
- package/evaluate.js +221 -228
- package/excerpt.js +117 -115
- package/grammar.js +1025 -785
- package/html.js +174 -167
- package/inline-lexer.js +155 -125
- package/kni.js +286 -279
- package/link.js +50 -52
- package/outline-lexer.js +64 -37
- package/package.json +27 -34
- package/parser.js +32 -20
- package/path.js +34 -46
- package/readline.js +89 -79
- package/scanner.js +101 -78
- package/scope.js +32 -36
- package/story.js +174 -165
- package/test.js +6 -0
- package/translate-json.js +3 -5
- package/tsconfig.json +11 -0
- package/verify.js +121 -117
- package/wrapper.js +37 -41
- package/template.js +0 -69
package/kni.js
CHANGED
|
@@ -1,316 +1,323 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
2
|
+
|
|
3
|
+
import {pathToFileURL} from 'url';
|
|
4
|
+
import tee from 'tee';
|
|
5
|
+
import Console from './console.js';
|
|
6
|
+
import Readline from './readline.js';
|
|
7
|
+
import Engine from './engine.js';
|
|
8
|
+
import Scanner from './scanner.js';
|
|
9
|
+
import OutlineLexer from './outline-lexer.js';
|
|
10
|
+
import InlineLexer from './inline-lexer.js';
|
|
11
|
+
import Parser from './parser.js';
|
|
12
|
+
import Story from './story.js';
|
|
13
|
+
import * as Path from './path.js';
|
|
14
|
+
import start from './grammar.js';
|
|
15
|
+
import link from './link.js';
|
|
16
|
+
import verify from './verify.js';
|
|
17
|
+
import exec from 'shon/exec.js';
|
|
18
|
+
import usage from './kni.json' with {type: 'json'};
|
|
19
|
+
import xorshift from 'xorshift';
|
|
20
|
+
import table from 'table';
|
|
21
|
+
import describe from './describe.js';
|
|
22
|
+
import makeHtml from './html.js';
|
|
23
|
+
|
|
24
|
+
const {default: tableDefault, getBorderCharacters} = table;
|
|
25
|
+
|
|
26
|
+
const run = (args, out, done) => {
|
|
27
|
+
const config = exec(usage, args);
|
|
28
|
+
if (!config) {
|
|
29
|
+
done(null);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
serial(config.scripts, readAndKeep, (err, kniscripts) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
done(err);
|
|
36
|
+
return;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
let interactive = true;
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
if (config.transcript === out) {
|
|
42
|
+
config.transcript = null;
|
|
43
|
+
}
|
|
44
|
+
if (config.transcript) {
|
|
45
|
+
out = tee(config.transcript, out);
|
|
46
|
+
}
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
let states;
|
|
49
|
+
if (config.fromJson) {
|
|
50
|
+
states = JSON.parse(kniscripts[0].content); // TODO test needed
|
|
51
|
+
} else {
|
|
52
|
+
const story = new Story();
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
config.transcript = null;
|
|
47
|
-
}
|
|
48
|
-
if (config.transcript) {
|
|
49
|
-
out = tee(config.transcript, out);
|
|
50
|
-
}
|
|
54
|
+
for (let i = 0; i < kniscripts.length; i++) {
|
|
55
|
+
const kniscript = kniscripts[i].content;
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
states = JSON.parse(knicript);
|
|
55
|
-
|
|
56
|
-
} else {
|
|
57
|
-
var story = new Story();
|
|
58
|
-
|
|
59
|
-
for (var i = 0; i < kniscripts.length; i++) {
|
|
60
|
-
var kniscript = kniscripts[i].content;
|
|
61
|
-
|
|
62
|
-
if (config.debugInput) {
|
|
63
|
-
console.log(kniscript);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
var path = Path.start();
|
|
67
|
-
var base = [];
|
|
68
|
-
if (kniscripts.length > 1) {
|
|
69
|
-
path = kniscripts[i].stream.path;
|
|
70
|
-
path = [path.split('/').pop().split('.').shift()];
|
|
71
|
-
base = path;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
var p = new Parser(grammar.start(story, path, base));
|
|
75
|
-
var il = new InlineLexer(p);
|
|
76
|
-
var ol = new OutlineLexer(il);
|
|
77
|
-
var s = new Scanner(ol, kniscripts[i].stream.path);
|
|
78
|
-
|
|
79
|
-
// Kick off each file with a fresh paragraph.
|
|
80
|
-
p.next('token', '', '//', s);
|
|
81
|
-
|
|
82
|
-
if (config.debugParser) {
|
|
83
|
-
p.debug = true;
|
|
84
|
-
interactive = false;
|
|
85
|
-
}
|
|
86
|
-
if (config.debugInlineLexer) {
|
|
87
|
-
il.debug = true;
|
|
88
|
-
interactive = false;
|
|
89
|
-
}
|
|
90
|
-
if (config.debugOutlineLexer) {
|
|
91
|
-
ol.debug = true;
|
|
92
|
-
interactive = false;
|
|
93
|
-
}
|
|
94
|
-
if (config.debugScanner) {
|
|
95
|
-
s.debug = true;
|
|
96
|
-
interactive = false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
s.next(kniscript);
|
|
100
|
-
s.return();
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
link(story);
|
|
104
|
-
|
|
105
|
-
states = story.states;
|
|
106
|
-
if (story.errors.length) {
|
|
107
|
-
dump(story.errors, process.stderr);
|
|
108
|
-
if (config.transcript != null) {
|
|
109
|
-
dump(story.errors, config.transcript);
|
|
110
|
-
}
|
|
111
|
-
process.exitCode = -1;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
57
|
+
if (config.debugInput) {
|
|
58
|
+
console.log(kniscript);
|
|
114
59
|
}
|
|
115
60
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
interactive = false;
|
|
123
|
-
|
|
124
|
-
} else if (config.toHtml) {
|
|
125
|
-
makeHtml(states, config.toHtml, {
|
|
126
|
-
title: config.htmlTitle,
|
|
127
|
-
color: config.htmlColor,
|
|
128
|
-
backgroundColor: config.htmlBackgroundColor,
|
|
129
|
-
});
|
|
130
|
-
interactive = false;
|
|
61
|
+
let path = Path.start();
|
|
62
|
+
let base = [];
|
|
63
|
+
if (kniscripts.length > 1) {
|
|
64
|
+
path = kniscripts[i].stream.path;
|
|
65
|
+
path = [path.split('/').pop().split('.').shift()];
|
|
66
|
+
base = path;
|
|
131
67
|
}
|
|
132
68
|
|
|
133
|
-
|
|
69
|
+
const p = new Parser(start(story, path, base));
|
|
70
|
+
const il = new InlineLexer(p);
|
|
71
|
+
const ol = new OutlineLexer(il);
|
|
72
|
+
const s = new Scanner(ol, kniscripts[i].stream.path);
|
|
134
73
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
randomer = new xorshift.constructor([
|
|
138
|
-
37615 ^ config.seed,
|
|
139
|
-
54552 ^ config.seed,
|
|
140
|
-
59156 ^ config.seed,
|
|
141
|
-
24695 ^ config.seed
|
|
142
|
-
]);
|
|
143
|
-
}
|
|
74
|
+
// Kick off each file with a fresh paragraph.
|
|
75
|
+
p.next('token', '', '//', s);
|
|
144
76
|
|
|
145
|
-
if (config.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
console.error(err.message);
|
|
149
|
-
process.exitCode = -1;
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
test(kniscript, typescript);
|
|
153
|
-
});
|
|
154
|
-
return;
|
|
77
|
+
if (config.debugParser) {
|
|
78
|
+
p.debug = true;
|
|
79
|
+
interactive = false;
|
|
155
80
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
if (config.debugRuntime) {
|
|
169
|
-
engine.debug = true;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (config.waypoint) {
|
|
173
|
-
read(config.waypoint, function onWaypoint(err, waypoint) {
|
|
174
|
-
if (err) {
|
|
175
|
-
console.error(err.message);
|
|
176
|
-
process.exitCode = -1;
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
waypoint = JSON.parse(waypoint);
|
|
180
|
-
engine.continue(waypoint);
|
|
181
|
-
});
|
|
182
|
-
} else {
|
|
183
|
-
engine.continue();
|
|
184
|
-
}
|
|
81
|
+
if (config.debugInlineLexer) {
|
|
82
|
+
il.debug = true;
|
|
83
|
+
interactive = false;
|
|
84
|
+
}
|
|
85
|
+
if (config.debugOutlineLexer) {
|
|
86
|
+
ol.debug = true;
|
|
87
|
+
interactive = false;
|
|
88
|
+
}
|
|
89
|
+
if (config.debugScanner) {
|
|
90
|
+
s.debug = true;
|
|
91
|
+
interactive = false;
|
|
185
92
|
}
|
|
186
|
-
}
|
|
187
93
|
|
|
188
|
-
|
|
94
|
+
s.next(kniscript);
|
|
95
|
+
s.return();
|
|
96
|
+
}
|
|
189
97
|
|
|
190
|
-
|
|
191
|
-
var result = verify(kniscript, typescript);
|
|
192
|
-
if (!result.pass) {
|
|
193
|
-
console.log(result.actual);
|
|
194
|
-
process.exit(1);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
98
|
+
link(story);
|
|
197
99
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
var key = keys[i];
|
|
203
|
-
var node = states[key];
|
|
204
|
-
var next;
|
|
205
|
-
if (i === keys.length - 1) {
|
|
206
|
-
next = null;
|
|
207
|
-
} else {
|
|
208
|
-
next = keys[i + 1];
|
|
100
|
+
states = story.states;
|
|
101
|
+
if (story.errors.length) {
|
|
102
|
+
if (config.transcript != null) {
|
|
103
|
+
dump(story.errors, config.transcript);
|
|
209
104
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
stripe(i, describe(node)),
|
|
216
|
-
stripe(i, node.drop ? '-' : ' '),
|
|
217
|
-
stripe(i, describeNext(node.next, next))
|
|
218
|
-
]);
|
|
105
|
+
const storyError = new Error('internal story error');
|
|
106
|
+
storyError.story = story;
|
|
107
|
+
done(storyError);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
219
110
|
}
|
|
220
|
-
console.log(table(cells, {
|
|
221
|
-
border: getBorderCharacters('void'),
|
|
222
|
-
columnDefault: {
|
|
223
|
-
paddingLeft: 0,
|
|
224
|
-
paddingRight: 2
|
|
225
|
-
},
|
|
226
|
-
columns: {
|
|
227
|
-
4: {
|
|
228
|
-
width: 40,
|
|
229
|
-
wrapWord: true
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
drawHorizontalLine: no
|
|
233
|
-
}));
|
|
234
|
-
}
|
|
235
111
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
} else {
|
|
240
|
-
return '\x1b[90m' + text + '\x1b[0m';
|
|
112
|
+
if (config.describe) {
|
|
113
|
+
describeStory(states, out, done);
|
|
114
|
+
return;
|
|
241
115
|
}
|
|
242
|
-
}
|
|
243
116
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
} else if (
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return '-> ' + jump;
|
|
117
|
+
if (config.toJson) {
|
|
118
|
+
console.log(JSON.stringify(states, null, 4), done);
|
|
119
|
+
interactive = false;
|
|
120
|
+
} else if (config.toHtml) {
|
|
121
|
+
makeHtml(states, config.toHtml, {
|
|
122
|
+
title: config.htmlTitle,
|
|
123
|
+
color: config.htmlColor,
|
|
124
|
+
backgroundColor: config.htmlBackgroundColor,
|
|
125
|
+
});
|
|
126
|
+
interactive = false;
|
|
255
127
|
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function no() {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
128
|
|
|
262
|
-
|
|
263
|
-
read(stream, function onRead(err, content) {
|
|
264
|
-
if (err != null) {
|
|
265
|
-
return callback(err);
|
|
266
|
-
}
|
|
267
|
-
callback(null, {stream: stream, content: content});
|
|
268
|
-
});
|
|
269
|
-
}
|
|
129
|
+
let randomer = xorshift;
|
|
270
130
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
131
|
+
if (config.transcript || config.seed) {
|
|
132
|
+
// I rolled 4d64k this morning.
|
|
133
|
+
randomer = new xorshift.constructor([
|
|
134
|
+
37615 ^ config.seed,
|
|
135
|
+
54552 ^ config.seed,
|
|
136
|
+
59156 ^ config.seed,
|
|
137
|
+
24695 ^ config.seed,
|
|
138
|
+
]);
|
|
279
139
|
}
|
|
280
|
-
|
|
140
|
+
|
|
141
|
+
if (config.expected) {
|
|
142
|
+
read(config.expected, (err, typescript) => {
|
|
281
143
|
if (err) {
|
|
282
|
-
|
|
283
|
-
|
|
144
|
+
done(err);
|
|
145
|
+
return;
|
|
284
146
|
}
|
|
285
|
-
callback(null, string);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function serial(array, eachback, callback) {
|
|
290
|
-
var values = [];
|
|
291
|
-
next(0);
|
|
292
147
|
|
|
293
|
-
|
|
294
|
-
if (
|
|
295
|
-
|
|
148
|
+
const result = verify(kniscripts[0].content, typescript);
|
|
149
|
+
if (!result.pass) {
|
|
150
|
+
console.log(result.actual);
|
|
151
|
+
done(new Error('verification failed'));
|
|
152
|
+
return;
|
|
296
153
|
}
|
|
154
|
+
});
|
|
155
|
+
done(null);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
297
158
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
159
|
+
if (interactive) {
|
|
160
|
+
const readline = new Readline(config.transcript);
|
|
161
|
+
const render = new Console(out);
|
|
162
|
+
const engine = new Engine({
|
|
163
|
+
story: states,
|
|
164
|
+
start: config.start,
|
|
165
|
+
render: render,
|
|
166
|
+
dialog: readline,
|
|
167
|
+
randomer: randomer,
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
if (config.debugRuntime) {
|
|
171
|
+
engine.debug = true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (config.waypoint) {
|
|
175
|
+
read(config.waypoint, (err, waypoint) => {
|
|
176
|
+
if (err) {
|
|
177
|
+
done(err);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
waypoint = JSON.parse(waypoint);
|
|
181
|
+
engine.continue(waypoint);
|
|
182
|
+
});
|
|
183
|
+
} else {
|
|
184
|
+
engine.continue();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
done(null);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const describeStory = (states, out, done) => {
|
|
193
|
+
const keys = Object.keys(states);
|
|
194
|
+
const cells = [['L:C', 'AT', 'DO', 'S', 'USING', 'S', 'GO']];
|
|
195
|
+
for (let i = 0; i < keys.length; i++) {
|
|
196
|
+
const key = keys[i];
|
|
197
|
+
const node = states[key];
|
|
198
|
+
let next;
|
|
199
|
+
if (i === keys.length - 1) {
|
|
200
|
+
next = null;
|
|
201
|
+
} else {
|
|
202
|
+
next = keys[i + 1];
|
|
203
|
+
}
|
|
204
|
+
cells.push([
|
|
205
|
+
stripe(i, node.position),
|
|
206
|
+
stripe(i, key),
|
|
207
|
+
stripe(i, node.mode || node.type),
|
|
208
|
+
stripe(i, node.lift ? '-' : ' '),
|
|
209
|
+
stripe(i, describe(node)),
|
|
210
|
+
stripe(i, node.drop ? '-' : ' '),
|
|
211
|
+
stripe(i, describeNext(node.next, next)),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
out.write(
|
|
215
|
+
tableDefault(cells, {
|
|
216
|
+
border: getBorderCharacters('void'),
|
|
217
|
+
columnDefault: {
|
|
218
|
+
paddingLeft: 0,
|
|
219
|
+
paddingRight: 2,
|
|
220
|
+
},
|
|
221
|
+
columns: {
|
|
222
|
+
4: {
|
|
223
|
+
width: 40,
|
|
224
|
+
wrapWord: true,
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
drawHorizontalLine: no,
|
|
228
|
+
}),
|
|
229
|
+
done
|
|
230
|
+
);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const stripe = (index, text) => {
|
|
234
|
+
if (index % 2 === 1) {
|
|
235
|
+
return text;
|
|
236
|
+
} else {
|
|
237
|
+
return `\x1b[90m${text}\x1b[0m`;
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const describeNext = (jump, next) => {
|
|
242
|
+
if (jump === undefined) {
|
|
243
|
+
return '';
|
|
244
|
+
} else if (jump === next) {
|
|
245
|
+
return '';
|
|
246
|
+
} else if (jump == 'RET') {
|
|
247
|
+
return '<-';
|
|
248
|
+
} else if (jump == 'ESC') {
|
|
249
|
+
return '<<';
|
|
250
|
+
} else {
|
|
251
|
+
return `-> ${jump}`;
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
const no = () => {
|
|
256
|
+
return false;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const readAndKeep = (stream, callback) => {
|
|
260
|
+
read(stream, (err, content) => {
|
|
261
|
+
if (err != null) {
|
|
262
|
+
return callback(err);
|
|
263
|
+
}
|
|
264
|
+
callback(null, {stream: stream, content: content});
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const read = (stream, callback) => {
|
|
269
|
+
stream.setEncoding('utf8');
|
|
270
|
+
let string = '';
|
|
271
|
+
const onData = chunk => {
|
|
272
|
+
string += chunk;
|
|
273
|
+
};
|
|
274
|
+
const onEnd = err => {
|
|
275
|
+
if (err) {
|
|
276
|
+
callback(err);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
callback(null, string);
|
|
280
|
+
};
|
|
281
|
+
stream.on('data', onData);
|
|
282
|
+
stream.on('end', onEnd);
|
|
283
|
+
stream.on('error', onEnd);
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
const serial = (array, eachback, callback) => {
|
|
287
|
+
const values = [];
|
|
288
|
+
const next = i => {
|
|
289
|
+
if (i >= array.length) {
|
|
290
|
+
return callback(null, values);
|
|
307
291
|
}
|
|
308
|
-
}
|
|
309
292
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
293
|
+
eachback(array[i], (err, value) => {
|
|
294
|
+
if (err != null) {
|
|
295
|
+
return callback(err, null);
|
|
296
|
+
}
|
|
297
|
+
values.push(value);
|
|
298
|
+
next(i + 1);
|
|
299
|
+
});
|
|
300
|
+
};
|
|
301
|
+
next(0);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const dump = (errors, writer) => {
|
|
305
|
+
for (let i = 0; i < errors.length; i++) {
|
|
306
|
+
writer.write(`${errors[i]}\n`);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
311
|
+
run(null, process.stdout, err => {
|
|
312
|
+
if (err) {
|
|
313
|
+
console.error(typeof err === 'object' && err.message ? err.message : err);
|
|
314
|
+
if (typeof err.story === 'object' && err.story) {
|
|
315
|
+
const story = err.story;
|
|
316
|
+
dump(story.errors, process.stderr);
|
|
317
|
+
}
|
|
318
|
+
process.exit(-1);
|
|
313
319
|
}
|
|
320
|
+
});
|
|
314
321
|
}
|
|
315
322
|
|
|
316
|
-
|
|
323
|
+
export default run;
|