@qooxdoo/framework 7.0.0-beta.2 → 7.0.0-beta.6

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.
Files changed (143) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/Manifest.json +2 -3
  3. package/README.md +7 -3
  4. package/bin/deploy/qx +0 -0
  5. package/lib/compiler/compile-info.json +44 -45
  6. package/lib/compiler/index.js +1971 -8371
  7. package/lib/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
  8. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css +1 -1
  9. package/lib/resource/qx/tool/cli/templates/skeleton/mobile/source/theme/custom/css/custom.css.map +1 -1
  10. package/lib/resource/qx/tool/cli/templates/template_vars.js +1 -1
  11. package/lib/resource/qx/tool/loadsass.js +6 -12
  12. package/lib/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
  13. package/lib/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
  14. package/lib/resource/qx/tool/schema/compile-1-0-0.json +3 -7
  15. package/package.json +25 -12
  16. package/source/class/qx/io/__init__.js +5 -3
  17. package/source/class/qx/io/exception/Cancel.js +34 -0
  18. package/source/class/qx/io/exception/Exception.js +38 -0
  19. package/source/class/qx/{tool/compiler/Version.js → io/exception/Protocol.js} +13 -7
  20. package/source/class/qx/io/exception/Transport.js +39 -0
  21. package/source/class/qx/io/exception/__init__.js +4 -0
  22. package/source/class/qx/io/graphql/Client.js +112 -0
  23. package/source/class/qx/io/graphql/__init__.js +9 -0
  24. package/source/class/qx/io/graphql/protocol/Message.js +65 -0
  25. package/source/class/qx/io/graphql/protocol/Request.js +95 -0
  26. package/source/class/qx/io/graphql/protocol/Response.js +61 -0
  27. package/source/class/qx/io/graphql/protocol/__init__.js +6 -0
  28. package/source/class/qx/io/jsonrpc/Client.js +323 -0
  29. package/source/class/qx/io/jsonrpc/__init__.js +15 -0
  30. package/source/class/qx/io/jsonrpc/protocol/Batch.js +97 -0
  31. package/source/class/qx/io/jsonrpc/protocol/Error.js +63 -0
  32. package/source/class/qx/io/jsonrpc/protocol/Message.js +48 -0
  33. package/source/class/qx/io/jsonrpc/protocol/Notification.js +45 -0
  34. package/source/class/qx/io/jsonrpc/protocol/Parser.js +81 -0
  35. package/source/class/qx/io/jsonrpc/protocol/Request.js +93 -0
  36. package/source/class/qx/io/jsonrpc/protocol/Result.js +48 -0
  37. package/source/class/qx/io/jsonrpc/protocol/__init__.js +5 -0
  38. package/source/class/qx/io/request/authentication/Bearer.js +52 -0
  39. package/source/class/qx/io/transport/AbstractClient.js +100 -0
  40. package/source/class/qx/io/transport/AbstractTransport.js +41 -0
  41. package/source/class/qx/io/transport/Fetch.js +95 -0
  42. package/source/class/qx/io/transport/ITransport.js +40 -0
  43. package/source/class/qx/io/transport/PostMessage.js +55 -0
  44. package/source/class/qx/io/transport/Websocket.js +97 -0
  45. package/source/class/qx/io/transport/Xhr.js +139 -0
  46. package/source/class/qx/io/transport/__init__.js +18 -0
  47. package/source/class/qx/test/io/MAssert.js +46 -0
  48. package/source/class/qx/test/io/graphql/Client.js +169 -0
  49. package/source/class/qx/test/io/graphql/ClientFetch.js +34 -0
  50. package/source/class/qx/test/io/graphql/Request.js +42 -0
  51. package/source/class/qx/test/io/jsonrpc/Client.js +267 -0
  52. package/source/class/qx/test/io/jsonrpc/Protocol.js +80 -0
  53. package/source/class/qx/test/io/transport/PostMessage.js +56 -0
  54. package/source/class/qx/test/io/transport/Websocket.js +63 -0
  55. package/source/class/qx/test/ui/embed/Iframe.js +1 -0
  56. package/source/class/qx/test/ui/form/ComboBox.js +0 -42
  57. package/source/class/qx/test/util/DateFormat.js +45 -6
  58. package/source/class/qx/theme/manager/Decoration.js +0 -0
  59. package/source/class/qx/theme/tangible/ColorDark.js +0 -0
  60. package/source/class/qx/tool/cli/Cli.js +5 -3
  61. package/source/class/qx/tool/cli/api/CompilerApi.js +15 -5
  62. package/source/class/qx/tool/cli/commands/Command.js +7 -0
  63. package/source/class/qx/tool/cli/commands/Compile.js +4 -4
  64. package/source/class/qx/tool/cli/commands/Lint.js +30 -11
  65. package/source/class/qx/tool/cli/commands/Package.js +1 -2
  66. package/source/class/qx/tool/cli/commands/package/Publish.js +33 -10
  67. package/source/class/qx/tool/compiler/Analyser.js +21 -22
  68. package/source/class/qx/tool/compiler/app/WebFont.js +1 -1
  69. package/source/class/qx/tool/compiler/makers/AppMaker.js +15 -14
  70. package/source/class/qx/tool/compiler/targets/Target.js +2 -1
  71. package/source/class/qx/tool/compiler/targets/TypeScriptWriter.js +1 -2
  72. package/source/class/qx/tool/compiler/targets/meta/PolyfillJs.js +17 -9
  73. package/source/class/qx/tool/config/Abstract.js +3 -3
  74. package/source/class/qx/tool/config/Utils.js +10 -1
  75. package/source/class/qx/tool/utils/Json.js +1 -1
  76. package/source/class/qx/ui/container/SlideBar.js +3 -0
  77. package/source/class/qx/ui/core/Widget.js +70 -0
  78. package/source/class/qx/ui/core/scroll/NativeScrollBar.js +3 -0
  79. package/source/class/qx/ui/core/scroll/ScrollBar.js +3 -0
  80. package/source/class/qx/ui/form/AbstractSelectBox.js +38 -6
  81. package/source/class/qx/ui/form/Button.js +3 -0
  82. package/source/class/qx/ui/form/CheckBox.js +25 -1
  83. package/source/class/qx/ui/form/ComboBox.js +41 -27
  84. package/source/class/qx/ui/form/DateField.js +16 -1
  85. package/source/class/qx/ui/form/List.js +3 -0
  86. package/source/class/qx/ui/form/MenuButton.js +28 -2
  87. package/source/class/qx/ui/form/RadioButton.js +7 -0
  88. package/source/class/qx/ui/form/RadioButtonGroup.js +3 -0
  89. package/source/class/qx/ui/form/RadioGroup.js +19 -0
  90. package/source/class/qx/ui/form/SelectBox.js +28 -1
  91. package/source/class/qx/ui/form/Slider.js +15 -0
  92. package/source/class/qx/ui/form/SplitButton.js +3 -0
  93. package/source/class/qx/ui/form/ToggleButton.js +8 -0
  94. package/source/class/qx/ui/menu/AbstractButton.js +28 -0
  95. package/source/class/qx/ui/menu/Button.js +3 -0
  96. package/source/class/qx/ui/menu/CheckBox.js +8 -0
  97. package/source/class/qx/ui/menu/Manager.js +2 -0
  98. package/source/class/qx/ui/menu/Menu.js +74 -2
  99. package/source/class/qx/ui/menu/RadioButton.js +10 -1
  100. package/source/class/qx/ui/menubar/Button.js +0 -27
  101. package/source/class/qx/ui/menubar/MenuBar.js +12 -0
  102. package/source/class/qx/ui/splitpane/Blocker.js +3 -0
  103. package/source/class/qx/ui/splitpane/Pane.js +3 -0
  104. package/source/class/qx/ui/table/Table.js +24 -2
  105. package/source/class/qx/ui/table/cellrenderer/Abstract.js +3 -1
  106. package/source/class/qx/ui/table/cellrenderer/AbstractImage.js +7 -3
  107. package/source/class/qx/ui/table/headerrenderer/HeaderCell.js +3 -0
  108. package/source/class/qx/ui/table/pane/Header.js +3 -0
  109. package/source/class/qx/ui/table/pane/Model.js +10 -4
  110. package/source/class/qx/ui/table/pane/Scroller.js +3 -7
  111. package/source/class/qx/ui/table/rowrenderer/Default.js +1 -1
  112. package/source/class/qx/ui/tabview/Page.js +26 -0
  113. package/source/class/qx/ui/tabview/TabView.js +3 -0
  114. package/source/class/qx/ui/toolbar/Button.js +2 -27
  115. package/source/class/qx/ui/toolbar/CheckBox.js +0 -27
  116. package/source/class/qx/ui/toolbar/RadioButton.js +21 -0
  117. package/source/class/qx/ui/toolbar/SplitButton.js +0 -28
  118. package/source/class/qx/ui/toolbar/ToolBar.js +3 -0
  119. package/source/class/qx/ui/window/Window.js +8 -0
  120. package/source/class/qx/util/format/DateFormat.js +44 -17
  121. package/source/class/qxWeb.js +2 -0
  122. package/source/resource/qx/decoration/Indigo/font/JosefinSlab-SemiBold.ttf +0 -0
  123. package/source/resource/qx/decoration/Indigo/font/SIL Open Font License 1.1.txt +0 -0
  124. package/source/resource/qx/iconfont/MaterialIcons/fetch-fonts.sh +0 -0
  125. package/source/resource/qx/tool/bin/build-devtools +0 -0
  126. package/source/resource/qx/tool/bin/build-website +0 -0
  127. package/source/resource/qx/tool/bin/download-assets +0 -0
  128. package/source/resource/qx/tool/cli/templates/loader/loader-node.tmpl.js +3 -1
  129. package/source/resource/qx/tool/cli/templates/template_vars.js +1 -1
  130. package/source/resource/qx/tool/loadsass.js +6 -12
  131. package/source/resource/qx/tool/schema/Manifest-1-0-0.json +1 -2
  132. package/source/resource/qx/tool/schema/Manifest-2-0-0.json +1 -2
  133. package/source/resource/qx/tool/schema/compile-1-0-0.json +3 -7
  134. package/source/translation/hr.po +297 -0
  135. package/lib/resource/qx/tool/website/.gitignore +0 -2
  136. package/source/class/qx/io/request/auth/.gitignore +0 -0
  137. package/source/class/qx/test/bom/client/.gitignore +0 -0
  138. package/source/class/qx/test/ui/control/.gitignore +0 -0
  139. package/source/resource/qx/decoration/Modern/treevirtual/.gitignore +0 -0
  140. package/source/resource/qx/mobile/css/.gitignore +0 -3
  141. package/source/resource/qx/tool/website/.gitignore +0 -2
  142. package/source/resource/qx/website/.gitignore +0 -1
  143. package/source/resource/qx/website/scss/.gitignore +0 -1
