architecture-viewer 0.0.1-security → 4.4.5
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.
Potentially problematic release.
This version of architecture-viewer might be problematic. Click here for more details.
- package/2/package.json +10 -0
- package/2/postinstall.js +33 -0
- package/New Folder/architecture-viewer/.babelrc +9 -0
- package/New Folder/architecture-viewer/.whitesource +8 -0
- package/New Folder/architecture-viewer/CODEOWNERS +2 -0
- package/New Folder/architecture-viewer/LICENSE.txt +201 -0
- package/New Folder/architecture-viewer/README.md +238 -0
- package/New Folder/architecture-viewer/licenses.csv +40 -0
- package/New Folder/architecture-viewer/package-lock.json +16126 -0
- package/New Folder/architecture-viewer/package.json +60 -0
- package/New Folder/architecture-viewer/preact.config.js +62 -0
- package/New Folder/architecture-viewer/readme_resources/screenrecord_arch_diagram.gif +0 -0
- package/New Folder/architecture-viewer/sample_json_data/large_web.json +289 -0
- package/New Folder/architecture-viewer/sample_json_data/no_steps.json +185 -0
- package/New Folder/architecture-viewer/sample_json_data/readme_example.json +55 -0
- package/New Folder/architecture-viewer/sample_json_data/section_example.json +323 -0
- package/New Folder/architecture-viewer/sample_json_data/simple_structure.json +131 -0
- package/New Folder/architecture-viewer/sample_json_data/zones_example.json +445 -0
- package/New Folder/architecture-viewer/sample_plantuml_data/example.adoc +65 -0
- package/New Folder/architecture-viewer/sample_plantuml_data/example.png +0 -0
- package/New Folder/architecture-viewer/sample_plantuml_data/example.svg +1 -0
- package/New Folder/architecture-viewer/src/assets/data.json +445 -0
- package/New Folder/architecture-viewer/src/assets/favicon.ico +0 -0
- package/New Folder/architecture-viewer/src/assets/grid_data.json +1126 -0
- package/New Folder/architecture-viewer/src/assets/icons/android-chrome-192x192.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/android-chrome-512x512.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/apple-touch-icon.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/favicon-16x16.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/favicon-32x32.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/info.png +0 -0
- package/New Folder/architecture-viewer/src/assets/icons/mstile-150x150.png +0 -0
- package/New Folder/architecture-viewer/src/assets/test_data.json +32 -0
- package/New Folder/architecture-viewer/src/components/app.js +231 -0
- package/New Folder/architecture-viewer/src/components/controls.js +195 -0
- package/New Folder/architecture-viewer/src/components/diagram.js +362 -0
- package/New Folder/architecture-viewer/src/components/diagramArea.js +68 -0
- package/New Folder/architecture-viewer/src/components/info.js +37 -0
- package/New Folder/architecture-viewer/src/components/infoArea.js +75 -0
- package/New Folder/architecture-viewer/src/components/key.js +42 -0
- package/New Folder/architecture-viewer/src/components/tableOfContents.js +112 -0
- package/New Folder/architecture-viewer/src/components/tocStep.js +100 -0
- package/New Folder/architecture-viewer/src/components/zoneLegend.js +55 -0
- package/New Folder/architecture-viewer/src/index.js +20 -0
- package/New Folder/architecture-viewer/src/manifest.json +19 -0
- package/New Folder/architecture-viewer/src/routes/home/index.js +29 -0
- package/New Folder/architecture-viewer/src/routes/home/style.less +23 -0
- package/New Folder/architecture-viewer/src/routes/profile/index.js +63 -0
- package/New Folder/architecture-viewer/src/routes/profile/style.less +23 -0
- package/New Folder/architecture-viewer/src/style/helpers.less +40 -0
- package/New Folder/architecture-viewer/src/style/index.css +224 -0
- package/New Folder/architecture-viewer/src/style/jquery.qtip.less +623 -0
- package/New Folder/architecture-viewer/src/sw.js +4 -0
- package/New Folder/architecture-viewer/src/template.html +15 -0
- package/New Folder/architecture-viewer/src/utils/dataValidator.js +333 -0
- package/New Folder/architecture-viewer/src/utils/parser.js +623 -0
- package/New Folder/architecture-viewer/src/utils/stepUtils.js +30 -0
- package/New Folder/architecture-viewer/tests/__mocks__/browserMocks.js +21 -0
- package/New Folder/architecture-viewer/tests/__mocks__/fileMocks.js +3 -0
- package/New Folder/architecture-viewer/tests/__mocks__/setupTests.js +6 -0
- package/New Folder/architecture-viewer/tests/parser.test.js +799 -0
- package/New Folder/architecture-viewer/tests/testfiles/aliased_participants.adoc +7 -0
- package/New Folder/architecture-viewer/tests/testfiles/bigspace.json +1 -0
- package/New Folder/architecture-viewer/tests/testfiles/dividers.adoc +18 -0
- package/New Folder/architecture-viewer/tests/testfiles/doubled_names.adoc +10 -0
- package/New Folder/architecture-viewer/tests/testfiles/empty.adoc +2 -0
- package/New Folder/architecture-viewer/tests/testfiles/meta.adoc +19 -0
- package/New Folder/architecture-viewer/tests/testfiles/notes_multiline.adoc +17 -0
- package/New Folder/architecture-viewer/tests/testfiles/notes_singleline.adoc +16 -0
- package/New Folder/architecture-viewer/tests/testfiles/parsefile.adoc +6 -0
- package/New Folder/architecture-viewer/tests/testfiles/participant_decl.adoc +6 -0
- package/New Folder/architecture-viewer/tests/testfiles/participant_info.adoc +7 -0
- package/New Folder/architecture-viewer/tests/testfiles/readme.adoc +7 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_aliased.adoc +9 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_group.adoc +16 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_group.json +1 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_group_mixed.adoc +16 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_group_mixed.json +1 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_loop.adoc +16 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_loop.json +1 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_mixed.adoc +9 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_steptest.adoc +17 -0
- package/New Folder/architecture-viewer/tests/testfiles/steps_unaliased.adoc +9 -0
- package/New Folder/architecture-viewer/tests/testfiles/supernodes.adoc +10 -0
- package/New Folder/architecture-viewer/tests/testfiles/unaliased_participants.adoc +6 -0
- package/New Folder/architecture-viewer/tests/testfiles/undeclaredparticipant.adoc +23 -0
- package/New Folder/architecture-viewer/tests/testfiles/xsstest.adoc +15 -0
- package/New Folder/architecture-viewer/tests/testfiles/zoned_participants.adoc +5 -0
- package/New Folder/architecture-viewer/tests/validator.test.js +63 -0
- package/New Folder/d_i.txt +1 -0
- package/New Folder/dependency_confution_npm.sh +70 -0
- package/New Folder/licenses.csv +40 -0
- package/New Folder/npm_sub.txt +0 -0
- package/New Folder/package-lock.json +23 -0
- package/New Folder/package.json.save +12 -0
- package/index.js +39 -0
- package/package.json +12 -3
- package/README.md +0 -5
@@ -0,0 +1,623 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2017 Capital One Services, LLC
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
// ===== Miscellaneous Utilities =====
|
18
|
+
|
19
|
+
const peek = (arr) => {
|
20
|
+
return arr[arr.length - 1];
|
21
|
+
}
|
22
|
+
|
23
|
+
const empty = (arr) => {
|
24
|
+
return arr.length === 0;
|
25
|
+
}
|
26
|
+
|
27
|
+
const hexToRgb = (hex) => {
|
28
|
+
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
29
|
+
return result ? [
|
30
|
+
parseInt(result[1], 16),
|
31
|
+
parseInt(result[2], 16),
|
32
|
+
parseInt(result[3], 16)
|
33
|
+
] : [0, 0, 0];
|
34
|
+
}
|
35
|
+
|
36
|
+
const componentToHex = (c) => {
|
37
|
+
var hex = c.toString(16);
|
38
|
+
return hex.length == 1 ? "0" + hex : hex;
|
39
|
+
}
|
40
|
+
|
41
|
+
const rgbToHex = (r, g, b) => {
|
42
|
+
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
|
43
|
+
}
|
44
|
+
|
45
|
+
const shadeColor = (color, percent) => {
|
46
|
+
var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
|
47
|
+
return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
|
48
|
+
}
|
49
|
+
|
50
|
+
const convertColor = (c) => {
|
51
|
+
if (c.length == 7) return c;
|
52
|
+
return '#' + c[1] + c[1] + c[2] + c[2] + c[3] + c[3];
|
53
|
+
}
|
54
|
+
|
55
|
+
const tint = (c) => shadeColor(convertColor(c), .15);
|
56
|
+
|
57
|
+
// ===== REGEXES/STRINGS =====
|
58
|
+
|
59
|
+
//match the beginning of a plantuml diagram
|
60
|
+
const START_FLAG = "@startuml";
|
61
|
+
|
62
|
+
//match the end of a plantuml diagram
|
63
|
+
const END_FLAG = "@enduml";
|
64
|
+
|
65
|
+
//match the title of a plantUML diagram
|
66
|
+
const TITLE = /^title (\"?.+\"?)$/;
|
67
|
+
|
68
|
+
//match a line when a participant is declared
|
69
|
+
const PARTICIPANT = /^(participant|actor) ((\"?.+\"?) as (\w+)|\"?\w+\"?)\s*(<< \((.,\s*#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}))\) (.+) >>)?$/;
|
70
|
+
|
71
|
+
const PARTICIPANT_INFO = /^\s*note over (\w+)\s*$/;
|
72
|
+
|
73
|
+
//match a line that looks roughly like this: "A -> B: description"
|
74
|
+
const STEP_FORWARD = /^\s*(\w+)\s*(->|-\\|-\/|->>|-\\\\|-\/\/|-->|--\\\\|--\/\/|-->>)\s*(\w+)\s*:\s*(.+)$/;
|
75
|
+
|
76
|
+
//match a line that looks roughly like this: "A <- B: description"
|
77
|
+
const STEP_BACKWARD = /^\s*(\w+)\s*(<-|\/-|\\-|<<-|\/\/\/\/-|\\\\-|<--|\/\/--|\\\\--|<<--)\s*(\w+)\s*:\s*(.+)$/;
|
78
|
+
|
79
|
+
//match a note on either side of a step. It looks like this: "note [left|right]: description"
|
80
|
+
const SINGLE_LINE_NOTE = /^\s*note (left|right|over (\w+)|left of (\w+)|right of (\w+)):\s*(.*)$/;
|
81
|
+
|
82
|
+
//matches the start of a note, looks like this: "note [left|right]"
|
83
|
+
const MULTI_LINE_NOTE_START = /^\s*note (left|right)$/;
|
84
|
+
|
85
|
+
//matches the content of a line of a note
|
86
|
+
const NOTE_LINE = /^(\s*)(.*)$/;
|
87
|
+
|
88
|
+
//matches the end of a note
|
89
|
+
const MULTI_LINE_NOTE_END = /^\s*end note$/;
|
90
|
+
|
91
|
+
// matches the start of a "loop" type of group
|
92
|
+
const LOOP_START = /^\s*loop (.+)$/;
|
93
|
+
|
94
|
+
// matches the start of a "group" type of group
|
95
|
+
const GROUP_START = /^\s*group (.+)$/;
|
96
|
+
|
97
|
+
// matches the end of both a loop AND a group
|
98
|
+
const GROUPING_END = /^\s*end( loop)?$/;
|
99
|
+
|
100
|
+
//matches the declaration of a divider
|
101
|
+
const DIVIDER = /^\s*==\s*(.+)\s*==$/;
|
102
|
+
|
103
|
+
//matches an alt (TODO: flesh this out into real support or parse it out)
|
104
|
+
const ALT = /^\s*alt.*$/;
|
105
|
+
|
106
|
+
|
107
|
+
// ===== FLAGS/CONSTANTS =====
|
108
|
+
const debug = false;
|
109
|
+
|
110
|
+
let processingUML = false;
|
111
|
+
|
112
|
+
//edge/step info
|
113
|
+
let edgeIndexCounter = 0;
|
114
|
+
let stepIndexCounter = 0;
|
115
|
+
|
116
|
+
//group/divider info
|
117
|
+
const NO_GROUPS = 0;
|
118
|
+
const GROUPS = 1;
|
119
|
+
const SECTIONS = 2;
|
120
|
+
|
121
|
+
let groupType = NO_GROUPS;
|
122
|
+
let groupStepStack = [];
|
123
|
+
let groupIndexCounter = 0;
|
124
|
+
|
125
|
+
let parsingDivider = false;
|
126
|
+
|
127
|
+
let processingParticipantInfo = false;
|
128
|
+
let participantProcessed = null;
|
129
|
+
|
130
|
+
//note info
|
131
|
+
let processingNote = false;
|
132
|
+
let noteContent = [];
|
133
|
+
let previousNoteStep = null;
|
134
|
+
|
135
|
+
//node/zone tracking
|
136
|
+
const nodeMap = {};
|
137
|
+
const zoneMap = {
|
138
|
+
main: "#FBDCD6"
|
139
|
+
};
|
140
|
+
|
141
|
+
//TODO: flesh this out into real support or parse it out
|
142
|
+
let altCount = 0;
|
143
|
+
|
144
|
+
|
145
|
+
// ===== HELPER FUNCTIONS =====
|
146
|
+
const setProcessingFlag = (line) => {
|
147
|
+
if (line === START_FLAG) {
|
148
|
+
processingUML = true;
|
149
|
+
} else if (line === END_FLAG) {
|
150
|
+
processingUML = false;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
const detectTitle = (data, line) => {
|
155
|
+
if (!TITLE.test(line)) return;
|
156
|
+
|
157
|
+
const titleInfo = TITLE
|
158
|
+
.exec(line)[1]
|
159
|
+
.replace(/^"(.+)"$/, '$1');
|
160
|
+
|
161
|
+
data.title = titleInfo;
|
162
|
+
}
|
163
|
+
|
164
|
+
const detectParticipant = (data, line) => {
|
165
|
+
if (!PARTICIPANT.test(line)) return;
|
166
|
+
|
167
|
+
const participantInfo = PARTICIPANT
|
168
|
+
.exec(line)
|
169
|
+
.slice(2);
|
170
|
+
|
171
|
+
// no alias vs alias
|
172
|
+
let officialName;
|
173
|
+
let shortName;
|
174
|
+
if (participantInfo[1] === undefined) {
|
175
|
+
const name = participantInfo[0]
|
176
|
+
.replace(/"/g, "")
|
177
|
+
.replace(/\\n/g, " ");
|
178
|
+
nodeMap[name] = name;
|
179
|
+
officialName = name;
|
180
|
+
shortName = name;
|
181
|
+
} else {
|
182
|
+
shortName = participantInfo[2];
|
183
|
+
const longName = participantInfo[1]
|
184
|
+
.replace(/"/g, "")
|
185
|
+
.replace(/\\n/g, " ");
|
186
|
+
|
187
|
+
nodeMap[shortName] = longName;
|
188
|
+
// nodeMap[longName] = shortName;
|
189
|
+
officialName = longName;
|
190
|
+
}
|
191
|
+
|
192
|
+
let zone;
|
193
|
+
let zoneName = null;
|
194
|
+
if (participantInfo[6] === undefined) {
|
195
|
+
zone = zoneMap["main"];
|
196
|
+
} else {
|
197
|
+
zoneName = participantInfo[6];
|
198
|
+
zoneMap[zoneName] = `#${participantInfo[5]}`;
|
199
|
+
zone = zoneMap[zoneName];
|
200
|
+
}
|
201
|
+
|
202
|
+
let partial_data = {
|
203
|
+
id: shortName,
|
204
|
+
fname: officialName,
|
205
|
+
zone: zone,
|
206
|
+
}
|
207
|
+
|
208
|
+
if (zoneName != null) {
|
209
|
+
partial_data.parent = zoneName;
|
210
|
+
}
|
211
|
+
|
212
|
+
//insert node into data
|
213
|
+
//TODO: support zones in the future
|
214
|
+
data.graphData.nodes.push({
|
215
|
+
data: partial_data
|
216
|
+
})
|
217
|
+
|
218
|
+
}
|
219
|
+
|
220
|
+
const detectParticipantInfo = (data, line) => {
|
221
|
+
if (!processingParticipantInfo) {
|
222
|
+
if (PARTICIPANT_INFO.test(line)) {
|
223
|
+
participantProcessed = PARTICIPANT_INFO.exec(line)[1];
|
224
|
+
processingParticipantInfo = true;
|
225
|
+
}
|
226
|
+
} else {
|
227
|
+
if (MULTI_LINE_NOTE_END.test(line)) {
|
228
|
+
const participant = data.graphData.nodes.filter(n => {
|
229
|
+
return n.data.id == participantProcessed;
|
230
|
+
})[0];
|
231
|
+
participant.data.info = noteContent.join(" ");
|
232
|
+
participantProcessed = null;
|
233
|
+
noteContent = [];
|
234
|
+
processingParticipantInfo = false;
|
235
|
+
} else {
|
236
|
+
if (!NOTE_LINE.test(line)) return;
|
237
|
+
|
238
|
+
const parsed_line = NOTE_LINE.exec(line);
|
239
|
+
noteContent.push(parsed_line[2]);
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
|
244
|
+
const detectStep = (data, line) => {
|
245
|
+
if (!STEP_FORWARD.test(line) && !STEP_BACKWARD.test(line)) return;
|
246
|
+
|
247
|
+
let stepInfo;
|
248
|
+
let source;
|
249
|
+
let target;
|
250
|
+
let description;
|
251
|
+
|
252
|
+
if (STEP_FORWARD.test(line)) {
|
253
|
+
stepInfo = STEP_FORWARD.exec(line);
|
254
|
+
source = stepInfo[1];
|
255
|
+
if (nodeMap[source] == undefined) {
|
256
|
+
nodeMap[stepInfo[1]] = stepInfo[1];
|
257
|
+
source = stepInfo[1];
|
258
|
+
data.graphData.nodes.push({
|
259
|
+
data: {
|
260
|
+
id: stepInfo[1],
|
261
|
+
fname: stepInfo[1],
|
262
|
+
zone: zoneMap["main"]
|
263
|
+
}
|
264
|
+
})
|
265
|
+
}
|
266
|
+
|
267
|
+
target = stepInfo[3];
|
268
|
+
if (nodeMap[target] == undefined) {
|
269
|
+
nodeMap[stepInfo[3]] = stepInfo[3];
|
270
|
+
target = stepInfo[3];
|
271
|
+
data.graphData.nodes.push({
|
272
|
+
data: {
|
273
|
+
id: stepInfo[3],
|
274
|
+
fname: stepInfo[3],
|
275
|
+
zone: zoneMap["main"]
|
276
|
+
}
|
277
|
+
})
|
278
|
+
}
|
279
|
+
|
280
|
+
description = stepInfo[4];
|
281
|
+
|
282
|
+
} else {
|
283
|
+
stepInfo = STEP_BACKWARD.exec(line);
|
284
|
+
source = stepInfo[3];
|
285
|
+
if (nodeMap[source] == undefined) {
|
286
|
+
nodeMap[stepInfo[3]] = stepInfo[3];
|
287
|
+
source = stepInfo[3];
|
288
|
+
data.graphData.nodes.push({
|
289
|
+
data: {
|
290
|
+
id: stepInfo[3],
|
291
|
+
fname: stepInfo[3],
|
292
|
+
zone: zoneMap["main"]
|
293
|
+
}
|
294
|
+
})
|
295
|
+
}
|
296
|
+
|
297
|
+
target = stepInfo[1];
|
298
|
+
if (nodeMap[target] == undefined) {
|
299
|
+
nodeMap[stepInfo[1]] = stepInfo[1];
|
300
|
+
target = stepInfo[1];
|
301
|
+
data.graphData.nodes.push({
|
302
|
+
data: {
|
303
|
+
id: stepInfo[1],
|
304
|
+
fname: stepInfo[1],
|
305
|
+
zone: zoneMap["main"]
|
306
|
+
}
|
307
|
+
})
|
308
|
+
}
|
309
|
+
|
310
|
+
description = stepInfo[4];
|
311
|
+
}
|
312
|
+
|
313
|
+
const edgeExists = data.graphData.edges.some(edge => {
|
314
|
+
const data = edge.data;
|
315
|
+
const src = data.source;
|
316
|
+
const tar = data.target;
|
317
|
+
|
318
|
+
return (src == source && tar == target) || (src == target && tar == source);
|
319
|
+
});
|
320
|
+
|
321
|
+
if (!edgeExists) {
|
322
|
+
data.graphData.edges.push({
|
323
|
+
data: {
|
324
|
+
id: "e" + edgeIndexCounter,
|
325
|
+
source: source,
|
326
|
+
target: target
|
327
|
+
}
|
328
|
+
});
|
329
|
+
edgeIndexCounter += 1;
|
330
|
+
}
|
331
|
+
|
332
|
+
const step = {
|
333
|
+
id: "" + stepIndexCounter,
|
334
|
+
type: "single",
|
335
|
+
nodes: [source, target],
|
336
|
+
steps: [],
|
337
|
+
description: description,
|
338
|
+
note: ""
|
339
|
+
};
|
340
|
+
|
341
|
+
let prevStep;
|
342
|
+
|
343
|
+
if (empty(groupStepStack)) {
|
344
|
+
data.stepData.push(step);
|
345
|
+
prevStep = peek(data.stepData);
|
346
|
+
} else {
|
347
|
+
const group = peek(groupStepStack);
|
348
|
+
group.steps.push(step);
|
349
|
+
prevStep = peek(group.steps);
|
350
|
+
}
|
351
|
+
|
352
|
+
previousNoteStep = prevStep;
|
353
|
+
|
354
|
+
stepIndexCounter += 1;
|
355
|
+
|
356
|
+
}
|
357
|
+
|
358
|
+
const detectSingleLineNote = (data, line) => {
|
359
|
+
if (!SINGLE_LINE_NOTE.test(line)) return;
|
360
|
+
|
361
|
+
const regex_result = SINGLE_LINE_NOTE.exec(line);
|
362
|
+
|
363
|
+
// depending on the regex, could be the second or 5th group
|
364
|
+
const note = regex_result[2] || regex_result[5];
|
365
|
+
|
366
|
+
// the note refers to a node
|
367
|
+
if (regex_result[2] != undefined || regex_result[4] != undefined) {
|
368
|
+
let node_id = regex_result[2] || regex_result[4];
|
369
|
+
let noteNode = null;
|
370
|
+
for (let i = 0; i < data.graphData.nodes.length; i++) {
|
371
|
+
let node = data.graphData.nodes[i];
|
372
|
+
if (node.data.id === node_id) {
|
373
|
+
noteNode = node;
|
374
|
+
}
|
375
|
+
}
|
376
|
+
noteNode.data.info = note;
|
377
|
+
}
|
378
|
+
// the note refers to a step
|
379
|
+
else {
|
380
|
+
previousNoteStep.note = note;
|
381
|
+
previousNoteStep = null;
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
const detectMultiLineNote = (data, line) => {
|
386
|
+
if (!processingNote) {
|
387
|
+
if (MULTI_LINE_NOTE_START.test(line)) {
|
388
|
+
processingNote = true;
|
389
|
+
}
|
390
|
+
} else {
|
391
|
+
if (MULTI_LINE_NOTE_END.test(line)) {
|
392
|
+
|
393
|
+
previousNoteStep.note = noteContent.join("\n");
|
394
|
+
previousNoteStep = null;
|
395
|
+
noteContent = [];
|
396
|
+
processingNote = false;
|
397
|
+
return;
|
398
|
+
} else {
|
399
|
+
if (!NOTE_LINE.test(line)) return;
|
400
|
+
|
401
|
+
const parsed_line = NOTE_LINE.exec(line);
|
402
|
+
noteContent.push(parsed_line[2]);
|
403
|
+
}
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
const detectLoop = (data, line) => {
|
408
|
+
if (!LOOP_START.test(line)) return;
|
409
|
+
|
410
|
+
const step = {
|
411
|
+
id: "g" + groupIndexCounter,
|
412
|
+
type: "group",
|
413
|
+
groupName: "loop",
|
414
|
+
nodes: [],
|
415
|
+
steps: [],
|
416
|
+
description: "",
|
417
|
+
note: ""
|
418
|
+
};
|
419
|
+
|
420
|
+
const loopDescription = LOOP_START.exec(line)[1];
|
421
|
+
step.description = loopDescription;
|
422
|
+
|
423
|
+
groupStepStack.push(step);
|
424
|
+
groupIndexCounter++;
|
425
|
+
}
|
426
|
+
|
427
|
+
const detectGroup = (data, line) => {
|
428
|
+
if (!GROUP_START.test(line)) return;
|
429
|
+
|
430
|
+
const step = {
|
431
|
+
id: "g" + groupIndexCounter,
|
432
|
+
type: "group",
|
433
|
+
groupName: "group",
|
434
|
+
nodes: [],
|
435
|
+
steps: [],
|
436
|
+
description: "",
|
437
|
+
note: ""
|
438
|
+
};
|
439
|
+
|
440
|
+
const groupDescription = GROUP_START.exec(line)[1];
|
441
|
+
step.description = groupDescription;
|
442
|
+
|
443
|
+
groupStepStack.push(step);
|
444
|
+
groupIndexCounter++;
|
445
|
+
}
|
446
|
+
|
447
|
+
const detectGroupEnd = (data, line) => {
|
448
|
+
if (!GROUPING_END.test(line)) return;
|
449
|
+
|
450
|
+
/*
|
451
|
+
introducing support for the "alt" syntax in PlantUML (basically if statements)
|
452
|
+
TODO: flesh this out into real support or parse it out
|
453
|
+
quick support for ALT
|
454
|
+
*/
|
455
|
+
if (altCount > 0) {
|
456
|
+
altCount--;
|
457
|
+
return;
|
458
|
+
}
|
459
|
+
|
460
|
+
const finishedGroup = groupStepStack.pop();
|
461
|
+
previousNoteStep = finishedGroup;
|
462
|
+
let parent;
|
463
|
+
if (empty(groupStepStack)) {
|
464
|
+
parent = data.stepData;
|
465
|
+
parent.push(finishedGroup);
|
466
|
+
} else {
|
467
|
+
parent = peek(groupStepStack);
|
468
|
+
parent.steps.push(finishedGroup);
|
469
|
+
}
|
470
|
+
|
471
|
+
}
|
472
|
+
|
473
|
+
const detectDivider = (data, line) => {
|
474
|
+
if (!DIVIDER.test(line)) return;
|
475
|
+
|
476
|
+
if (parsingDivider) {
|
477
|
+
const finishedGroup = groupStepStack.pop();
|
478
|
+
previousNoteStep = finishedGroup;
|
479
|
+
let parent;
|
480
|
+
if (empty(groupStepStack)) {
|
481
|
+
parent = data.stepData;
|
482
|
+
parent.push(finishedGroup);
|
483
|
+
} else {
|
484
|
+
parent = peek(groupStepStack);
|
485
|
+
parent.steps.push(finishedGroup);
|
486
|
+
}
|
487
|
+
|
488
|
+
}
|
489
|
+
const step = {
|
490
|
+
id: "g" + groupIndexCounter,
|
491
|
+
type: "group",
|
492
|
+
groupName: "group",
|
493
|
+
nodes: [],
|
494
|
+
steps: [],
|
495
|
+
description: "",
|
496
|
+
note: ""
|
497
|
+
};
|
498
|
+
|
499
|
+
const groupDescription = DIVIDER.exec(line)[1].trim();
|
500
|
+
step.description = groupDescription;
|
501
|
+
|
502
|
+
groupStepStack.push(step);
|
503
|
+
groupIndexCounter++;
|
504
|
+
parsingDivider = true;
|
505
|
+
|
506
|
+
}
|
507
|
+
|
508
|
+
/*
|
509
|
+
introducing support for the "alt" syntax in PlantUML (basically if statements)
|
510
|
+
TODO: flesh this out into real support or parse it out
|
511
|
+
quick support for ALT
|
512
|
+
*/
|
513
|
+
const detectAlt = (data, line) => {
|
514
|
+
if (!ALT.test(line)) return;
|
515
|
+
altCount++;
|
516
|
+
}
|
517
|
+
|
518
|
+
|
519
|
+
const parseContents = (contents) => {
|
520
|
+
//create a skeleton JSON
|
521
|
+
const result = {
|
522
|
+
title: "",
|
523
|
+
graphData: {
|
524
|
+
nodes: [],
|
525
|
+
edges: []
|
526
|
+
},
|
527
|
+
stepData: [],
|
528
|
+
zoneData: []
|
529
|
+
}
|
530
|
+
|
531
|
+
//loop through the file to populate JSON
|
532
|
+
for (let line of contents) {
|
533
|
+
setProcessingFlag(line);
|
534
|
+
if (processingUML) {
|
535
|
+
detectTitle(result, line);
|
536
|
+
detectParticipant(result, line);
|
537
|
+
detectParticipantInfo(result, line);
|
538
|
+
detectStep(result, line);
|
539
|
+
detectSingleLineNote(result, line);
|
540
|
+
detectMultiLineNote(result, line);
|
541
|
+
detectLoop(result, line);
|
542
|
+
detectGroup(result, line);
|
543
|
+
detectDivider(result, line);
|
544
|
+
detectAlt(result, line);
|
545
|
+
detectGroupEnd(result, line);
|
546
|
+
}
|
547
|
+
}
|
548
|
+
|
549
|
+
//finish off last divider
|
550
|
+
if (parsingDivider) {
|
551
|
+
const finishedGroup = groupStepStack.pop();
|
552
|
+
previousNoteStep = finishedGroup;
|
553
|
+
let parent;
|
554
|
+
if (empty(groupStepStack)) {
|
555
|
+
parent = result.stepData;
|
556
|
+
parent.push(finishedGroup);
|
557
|
+
} else {
|
558
|
+
parent = peek(groupStepStack);
|
559
|
+
parent.steps.push(finishedGroup);
|
560
|
+
}
|
561
|
+
}
|
562
|
+
|
563
|
+
//generate zone nodes
|
564
|
+
for (let z of Object.keys(zoneMap)) {
|
565
|
+
if (z != "main") {
|
566
|
+
let tintedZone = tint(zoneMap[z]);
|
567
|
+
result.graphData.nodes.push({
|
568
|
+
data: {
|
569
|
+
id: z,
|
570
|
+
zone: tintedZone
|
571
|
+
}
|
572
|
+
})
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
576
|
+
//TODO: cleanup so global scope is ok
|
577
|
+
|
578
|
+
//edge/step info
|
579
|
+
edgeIndexCounter = 0;
|
580
|
+
stepIndexCounter = 0;
|
581
|
+
|
582
|
+
groupType = NO_GROUPS;
|
583
|
+
groupStepStack = [];
|
584
|
+
groupIndexCounter = 0;
|
585
|
+
|
586
|
+
parsingDivider = false;
|
587
|
+
|
588
|
+
//note info
|
589
|
+
processingNote = false;
|
590
|
+
noteContent = [];
|
591
|
+
previousNoteStep = null;
|
592
|
+
|
593
|
+
//node/zone tracking
|
594
|
+
for (var n in nodeMap) {
|
595
|
+
delete nodeMap[n];
|
596
|
+
}
|
597
|
+
|
598
|
+
for (var z in zoneMap) {
|
599
|
+
delete zoneMap[z];
|
600
|
+
}
|
601
|
+
zoneMap.main = "#FBDCD6";
|
602
|
+
|
603
|
+
/*
|
604
|
+
introducing support for the "alt" syntax in PlantUML (basically if statements)
|
605
|
+
TODO: flesh this out into real support or parse it out
|
606
|
+
quick support for ALT
|
607
|
+
*/
|
608
|
+
altCount = 0;
|
609
|
+
|
610
|
+
return result;
|
611
|
+
}
|
612
|
+
|
613
|
+
module.exports = {
|
614
|
+
utils: {
|
615
|
+
detectParticipant
|
616
|
+
},
|
617
|
+
flags: {
|
618
|
+
processingUML,
|
619
|
+
nodeMap,
|
620
|
+
zoneMap
|
621
|
+
},
|
622
|
+
parseContents,
|
623
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2017 Capital One Services, LLC
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
const getCurrentStep = (stepStr, stepArray) => {
|
18
|
+
const reduceSteps = (foundStep, curStep) => {
|
19
|
+
if (curStep.type == "single") {
|
20
|
+
return curStep.id == stepStr ? curStep : foundStep;
|
21
|
+
} else if (curStep.type == "group") {
|
22
|
+
return curStep.steps.reduce(reduceSteps, foundStep);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
return stepArray.reduce(reduceSteps, null);
|
26
|
+
}
|
27
|
+
|
28
|
+
module.exports = {
|
29
|
+
getCurrentStep
|
30
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
// Mock Browser API's which are not supported by JSDOM, e.g. ServiceWorker, LocalStorage
|
2
|
+
/**
|
3
|
+
* An example how to mock localStorage is given below 👇
|
4
|
+
*/
|
5
|
+
|
6
|
+
/*
|
7
|
+
// Mocks localStorage
|
8
|
+
const localStorageMock = (function() {
|
9
|
+
let store = {};
|
10
|
+
|
11
|
+
return {
|
12
|
+
getItem: (key) => store[key] || null,
|
13
|
+
setItem: (key, value) => store[key] = value.toString(),
|
14
|
+
clear: () => store = {}
|
15
|
+
};
|
16
|
+
|
17
|
+
})();
|
18
|
+
|
19
|
+
Object.defineProperty(window, 'localStorage', {
|
20
|
+
value: localStorageMock
|
21
|
+
}); */
|