This repository was archived by the owner on Feb 7, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathraml-json-enhance-template.html
More file actions
312 lines (299 loc) · 10.8 KB
/
Copy pathraml-json-enhance-template.html
File metadata and controls
312 lines (299 loc) · 10.8 KB
1
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
<!--
@license
Copyright 2016 The Advanced REST client authors <arc@mulesoft.com>
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
-->
<link rel="import" href="../polymer/polymer.html">
<!--
The `<raml-json-enhance>` enhaces the JSON output from the RAML parser so it can
be used in the ARC elements (which expects enhanced data structure).
The work is asynchronous. After the `json` property is set/changed it will call the
worker automatically and report the result via the `raml-json-enhance-ready` event.
Polymer application can bind to the `result` property which will notify the change.
### Example
```
<raml-json-enhance json="{...}"></raml-json-enhance>
window.addEventListener('raml-json-enhance-ready', function(e) {
console.log(e.detail.json);
// equals to
console.log(e.target.result);
});
```
**Note** This element MUST be used to enhance parser JSON output in order to use
any RAML related ARC element. Enhancer creates common data structure and
expands RAML types. Element expects the JSON object to contain complete data
about method / endpoint / type / security scheme and so on. It will not look for
the data in the root of raml definition. Thanks to this, you can push just a part
of the JSON object to a specific element to make it work.
For example, the `<raml-docs-method-viewer>` viewer expects the `raml` propety to
be a method definition only (without of the rest of the RAML structure). If
enhanced with the library, the JSON object describing the method will contain
all required information to render the view.
The element contains a set of Polyfills so it will work in IE11+ browsers.
### Biuld process
This element uses web workers to expand JSON result (normalize it).
The element will attempty to load following scitps from the same location where
this script resides:
- polyfills.js
- browser/index.js
- raml2object.js
Build scripts should ensure that this resources are included in the final build.
## Affected properties
- `types`, `traits`, `resourceTypes`, `annotationTypes`, `securitySchemes` - Becomes an object instead of array, keys are object name (with library variable name if applicable)
- `responses`, `body`, `queryParameters`, `headers`, `properties`, `baseUriParameters`, `annotations`, `uriParameters` are recusively transformed into the arrays
- types/{object} - Expanded form for a RAML type and a canonical form with computed inheritance and pushed unions to the top level of the type structure. See documantaion for the [expansion library](https://github.com/raml-org/raml-parser-toolbelt/tree/master/tools/datatype-expansion).
- resource/parentUrl - a full URL of the parent resource
- resource/allUriParameters - list of all URI parameters that apply to this resource (computed from the root down to current resource)
- resource/securedBy - Replaces security schema name with schema's definition.
- method/allUriParameters - The same as for a resource but applied to a method that is direct child of the resource.
- method/absoluteUri - Full, absolute URL to the method containg URI parametes in their RAML's form, eg `/{fileId}`
- method/securedBy - The same as for the resource
- method/*/headers - Full list of all possible headers compured from traits, security schemes etc
- method/*/queryParameters - Full list of all possible queryParameters compured from traits, security schemes etc
- method/responses - Full list of all possible response compured from traits, security schemes etc
- type/properties/items - replaces type name with type definition
- */example(s) - always produces `examples` as an array of example contents
- */structuredExample - content is moved to the *.example array
## Developing this element
Unlike other web components this component has to be build. Make any
changes to the `raml-json-enhance-template.html`. After making a change call
`npm run build`. It will concatenate all required files
and insert generated web worker contentnt into the element's body.
The `raml-json-enhance.html` will be regenerated each time you call build
script.
@group RAML Elements
@element raml-json-enhance
@demo demo/index.html
-->
<dom-module id="raml-json-enhance">
<template>
<style>
:host {
display: none;
}
</style>
<script id="normalizer" type="javascript/worker">{{RAML2OBJ_CONTENT}}</script>
</template>
<script>
(function() {
/**
* Making the a private propery not available in element's API.
* Contains a list of currently running workers.
*
* @type {Array}
*/
var WORKERS = [];
/**
* @param {String} name Name of the worker.
* @return {Worker} A worker object for the name.
*/
function getWorker(name) {
for (var i = 0, len = WORKERS.length; i < len; i++) {
if (WORKERS[i].name === name) {
return WORKERS[i].ref;
}
}
}
Polymer({
is: 'raml-json-enhance',
properties: {
/**
* A JSON retuned by the `toJson()` function of the RAML JS parser's
* API object.
*/
json: {
type: Object,
observer: '_jsonChnaged'
},
// The result of enhancing the `json` object.
result: {
type: Object,
notify: true,
readOnly: true
},
// Flag set to true when currently JSON is being enhanced.
expanding: {
type: Boolean,
notify: true,
readOnly: true
},
/**
* If true it will instruct `raml2obj` library to measure execution
* time. It will be printed to the console after RAML is enhanced
*/
printMeasurements: Boolean
},
// Handler for the `json` property change.
_jsonChnaged: function(json) {
if (!json) {
return this._setResult(undefined);
}
this._noSupportedError();
if (json.specification) {
json = json.specification;
}
this._killWorkers();
this.enhance(json);
},
/**
* Sends an error when running from unsupported browser.
*/
_noSupportedError: function() {
var ie10 = /msie 10/i.test(navigator.userAgent);
if (!ie10) {
return;
}
this._setResult(undefined);
this.fire('error', {
message: 'This browser is not supported.'
});
throw new Error('This browser is not supported.');
},
/**
* Terminates currently running workers.
* Thisa is helpful when another process is requested and old process is
* still running. It terminates workers so messages from them won't be
* sent to the main thread and notified outside for old api call.
*
* It also clears data URL object created by URL.createObjectURL().
*
* This resets state to 0.
*/
_killWorkers: function() {
for (var i = WORKERS.length - 1; i >= 0; i--) {
this.__terminateWorker(WORKERS[i]);
WORKERS.splice(i, 1);
}
},
/**
* Terminates the worker if it exists and is running
*
* @param {Object} workerRef An object created by `__createWorker` function
*/
__terminateWorker: function(workerRef) {
workerRef.ref.terminate();
workerRef.ref.removeEventListener('message', workerRef.data);
workerRef.ref.removeEventListener('error', workerRef.error);
this.__clearDataUrl(workerRef.url);
},
/**
* Clears a data URL created by URL.createObjectURL().
*
* @param {String} url The URL to clean
*/
__clearDataUrl: function(url) {
if (url) {
window.URL.revokeObjectURL(url);
}
},
/**
* Creates a web workers before the work starts.
*/
_createWorkers: function() {
var norm = this.__createWorker('_normalize', this.$.normalizer.textContent);
WORKERS.push(norm);
},
/**
* Creates an instance of web worker from a text content.
*
* @param {String} property Name of the worker. `this` must contains
* functions for handling data and errors named `property` + `DataHandler`
* and `property` + `ErrorHandler`
* @param {String} body Body of the worker
*/
__createWorker: function(property, body) {
var blob = new Blob([body]);
var workerUrl = window.URL.createObjectURL(blob);
var worker = new Worker(workerUrl);
var dataHandler = this[property + 'DataHandler'].bind(this);
var errorHandler = this[property + 'ErrorHandler'].bind(this);
worker.addEventListener('message', dataHandler);
worker.addEventListener('error', errorHandler);
return {
name: property,
ref: worker,
url: workerUrl,
error: errorHandler,
data: dataHandler
};
},
/**
* Enhances the JavaScript object.
*
* @param {Object} json An object returned from RAML js parser after calling
* `toJSON`.
*/
enhance: function(json) {
this._setExpanding(true);
this._createWorkers();
var worker = getWorker('_normalize');
var message = {
payload: 'parse',
json: json,
takeMeasurements: this.printMeasurements
};
worker.postMessage(message);
},
/**
* Reports results to the called by dispatching the
* `raml-json-enhance-ready` event.
*
* @param {Object} result Expanded and normalized object.
*/
_reportResult: function(result) {
this._setResult(result);
this.fire('raml-json-enhance-ready', {
json: result
});
this._killWorkers();
},
/**
* Reports an error
*
* @param {String} errorMessage Error message to report.
*/
_reportError: function(errorMessage) {
var err = new Error(errorMessage);
this.fire('error', {
message: err.message
});
this._killWorkers();
throw err;
},
/**
* Handler for a message from the normalize worker.
* Depending on current state it calls next function in the chain.
*/
_normalizeDataHandler: function(e) {
this._setExpanding(false);
var data = e.data;
if (data.error) {
this._reportError(data.message);
return;
}
var json = data.result.json;
this._reportResult(json);
if (data.result.measurement) {
console.table(data.result.measurement);
}
},
/**
* Normalize worker error handler.
*/
_normalizeErrorHandler: function(e) {
var message = (e && e.message) ? 'Normalize worker: ' + e.message :
'Unknown normalize worker error.';
this._reportError(message);
}
});
})();
</script>
</dom-module>