@@ -0,0 +1,323 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+ /**
20
+ * This class provides a JSON-RPC client object with auto-configuration of the
21
+ * transport used (based on the URI passed).
22
+ */
23
+ qx.Class.define("qx.io.jsonrpc.Client",
24
+ {
25
+ extend : qx.io.transport.AbstractClient,
26
+
27
+ statics: {
28
+ // statics are not inherited from parent class
29
+ registerTransport : qx.io.transport.AbstractClient.registerTransport
30
+ },
31
+
32
+ events : {
33
+ /**
34
+ * Event fired before a request message is sent to the server.
35
+ * Event data is the {@link qx.io.jsonrpc.protocol.Message} to
36
+ * be sent. This also allows listeners to configure the transport
37
+ * object beforehand.
38
+ */
39
+ "outgoingRequest": "qx.event.type.Data",
40
+
41
+ /**
42
+ * Event fired when a request results in an error. Event data is an instance of
43
+ * {@link qx.io.exception.Transport}, {@link qx.io.exception.Protocol},
44
+ * or {@link qx.io.exception.Cancel}.
45
+ * Event fired when a message is received from the endpoint. Event data
46
+ * is an UTF-8 encoded string
47
+ */
48
+ "error" : "qx.event.type.Data",
49
+
50
+ /**
51
+ * Event fired when a peer-originated JSON-RPC message has been
52
+ * received from the peer endpoint. Event data is an instance of {@link
53
+ * qx.io.jsonrpc.message.Batch}, {@link qx.io.jsonrpc.message.Request}
54
+ * or {@link qx.io.jsonrpc.protocol.Notification}.
55
+ */
56
+ "incomingRequest" : "qx.event.type.Data"
57
+ },
58
+
59
+ /**
60
+ * @param {qx.io.transport.ITransport|String} transportOrUri
61
+ * Transport object, which must implement {@link qx.io.transport.ITransport}
62
+ * or a string URI, which will trigger auto-detection of transport, as long as an
63
+ * appropriate transport has been registered with the static `registerTransport()` function.
64
+ * @param {String?} methodPrefix
65
+ * Optional service name which will be prepended to the method
66
+ * @param {qx.io.jsonrpc.protocol.Parser?} parser
67
+ * Optional parser object, which needs to be an instance of a subclass of {@link qx.io.jsonrpc.protocol.Parser}
68
+ */
69
+ construct : function(transportOrUri, methodPrefix, parser) {
70
+ this.base(arguments);
71
+ this.selectTransport(transportOrUri);
72
+ // listen for incoming messages
73
+ this.getTransport().addListener("message", evt => this.handleIncoming(evt.getData()));
74
+ if (!methodPrefix) {
75
+ methodPrefix = "";
76
+ }
77
+ this.setMethodPrefix(methodPrefix);
78
+ if (!parser) {
79
+ parser = new qx.io.jsonrpc.protocol.Parser();
80
+ }
81
+ this.setParser(parser);
82
+ this.__requests = [];
83
+ },
84
+
85
+ properties :
86
+ {
87
+ /**
88
+ * An optional string which is prepended to the method name by the {@link #sendRequest}
89
+ * and {@link #sendNotification} methods
90
+ */
91
+ methodPrefix :
92
+ {
93
+ check : "String",
94
+ nullable : true
95
+ },
96
+
97
+ /**
98
+ * The parser object, which must be a subclass of {@link qx.io.jsonrpc.protocol.Parser}
99
+ */
100
+ parser: {
101
+ check : "qx.io.jsonrpc.protocol.Parser"
102
+ }
103
+ },
104
+
105
+ members :
106
+ {
107
+
108
+ /**
109
+ * A cache of the requests which have been sent out and are still pending
110
+ */
111
+ __requests : null,
112
+
113
+ /**
114
+ * If a service name has been configured, prepend it to the method name,
115
+ * unless it has already been prefixed
116
+ * @param {String} method
117
+ * @return {String}
118
+ * @private
119
+ */
120
+ _prependMethodPrefix(method) {
121
+ qx.core.Assert.assertString(method);
122
+ let methodPrefix = this.getMethodPrefix();
123
+ if (methodPrefix && !method.startsWith(methodPrefix)) {
124
+ return `${methodPrefix}${method}`;
125
+ }
126
+ return method;
127
+ },
128
+
129
+ /**
130
+ * Fires "error" event and throws the error after informing pending requests
131
+ * about the error.
132
+ * @param exception
133
+ * @private
134
+ */
135
+ _throwTransportException(exception) {
136
+ this.fireDataEvent("error", exception);
137
+ this.__requests.forEach(request => {
138
+ if (request instanceof qx.io.jsonrpc.protocol.Request) {
139
+ request.handleTransportException(exception);
140
+ }
141
+ });
142
+ throw exception;
143
+ },
144
+
145
+ /**
146
+ * Send the given JSON-RPC message object using the configured transport
147
+ *
148
+ * @param {qx.io.jsonrpc.protocol.Message|qx.io.jsonrpc.protocol.Batch} message
149
+ * @return {qx.Promise} Promise that resolves (with no data)
150
+ * when the message has been successfully sent out, and rejects
151
+ * when there is an error or a cancellation up to that point.
152
+ */
153
+ async send(message) {
154
+ if (!(message instanceof qx.io.jsonrpc.protocol.Message || message instanceof qx.io.jsonrpc.protocol.Batch)) {
155
+ throw new Error("Argument must be instanceof qx.io.jsonrpc.protocol.Message or qx.io.jsonrpc.protocol.Batch");
156
+ }
157
+
158
+ // filter by type
159
+ let messages = message instanceof qx.io.jsonrpc.protocol.Batch ? message.getBatch().toArray() : [message];
160
+ let requests = messages.filter(message => message instanceof qx.io.jsonrpc.protocol.Request);
161
+
162
+ // store requests
163
+ requests.forEach(request => {
164
+ let id = request.getId();
165
+ if (this.__requests[id] !== undefined) {
166
+ throw new qx.io.exception.Transport(`Request ID ${id} is already in use`, qx.io.exception.Transport.INVALID_ID, {request: message.toObject()});
167
+ }
168
+ this.__requests[id] = request;
169
+ });
170
+
171
+ // inform listeners
172
+ this.fireDataEvent("outgoingRequest", message);
173
+
174
+ // debugging
175
+ if (qx.core.Environment.get("qx.io.jsonrpc.debug")) {
176
+ this.debug(">>> Outgoing json-rpc message: " + message);
177
+ }
178
+
179
+ // send it async, using transport-specific implementation
180
+ return this.getTransport().send(message.toString());
181
+ },
182
+
183
+ /**
184
+ * Sends a single JSON-RPC request. If a method prefix name has been configured,
185
+ * it will be prepended to the method name.
186
+ * @param {String} method
187
+ * @param {Array|Object?} params
188
+ * @return {qx.Promise} Promise that resolves with the result to that request,
189
+ * and rejects with an exception in the {@link qx.io.jsonrpc.exception} namespace.
190
+ */
191
+ async sendRequest(method, params) {
192
+ const request = new qx.io.jsonrpc.protocol.Request(this._prependMethodPrefix(method), params);
193
+ await this.send(request);
194
+ return await request.getPromise();
195
+ },
196
+
197
+ /**
198
+ * Sends a single JSON-RPC notification. Will use the method prefix
199
+ * @param {String} method
200
+ * @param {Array|Object?} params
201
+ * @return {qx.Promise} Promise that resolves immediately, (i.e. when the
202
+ * notification has been sent out (which is synchronous)
203
+ */
204
+ async sendNotification(method, params) {
205
+ const notification = new qx.io.jsonrpc.protocol.Notification(this._prependMethodPrefix(method), params);
206
+ await this.send(notification);
207
+ },
208
+
209
+ /**
210
+ * Send the given message batch. Will use the method prefix.
211
+ * @param {qx.io.jsonrpc.protocol.Batch} batch
212
+ * @return {qx.Promise} Promise that resolves with an array of the responses
213
+ * to all requests in the batch, or rejects with any error that occurs.
214
+ */
215
+ async sendBatch(batch) {
216
+ qx.core.Assert.assertInstance(batch, qx.io.jsonrpc.protocol.Batch);
217
+ if (this.getMethodPrefix()) {
218
+ batch.getBatch().forEach(message => message.setMethod(this._prependMethodPrefix(message.getMethod())));
219
+ }
220
+ await this.send(batch);
221
+ return await qx.Promise.all(batch.getPromises());
222
+ },
223
+
224
+ /**
225
+ * Receives and handles an incoming JSON-RPC compliant message data
226
+ * @param {String} json JSON data
227
+ */
228
+ handleIncoming(json) {
229
+ if (qx.core.Environment.get("qx.io.jsonrpc.debug")) {
230
+ this.debug("<<< Incoming json-rpc message: " + json);
231
+ }
232
+ let message;
233
+ try {
234
+ message = this.getParser().parse(json);
235
+ // act on each message
236
+ this.handleMessage(message);
237
+ } catch (e) {
238
+ this._throwTransportException(e);
239
+ } finally {
240
+ // cleanup
241
+ if (message instanceof qx.io.jsonrpc.protocol.Batch) {
242
+ message.getBatch().forEach(msg => this._cleanup(msg));
243
+ } else if (message instanceof qx.io.jsonrpc.protocol.Message) {
244
+ this._cleanup(message);
245
+ }
246
+ }
247
+ },
248
+
249
+ /**
250
+ * Clean up after a message has been received
251
+ * @param {qx.io.jsonrpc.protocol.Message} message
252
+ * @private
253
+ */
254
+ _cleanup(message) {
255
+ message.dispose();
256
+ },
257
+
258
+ /**
259
+ * Handle an incoming message or batch of messages
260
+ * @param {qx.io.jsonrpc.protocol.Message|qx.io.jsonrpc.protocol.Batch} message Message or Batch
261
+ */
262
+ handleMessage(message) {
263
+ // handle batches
264
+ if (message instanceof qx.io.jsonrpc.protocol.Batch) {
265
+ message.getBatch().forEach(msg => this.handleMessage(msg));
266
+ return;
267
+ }
268
+ // handle individual message
269
+ qx.core.Assert.assertInstance(message, qx.io.jsonrpc.protocol.Message);
270
+ let request;
271
+ let id;
272
+ if (message instanceof qx.io.jsonrpc.protocol.Result || message instanceof qx.io.jsonrpc.protocol.Error) {
273
+ // handle results and errors, which are responses to sent requests
274
+ id = message.getId();
275
+ request = this.__requests[id];
276
+ if (request === undefined) {
277
+ // no request with this id exists
278
+ throw new qx.io.exception.Transport(
279
+ `Invalid jsonrpc response data: Unknown id ${id}.`,
280
+ qx.io.exception.Transport.UNKNOWN_ID,
281
+ message.toObject()
282
+ );
283
+ }
284
+ if (request === true) {
285
+ // the request has already been responded to
286
+ throw new qx.io.exception.Transport(
287
+ `Invalid jsonrpc response data: multiple responses with same id ${id}.`,
288
+ qx.io.exception.Transport.DUPLICATE_ID,
289
+ message.toObject()
290
+ );
291
+ }
292
+ }
293
+ // handle the different message types
294
+ if (message instanceof qx.io.jsonrpc.protocol.Result) {
295
+ // resolve the individual promise
296
+ request.getPromise().resolve(message.getResult());
297
+ } else if (message instanceof qx.io.jsonrpc.protocol.Error) {
298
+
299
+ let error = message.getError();
300
+ let ex = new qx.io.exception.Protocol(
301
+ error.message,
302
+ error.code,
303
+ message.toObject()
304
+ );
305
+ // inform listeners
306
+ this.fireDataEvent("error", ex);
307
+ // reject the individual promise
308
+ request.getPromise().reject(ex);
309
+ } else if (message instanceof qx.io.jsonrpc.protocol.Request || message instanceof qx.io.jsonrpc.protocol.Notification) {
310
+ // handle peer-originated requests and notifications
311
+ this.fireDataEvent("incomingRequest", message);
312
+ } else {
313
+ throw new Error("Unhandled message:" + message.toString());
314
+ }
315
+ // mark request as handled (and remove reference so it can be gc'ed)
316
+ this.__requests[id] = true;
317
+ }
318
+ },
319
+
320
+ environment: {
321
+ "qx.io.jsonrpc.debug" : false
322
+ }
323
+ });
@@ -0,0 +1,15 @@
1
+ /**
2
+ * <p>This namespace provides an API implementing the <a
3
+ * href="https://www.jsonrpc.org/specification">JSON Remote
4
+ * Procedure Call (JSON-RPC) version 2 specification</a></p>
5
+ *
6
+ * <p>JSON-RPC v2 is transport-agnostic. We provide a high-level
7
+ * API interface (qx.io.jsonrpc.Client), a transport interface
8
+ * (qx.io.transport.ITransport) and an HTTP transport implementation.
9
+ * Other transports based on websockets or other mechanisms can be added later.</p>
10
+ *
11
+ * <p>Please refer to
12
+ * <a href="https://github.com/qooxdoo/incubator.qx.io.jsonrpc/blob/master/readme.md#usage">
13
+ * the documentation on GitHub
14
+ * </a></p>
15
+ */
@@ -0,0 +1,97 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+ /**
20
+ * An object representing a JSON-RPC v2.0 batch message object. You can add
21
+ * one or more of the following message objects to the batch:
22
+ * - {@link qx.io.jsonrpc.protocol.Request}
23
+ * - {@link qx.io.jsonrpc.protocol.Notification}
24
+ * - {@link qx.io.jsonrpc.protocol.Result}
25
+ * - {@link qx.io.jsonrpc.protocol.Error}
26
+ * @see https://www.jsonrpc.org/specification#batch
27
+ */
28
+ qx.Class.define("qx.io.jsonrpc.protocol.Batch",{
29
+ extend: qx.core.Object,
30
+ properties: {
31
+ batch : {
32
+ check: "qx.data.Array"
33
+ }
34
+ },
35
+ construct() {
36
+ this.base(arguments);
37
+ this.setBatch(new qx.data.Array());
38
+ },
39
+ members: {
40
+
41
+ /**
42
+ * Adds a request or notification to the batch
43
+ * @param {qx.io.jsonrpc.protocol.Message} message
44
+ * @return {qx.io.jsonrpc.protocol.Batch}
45
+ */
46
+ add(message) {
47
+ qx.core.Assert.assertInstance(message, qx.io.jsonrpc.protocol.Message);
48
+ this.getBatch().push(message);
49
+ // return the instance for chaining
50
+ return this;
51
+ },
52
+
53
+ /**
54
+ * Adds a request to the batch
55
+ * @param method
56
+ * @param params
57
+ */
58
+ addRequest(method,params) {
59
+ this.add(new qx.io.jsonrpc.protocol.Request(method, params));
60
+ return this;
61
+ },
62
+
63
+ /**
64
+ * Adds a notification to the batch
65
+ * @param method
66
+ * @param params
67
+ */
68
+ addNotification(method,params) {
69
+ this.add(new qx.io.jsonrpc.protocol.Notification(method, params));
70
+ return this;
71
+ },
72
+
73
+ /**
74
+ * Returns an array of the promises of the requests in the batch
75
+ * @return {qx.Promise[]}
76
+ */
77
+ getPromises() {
78
+ return this.getBatch().map(message => message.getPromise());
79
+ },
80
+
81
+ /**
82
+ * Returns the message as a native object
83
+ * @return {*}
84
+ */
85
+ toObject() {
86
+ return this.getBatch().toArray().map(message => message.toObject());
87
+ },
88
+
89
+ /**
90
+ * Returns the message as a JSON string
91
+ * @return {String}
92
+ */
93
+ toString() {
94
+ return JSON.stringify(this.getBatch().toArray().map(message => message.toObject()));
95
+ }
96
+ }
97
+ });
@@ -0,0 +1,63 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+ /**
20
+ * A JSON-RPC v2.0 error message object, which is a response to a {@link qx.io.jsonrpc.protocol.Request},
21
+ * indicating a failure during the processing of the request on the server.
22
+ * @see https://www.jsonrpc.org/specification#error_object
23
+ */
24
+ qx.Class.define("qx.io.jsonrpc.protocol.Error",{
25
+ extend: qx.io.jsonrpc.protocol.Message,
26
+ properties: {
27
+
28
+ /**
29
+ * The integer id of the request
30
+ * @var {Number}
31
+ */
32
+ id : {
33
+ check: value => qx.lang.Type.isNumber(value) && parseInt(value, 10) === value
34
+ },
35
+
36
+ /**
37
+ * The error object
38
+ * @var {Object}
39
+ */
40
+ error : {
41
+ check : value => qx.lang.Type.isObject(value) && "code" in value && "message" in value
42
+ }
43
+ },
44
+ /**
45
+ * The response messsage constructor
46
+ * @param {Number} id^
47
+ * @param {Number} code
48
+ * @param {String} message
49
+ * @param {*?} data
50
+ */
51
+ construct(id, code, message, data) {
52
+ this.base(arguments);
53
+ this.setId(id);
54
+ if (!qx.lang.Type.isNumber(code) || parseInt(code, 10) !== code ) {
55
+ throw new Error("Code must be an integer");
56
+ }
57
+ let errorObj = {code, message};
58
+ if (data) {
59
+ errorObj.data = data;
60
+ }
61
+ this.setError(errorObj);
62
+ }
63
+ });
@@ -0,0 +1,48 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+ /**
20
+ * The base class for all JSON-RPC v2.0 object except {@link qx.io.jsonrpc.protocol.Batch}
21
+ */
22
+ qx.Class.define("qx.io.jsonrpc.protocol.Message",{
23
+ extend: qx.core.Object,
24
+ properties: {
25
+ jsonrpc : {
26
+ check: "String",
27
+ init: "2.0"
28
+ }
29
+ },
30
+
31
+ members : {
32
+ /**
33
+ * Serialize to JSON string
34
+ * @return {String}
35
+ */
36
+ toString() {
37
+ return qx.util.Serializer.toJson(this);
38
+ },
39
+
40
+ /**
41
+ * Serialize to a native javascript object
42
+ * @return {Object}
43
+ */
44
+ toObject() {
45
+ return qx.util.Serializer.toNativeObject(this);
46
+ }
47
+ }
48
+ });
@@ -0,0 +1,45 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+ /**
20
+ * A JSON-RPC v2.0 notification object
21
+ * @see https://www.jsonrpc.org/specification#request_object
22
+ */
23
+ qx.Class.define("qx.io.jsonrpc.protocol.Notification",{
24
+ extend: qx.io.jsonrpc.protocol.Message,
25
+ properties: {
26
+ method : {
27
+ check: "String",
28
+ nullable: false
29
+ },
30
+ params : {
31
+ check: "Object",
32
+ nullable: true,
33
+ init: null
34
+ }
35
+ },
36
+ /**
37
+ * Notification constructor
38
+ * @param {String} method
39
+ * @param {Object?} params
40
+ */
41
+ construct(method, params=null) {
42
+ this.base(arguments);
43
+ this.set({method, params});
44
+ }
45
+ });
@@ -0,0 +1,81 @@
1
+ /* ************************************************************************
2
+
3
+ qooxdoo - the new era of web development
4
+
5
+ http://qooxdoo.org
6
+
7
+ Copyright:
8
+ 2020 Christian Boulanger
9
+
10
+ License:
11
+ MIT: https://opensource.org/licenses/MIT
12
+ See the LICENSE file in the project's top-level directory for details.
13
+
14
+ Authors:
15
+ * Christian Boulanger (cboulanger)
16
+
17
+ ************************************************************************ */
18
+
19
+
20
+ /**
21
+ * The parser object has a parse() method, which takes a UTF-encoded string and
22
+ * returns an instance of the correponding subclass of {@link qx.io.jsonrpc.protocol.Message} or
23
+ * a {@link qx.io.jsonrpc.protocol.Batch} instance.
24
+ */
25
+ qx.Class.define("qx.io.jsonrpc.protocol.Parser", {
26
+ extend: qx.core.Object,
27
+ members: {
28
+ /**
29
+ * Given an UTF-8 encoded string, return the corresponding message object,
30
+ * which is one of {@link qx.io.jsonrpc.protocol.Batch}, {@link qx.io.jsonrpc.protocol.Notification},
31
+ * {@link qx.io.jsonrpc.protocol.Request}, {@link qx.io.jsonrpc.protocol.Result}, or
32
+ * {@link qx.io.jsonrpc.protocol.Error}.
33
+ *
34
+ * @param {String} message
35
+ * @return {qx.io.jsonrpc.protocol.Message}
36
+ * @throws {qx.io.exception.Transport}
37
+ */
38
+ parse(message) {
39
+ try {
40
+ message = JSON.parse(message);
41
+ } catch (e) {
42
+ throw new qx.io.exception.Transport(
43
+ e.toString(),
44
+ qx.io.exception.Transport.INVALID_JSON,
45
+ {message}
46
+ );
47
+ }
48
+ if (message === null) {
49
+ throw new qx.io.exception.Transport(
50
+ "No data",
51
+ qx.io.exception.Transport.NO_DATA
52
+ );
53
+ }
54
+ // batch
55
+ if (qx.lang.Type.isArray(message)) {
56
+ const batch = new qx.io.jsonrpc.protocol.Batch();
57
+ message.forEach(item => batch.add(this.parse(JSON.stringify(item))));
58
+ return batch;
59
+ }
60
+ // individual message
61
+ let {id, result, method, params, error} = message;
62
+ if (id !== undefined && result !== undefined && error === undefined && method === undefined) {
63
+ return new qx.io.jsonrpc.protocol.Result(id, result);
64
+ }
65
+ if (id !== undefined && result === undefined && error !== undefined && method === undefined) {
66
+ return new qx.io.jsonrpc.protocol.Error(id, error.code, error.message, error.data);
67
+ }
68
+ if (id !== undefined && result === undefined && error === undefined && method !== undefined) {
69
+ return new qx.io.jsonrpc.protocol.Request(method, params, id);
70
+ }
71
+ if (id === undefined && result === undefined && error === undefined && method !== undefined) {
72
+ return new qx.io.jsonrpc.protocol.Notification(method, params);
73
+ }
74
+ throw new qx.io.exception.Transport(
75
+ "Cannot parse message data.",
76
+ qx.io.exception.Transport.INVALID_MSG_DATA,
77
+ {message}
78
+ );
79
+ }
80
+ }
81
+ });