rdflib 2.2.21 → 2.2.22

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 (106) hide show
  1. package/dist/rdflib.min.js +1 -1
  2. package/dist/rdflib.min.js.LICENSE.txt +9 -1
  3. package/dist/rdflib.min.js.map +1 -1
  4. package/esm/blank-node.js +61 -114
  5. package/esm/class-order.js +1 -1
  6. package/esm/collection.js +70 -128
  7. package/esm/convert.js +1 -2
  8. package/esm/default-graph.js +14 -48
  9. package/esm/empty.js +8 -39
  10. package/esm/factories/canonical-data-factory.js +33 -65
  11. package/esm/factories/extended-term-factory.js +18 -25
  12. package/esm/factories/factory-types.js +3 -2
  13. package/esm/factories/rdflib-data-factory.js +9 -19
  14. package/esm/fetcher.js +1341 -1854
  15. package/esm/formula.js +639 -846
  16. package/esm/index.js +40 -76
  17. package/esm/jsonldparser.js +24 -49
  18. package/esm/jsonparser.js +1 -8
  19. package/esm/lists.js +47 -110
  20. package/esm/literal.js +120 -189
  21. package/esm/log.js +7 -7
  22. package/esm/n3parser.js +1015 -1412
  23. package/esm/named-node.js +70 -119
  24. package/esm/namespace.js +2 -5
  25. package/esm/node-internal.js +73 -110
  26. package/esm/node.js +2 -7
  27. package/esm/parse.js +12 -19
  28. package/esm/patch-parser.js +10 -30
  29. package/esm/query-to-sparql.js +0 -18
  30. package/esm/query.js +63 -147
  31. package/esm/rdfaparser.js +794 -997
  32. package/esm/rdfxmlparser.js +347 -461
  33. package/esm/serialize.js +9 -27
  34. package/esm/serializer.js +820 -1049
  35. package/esm/sparql-to-query.js +44 -134
  36. package/esm/statement.js +54 -85
  37. package/esm/store.js +830 -1103
  38. package/esm/types.js +22 -21
  39. package/esm/update-manager.js +869 -1106
  40. package/esm/updates-via.js +104 -161
  41. package/esm/uri.js +9 -53
  42. package/esm/utils/default-graph-uri.js +3 -2
  43. package/esm/utils/termValue.js +0 -1
  44. package/esm/utils/terms.js +19 -21
  45. package/esm/utils-js.js +20 -61
  46. package/esm/utils.js +10 -21
  47. package/esm/variable.js +32 -78
  48. package/esm/xsd.js +2 -2
  49. package/lib/blank-node.js +60 -113
  50. package/lib/class-order.js +1 -2
  51. package/lib/collection.js +69 -131
  52. package/lib/convert.js +3 -9
  53. package/lib/default-graph.js +13 -52
  54. package/lib/empty.js +8 -43
  55. package/lib/factories/canonical-data-factory.js +35 -79
  56. package/lib/factories/extended-term-factory.js +18 -32
  57. package/lib/factories/factory-types.d.ts +6 -6
  58. package/lib/factories/factory-types.js +1 -4
  59. package/lib/factories/rdflib-data-factory.js +9 -23
  60. package/lib/fetcher.d.ts +6 -6
  61. package/lib/fetcher.js +1370 -1843
  62. package/lib/formula.js +640 -855
  63. package/lib/index.js +66 -152
  64. package/lib/jsonldparser.js +23 -53
  65. package/lib/jsonparser.js +1 -10
  66. package/lib/lists.js +55 -112
  67. package/lib/literal.js +120 -195
  68. package/lib/log.d.ts +0 -6
  69. package/lib/log.js +7 -8
  70. package/lib/n3parser.js +1030 -1436
  71. package/lib/named-node.js +69 -126
  72. package/lib/namespace.js +2 -7
  73. package/lib/node-internal.js +74 -107
  74. package/lib/node.js +2 -12
  75. package/lib/parse.d.ts +1 -1
  76. package/lib/parse.js +12 -32
  77. package/lib/patch-parser.js +11 -34
  78. package/lib/query-to-sparql.js +0 -23
  79. package/lib/query.js +62 -167
  80. package/lib/rdfaparser.js +796 -1009
  81. package/lib/rdfxmlparser.js +349 -466
  82. package/lib/serialize.js +11 -37
  83. package/lib/serializer.js +823 -1064
  84. package/lib/sparql-to-query.js +42 -167
  85. package/lib/statement.js +55 -91
  86. package/lib/store.d.ts +1 -1
  87. package/lib/store.js +850 -1112
  88. package/lib/tf-types.d.ts +4 -4
  89. package/lib/types.d.ts +8 -8
  90. package/lib/types.js +23 -23
  91. package/lib/update-manager.d.ts +1 -1
  92. package/lib/update-manager.js +865 -1103
  93. package/lib/updates-via.js +105 -164
  94. package/lib/uri.js +8 -61
  95. package/lib/utils/default-graph-uri.js +3 -5
  96. package/lib/utils/termValue.js +0 -2
  97. package/lib/utils/terms.js +19 -40
  98. package/lib/utils-js.js +23 -88
  99. package/lib/utils.js +10 -27
  100. package/lib/variable.js +34 -85
  101. package/lib/xsd-internal.js +0 -3
  102. package/lib/xsd.js +2 -6
  103. package/package.json +36 -36
  104. package/src/fetcher.ts +2 -2
  105. package/src/update-manager.ts +12 -7
  106. package/changes.txt +0 -59
package/esm/fetcher.js CHANGED
@@ -1,18 +1,5 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _inherits from "@babel/runtime/helpers/inherits";
3
- import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
4
- import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
5
- import _createClass from "@babel/runtime/helpers/createClass";
6
- import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
7
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
8
- import _regeneratorRuntime from "@babel/runtime/regenerator";
9
-
10
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
11
-
12
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
13
-
14
2
  /* global $SolidTestEnvironment */
15
-
16
3
  /**
17
4
  *
18
5
  * Project: rdflib.js
@@ -55,16 +42,17 @@ import crossFetch, { Headers } from 'cross-fetch';
55
42
  import { TurtleContentType, RDFXMLContentType, XHTMLContentType } from './types';
56
43
  import { termValue } from './utils/termValue';
57
44
  import jsonldParser from './jsonldparser';
58
- var Parsable = {
45
+ const Parsable = {
59
46
  'text/n3': true,
60
47
  'text/turtle': true,
61
48
  'application/rdf+xml': true,
62
49
  'application/xhtml+xml': true,
63
50
  'text/html': true,
64
51
  'application/ld+json': true
65
- }; // This is a minimal set to allow the use of damaged servers if necessary
52
+ };
66
53
 
67
- var CONTENT_TYPE_BY_EXT = {
54
+ // This is a minimal set to allow the use of damaged servers if necessary
55
+ const CONTENT_TYPE_BY_EXT = {
68
56
  'rdf': RDFXMLContentType,
69
57
  'owl': RDFXMLContentType,
70
58
  'n3': 'text/n3',
@@ -73,13 +61,14 @@ var CONTENT_TYPE_BY_EXT = {
73
61
  'acl': 'text/n3',
74
62
  'html': 'text/html',
75
63
  'xml': 'text/xml'
76
- }; // Convenience namespaces needed in this module.
64
+ };
65
+
66
+ // Convenience namespaces needed in this module.
77
67
  // These are deliberately not exported as the user application should
78
68
  // make its own list and not rely on the prefixes used here,
79
69
  // and not be tempted to add to them, and them clash with those of another
80
70
  // application.
81
-
82
- var getNS = function getNS(factory) {
71
+ const getNS = factory => {
83
72
  return {
84
73
  link: Namespace('http://www.w3.org/2007/ont/link#', factory),
85
74
  http: Namespace('http://www.w3.org/2007/ont/http#', factory),
@@ -91,539 +80,351 @@ var getNS = function getNS(factory) {
91
80
  ldp: Namespace('http://www.w3.org/ns/ldp#', factory)
92
81
  };
93
82
  };
94
-
95
- var ns = getNS();
96
-
97
- var Handler = /*#__PURE__*/_createClass( // TODO: Document, type
98
- // TODO: Document, type
99
- function Handler(response, dom) {
100
- _classCallCheck(this, Handler);
101
-
102
- _defineProperty(this, "response", void 0);
103
-
104
- _defineProperty(this, "dom", void 0);
105
-
106
- this.response = response; // The type assertion operator here might need to be removed.
107
-
108
- this.dom = dom;
109
- });
110
-
83
+ const ns = getNS();
84
+ class Handler {
85
+ // TODO: Document, type
86
+
87
+ // TODO: Document, type
88
+
89
+ constructor(response, dom) {
90
+ _defineProperty(this, "response", void 0);
91
+ _defineProperty(this, "dom", void 0);
92
+ this.response = response;
93
+ // The type assertion operator here might need to be removed.
94
+ this.dom = dom;
95
+ }
96
+ }
111
97
  _defineProperty(Handler, "pattern", void 0);
112
-
113
- var RDFXMLHandler = /*#__PURE__*/function (_Handler) {
114
- _inherits(RDFXMLHandler, _Handler);
115
-
116
- var _super = _createSuper(RDFXMLHandler);
117
-
118
- function RDFXMLHandler() {
119
- _classCallCheck(this, RDFXMLHandler);
120
-
121
- return _super.apply(this, arguments);
98
+ class RDFXMLHandler extends Handler {
99
+ static toString() {
100
+ return 'RDFXMLHandler';
122
101
  }
123
-
124
- _createClass(RDFXMLHandler, [{
125
- key: "parse",
126
- value: function parse(fetcher,
127
- /** An XML String */
128
- responseText,
129
- /** Requires .original */
130
- options) {
131
- var kb = fetcher.store;
132
-
133
- if (!this.dom) {
134
- this.dom = Util.parseXML(responseText);
135
- }
136
-
137
- var root = this.dom.documentElement;
138
-
139
- if (root.nodeName === 'parsererror') {
140
- // Mozilla only See issue/issue110
141
- // have to fail the request
142
- return fetcher.failFetch(options, 'Badly formed XML in ' + options.resource.value, 'parse_error');
143
- }
144
-
145
- var parser = new RDFParser(kb);
146
-
147
- try {
148
- parser.parse(this.dom, options.original.value, options.original);
149
- } catch (err) {
150
- return fetcher.failFetch(options, 'Syntax error parsing RDF/XML! ' + err, 'parse_error');
151
- }
152
-
153
- if (!options.noMeta) {
154
- kb.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
155
- }
156
-
157
- return fetcher.doneFetch(options, this.response);
158
- }
159
- }], [{
160
- key: "toString",
161
- value: function toString() {
162
- return 'RDFXMLHandler';
163
- }
164
- }, {
165
- key: "register",
166
- value: function register(fetcher) {
167
- fetcher.mediatypes[RDFXMLContentType] = {
168
- 'q': 0.9
169
- };
170
- }
171
- }]);
172
-
173
- return RDFXMLHandler;
174
- }(Handler);
175
-
102
+ static register(fetcher) {
103
+ fetcher.mediatypes[RDFXMLContentType] = {
104
+ 'q': 0.9
105
+ };
106
+ }
107
+ parse(fetcher, /** An XML String */
108
+ responseText, /** Requires .original */
109
+ options) {
110
+ let kb = fetcher.store;
111
+ if (!this.dom) {
112
+ this.dom = Util.parseXML(responseText);
113
+ }
114
+ let root = this.dom.documentElement;
115
+ if (root.nodeName === 'parsererror') {
116
+ // Mozilla only See issue/issue110
117
+ // have to fail the request
118
+ return fetcher.failFetch(options, 'Badly formed XML in ' + options.resource.value, 'parse_error');
119
+ }
120
+ let parser = new RDFParser(kb);
121
+ try {
122
+ parser.parse(this.dom, options.original.value, options.original);
123
+ } catch (err) {
124
+ return fetcher.failFetch(options, 'Syntax error parsing RDF/XML! ' + err, 'parse_error');
125
+ }
126
+ if (!options.noMeta) {
127
+ kb.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
128
+ }
129
+ return fetcher.doneFetch(options, this.response);
130
+ }
131
+ }
176
132
  RDFXMLHandler.pattern = new RegExp('application/rdf\\+xml');
177
-
178
- var XHTMLHandler = /*#__PURE__*/function (_Handler2) {
179
- _inherits(XHTMLHandler, _Handler2);
180
-
181
- var _super2 = _createSuper(XHTMLHandler);
182
-
183
- function XHTMLHandler() {
184
- _classCallCheck(this, XHTMLHandler);
185
-
186
- return _super2.apply(this, arguments);
133
+ class XHTMLHandler extends Handler {
134
+ static toString() {
135
+ return 'XHTMLHandler';
187
136
  }
188
-
189
- _createClass(XHTMLHandler, [{
190
- key: "parse",
191
- value: function parse(fetcher, responseText, options) {
192
- var relation, reverse;
193
-
194
- if (!this.dom) {
195
- this.dom = Util.parseXML(responseText);
196
- }
197
-
198
- var kb = fetcher.store; // dc:title
199
-
200
- var title = this.dom.getElementsByTagName('title');
201
-
202
- if (title.length > 0) {
203
- kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(title[0].textContent), options.resource); // log.info("Inferring title of " + xhr.resource)
204
- } // link rel
205
-
206
-
207
- var links = this.dom.getElementsByTagName('link');
208
-
209
- for (var x = links.length - 1; x >= 0; x--) {
210
- // @@ rev
211
- relation = links[x].getAttribute('rel');
212
- reverse = false;
213
-
214
- if (!relation) {
215
- relation = links[x].getAttribute('rev');
216
- reverse = true;
217
- }
218
-
219
- if (relation) {
220
- fetcher.linkData(options.original, relation, links[x].getAttribute('href'), options.resource, reverse);
221
- }
222
- } // Data Islands
223
-
224
-
225
- var scripts = this.dom.getElementsByTagName('script');
226
-
227
- for (var i = 0; i < scripts.length; i++) {
228
- var contentType = scripts[i].getAttribute('type');
229
-
230
- if (Parsable[contentType]) {
231
- // @ts-ignore incompatibility between Store.add and Formula.add
232
- rdfParse(scripts[i].textContent, kb, options.original.value, contentType); // @ts-ignore incompatibility between Store.add and Formula.add
233
-
234
- rdfParse(scripts[i].textContent, kb, options.original.value, contentType);
235
- }
137
+ static register(fetcher) {
138
+ fetcher.mediatypes[XHTMLContentType] = {};
139
+ }
140
+ parse(fetcher, responseText, options) {
141
+ let relation, reverse;
142
+ if (!this.dom) {
143
+ this.dom = Util.parseXML(responseText);
144
+ }
145
+ let kb = fetcher.store;
146
+
147
+ // dc:title
148
+ let title = this.dom.getElementsByTagName('title');
149
+ if (title.length > 0) {
150
+ kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(title[0].textContent), options.resource);
151
+ // log.info("Inferring title of " + xhr.resource)
152
+ }
153
+
154
+ // link rel
155
+ let links = this.dom.getElementsByTagName('link');
156
+ for (let x = links.length - 1; x >= 0; x--) {
157
+ // @@ rev
158
+ relation = links[x].getAttribute('rel');
159
+ reverse = false;
160
+ if (!relation) {
161
+ relation = links[x].getAttribute('rev');
162
+ reverse = true;
236
163
  }
237
-
238
- if (!options.noMeta) {
239
- kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
164
+ if (relation) {
165
+ fetcher.linkData(options.original, relation, links[x].getAttribute('href'), options.resource, reverse);
240
166
  }
167
+ }
241
168
 
242
- if (!options.noRDFa && parseRDFaDOM) {
243
- // enable by default
244
- try {
245
- parseRDFaDOM(this.dom, kb, options.original.value);
246
- } catch (err) {
247
- // @ts-ignore
248
- var msg = 'Error trying to parse ' + options.resource + ' as RDFa:\n' + err + ':\n' + err.stack;
249
- return fetcher.failFetch(options, msg, 'parse_error');
250
- }
169
+ // Data Islands
170
+ let scripts = this.dom.getElementsByTagName('script');
171
+ for (let i = 0; i < scripts.length; i++) {
172
+ let contentType = scripts[i].getAttribute('type');
173
+ if (Parsable[contentType]) {
174
+ // @ts-ignore incompatibility between Store.add and Formula.add
175
+ rdfParse(scripts[i].textContent, kb, options.original.value, contentType);
176
+ // @ts-ignore incompatibility between Store.add and Formula.add
177
+ rdfParse(scripts[i].textContent, kb, options.original.value, contentType);
251
178
  }
252
-
253
- return fetcher.doneFetch(options, this.response);
254
179
  }
255
- }], [{
256
- key: "toString",
257
- value: function toString() {
258
- return 'XHTMLHandler';
180
+ if (!options.noMeta) {
181
+ kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
259
182
  }
260
- }, {
261
- key: "register",
262
- value: function register(fetcher) {
263
- fetcher.mediatypes[XHTMLContentType] = {};
183
+ if (!options.noRDFa && parseRDFaDOM) {
184
+ // enable by default
185
+ try {
186
+ parseRDFaDOM(this.dom, kb, options.original.value);
187
+ } catch (err) {
188
+ // @ts-ignore
189
+ let msg = 'Error trying to parse ' + options.resource + ' as RDFa:\n' + err + ':\n' + err.stack;
190
+ return fetcher.failFetch(options, msg, 'parse_error');
191
+ }
264
192
  }
265
- }]);
266
-
267
- return XHTMLHandler;
268
- }(Handler);
269
-
193
+ return fetcher.doneFetch(options, this.response);
194
+ }
195
+ }
270
196
  XHTMLHandler.pattern = new RegExp('application/xhtml');
271
-
272
- var XMLHandler = /*#__PURE__*/function (_Handler3) {
273
- _inherits(XMLHandler, _Handler3);
274
-
275
- var _super3 = _createSuper(XMLHandler);
276
-
277
- function XMLHandler() {
278
- _classCallCheck(this, XMLHandler);
279
-
280
- return _super3.apply(this, arguments);
197
+ class XMLHandler extends Handler {
198
+ static toString() {
199
+ return 'XMLHandler';
281
200
  }
282
-
283
- _createClass(XMLHandler, [{
284
- key: "parse",
285
- value: function parse(fetcher, responseText, options) {
286
- var dom = Util.parseXML(responseText); // XML Semantics defined by root element namespace
287
- // figure out the root element
288
-
289
- for (var c = 0; c < dom.childNodes.length; c++) {
290
- var node = dom.childNodes[c]; // is this node an element?
291
-
292
- if (XMLHandler.isElement(node)) {
293
- // We've found the first element, it's the root
294
- var _ns = node.namespaceURI; // Is it RDF/XML?
295
-
296
- if (_ns && _ns === _ns['rdf']) {
297
- fetcher.addStatus(options.req, 'Has XML root element in the RDF namespace, so assume RDF/XML.');
298
- var rdfHandler = new RDFXMLHandler(this.response, dom);
299
- return rdfHandler.parse(fetcher, responseText, options);
300
- }
301
-
302
- break;
303
- }
304
- } // Or it could be XHTML?
305
- // Maybe it has an XHTML DOCTYPE?
306
-
307
-
308
- if (dom.doctype) {
309
- // log.info("We found a DOCTYPE in " + xhr.resource)
310
- if (dom.doctype.name === 'html' && dom.doctype.publicId.match(/^-\/\/W3C\/\/DTD XHTML/) && dom.doctype.systemId.match(/http:\/\/www.w3.org\/TR\/xhtml/)) {
311
- fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTML Handler.\n');
312
- var xhtmlHandler = new XHTMLHandler(this.response, dom);
313
- return xhtmlHandler.parse(fetcher, responseText, options);
314
- }
315
- } // Or what about an XHTML namespace?
316
-
317
-
318
- var html = dom.getElementsByTagName('html')[0];
319
-
320
- if (html) {
321
- var xmlns = html.getAttribute('xmlns');
322
-
323
- if (xmlns && xmlns.match(/^http:\/\/www.w3.org\/1999\/xhtml/)) {
324
- fetcher.addStatus(options.req, 'Has a default namespace for ' + 'XHTML. Switching to XHTMLHandler.\n');
325
-
326
- var _xhtmlHandler = new XHTMLHandler(this.response, dom);
327
-
328
- return _xhtmlHandler.parse(fetcher, responseText, options);
201
+ static register(fetcher) {
202
+ fetcher.mediatypes['text/xml'] = {
203
+ 'q': 0.5
204
+ };
205
+ fetcher.mediatypes['application/xml'] = {
206
+ 'q': 0.5
207
+ };
208
+ }
209
+ static isElement(node) {
210
+ return node.nodeType === Node.ELEMENT_NODE;
211
+ }
212
+ parse(fetcher, responseText, options) {
213
+ let dom = Util.parseXML(responseText);
214
+
215
+ // XML Semantics defined by root element namespace
216
+ // figure out the root element
217
+ for (let c = 0; c < dom.childNodes.length; c++) {
218
+ const node = dom.childNodes[c];
219
+ // is this node an element?
220
+ if (XMLHandler.isElement(node)) {
221
+ // We've found the first element, it's the root
222
+ let ns = node.namespaceURI;
223
+
224
+ // Is it RDF/XML?
225
+ if (ns && ns === ns['rdf']) {
226
+ fetcher.addStatus(options.req, 'Has XML root element in the RDF namespace, so assume RDF/XML.');
227
+ let rdfHandler = new RDFXMLHandler(this.response, dom);
228
+ return rdfHandler.parse(fetcher, responseText, options);
329
229
  }
330
- } // At this point we should check the namespace document (cache it!) and
331
- // look for a GRDDL transform
332
- // @@ Get namespace document <n>, parse it, look for <n> grddl:namespaceTransform ?y
333
- // Apply ?y to dom
334
- // We give up. What dialect is this?
335
-
336
-
337
- return fetcher.failFetch(options, 'Unsupported dialect of XML: not RDF or XHTML namespace, etc.\n' + responseText.slice(0, 80), 901);
338
- }
339
- }], [{
340
- key: "toString",
341
- value: function toString() {
342
- return 'XMLHandler';
343
- }
344
- }, {
345
- key: "register",
346
- value: function register(fetcher) {
347
- fetcher.mediatypes['text/xml'] = {
348
- 'q': 0.5
349
- };
350
- fetcher.mediatypes['application/xml'] = {
351
- 'q': 0.5
352
- };
353
- }
354
- }, {
355
- key: "isElement",
356
- value: function isElement(node) {
357
- return node.nodeType === Node.ELEMENT_NODE;
230
+ break;
231
+ }
358
232
  }
359
- }]);
360
-
361
- return XMLHandler;
362
- }(Handler);
363
-
364
- XMLHandler.pattern = new RegExp('(text|application)/(.*)xml');
365
-
366
- var HTMLHandler = /*#__PURE__*/function (_Handler4) {
367
- _inherits(HTMLHandler, _Handler4);
368
-
369
- var _super4 = _createSuper(HTMLHandler);
370
-
371
- function HTMLHandler() {
372
- _classCallCheck(this, HTMLHandler);
373
233
 
374
- return _super4.apply(this, arguments);
375
- }
376
-
377
- _createClass(HTMLHandler, [{
378
- key: "parse",
379
- value: function parse(fetcher, responseText, options) {
380
- var kb = fetcher.store; // We only handle XHTML so we have to figure out if this is XML
381
- // log.info("Sniffing HTML " + xhr.resource + " for XHTML.")
382
-
383
- if (isXML(responseText)) {
384
- fetcher.addStatus(options.req, "Has an XML declaration. We'll assume " + "it's XHTML as the content-type was text/html.\n");
385
- var xhtmlHandler = new XHTMLHandler(this.response);
234
+ // Or it could be XHTML?
235
+ // Maybe it has an XHTML DOCTYPE?
236
+ if (dom.doctype) {
237
+ // log.info("We found a DOCTYPE in " + xhr.resource)
238
+ if (dom.doctype.name === 'html' && dom.doctype.publicId.match(/^-\/\/W3C\/\/DTD XHTML/) && dom.doctype.systemId.match(/http:\/\/www.w3.org\/TR\/xhtml/)) {
239
+ fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTML Handler.\n');
240
+ let xhtmlHandler = new XHTMLHandler(this.response, dom);
386
241
  return xhtmlHandler.parse(fetcher, responseText, options);
387
- } // DOCTYPE html
388
-
389
-
390
- if (isXHTML(responseText)) {
391
- fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTMLHandler.\n');
392
-
393
- var _xhtmlHandler2 = new XHTMLHandler(this.response);
394
-
395
- return _xhtmlHandler2.parse(fetcher, responseText, options);
396
- } // xmlns
397
-
398
-
399
- if (isXMLNS(responseText)) {
400
- fetcher.addStatus(options.req, 'Has default namespace for XHTML, so switching to XHTMLHandler.\n');
401
-
402
- var _xhtmlHandler3 = new XHTMLHandler(this.response);
403
-
404
- return _xhtmlHandler3.parse(fetcher, responseText, options);
405
- } // dc:title
406
- // no need to escape '/' here
407
-
408
-
409
- var titleMatch = new RegExp('<title>([\\s\\S]+?)</title>', 'im').exec(responseText);
410
-
411
- if (titleMatch) {
412
- kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(titleMatch[1]), options.resource); // think about xml:lang later
413
242
  }
414
-
415
- kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
416
- fetcher.addStatus(options.req, 'non-XML HTML document, not parsed for data.');
417
- return fetcher.doneFetch(options, this.response);
418
- }
419
- }], [{
420
- key: "toString",
421
- value: function toString() {
422
- return 'HTMLHandler';
423
- }
424
- }, {
425
- key: "register",
426
- value: function register(fetcher) {
427
- fetcher.mediatypes['text/html'] = {
428
- 'q': 0.9
429
- };
430
243
  }
431
- }]);
432
-
433
- return HTMLHandler;
434
- }(Handler);
435
-
436
- HTMLHandler.pattern = new RegExp('text/html');
437
-
438
- var JsonLdHandler = /*#__PURE__*/function (_Handler5) {
439
- _inherits(JsonLdHandler, _Handler5);
440
-
441
- var _super5 = _createSuper(JsonLdHandler);
442
-
443
- function JsonLdHandler() {
444
- _classCallCheck(this, JsonLdHandler);
445
244
 
446
- return _super5.apply(this, arguments);
447
- }
448
-
449
- _createClass(JsonLdHandler, [{
450
- key: "parse",
451
- value: function parse(fetcher, responseText, options, response) {
452
- var kb = fetcher.store;
453
- return new Promise(function (resolve, reject) {
454
- try {
455
- jsonldParser(responseText, kb, options.original.value, function () {
456
- resolve(fetcher.doneFetch(options, response));
457
- });
458
- } catch (err) {
459
- var msg = 'Error trying to parse ' + options.resource + ' as JSON-LD:\n' + err; // not err.stack -- irrelevant
460
-
461
- resolve(fetcher.failFetch(options, msg, 'parse_error', response));
462
- }
463
- });
464
- }
465
- }], [{
466
- key: "toString",
467
- value: function toString() {
468
- return 'JsonLdHandler';
469
- }
470
- }, {
471
- key: "register",
472
- value: function register(fetcher) {
473
- fetcher.mediatypes['application/ld+json'] = {
474
- 'q': 0.9
475
- };
245
+ // Or what about an XHTML namespace?
246
+ let html = dom.getElementsByTagName('html')[0];
247
+ if (html) {
248
+ let xmlns = html.getAttribute('xmlns');
249
+ if (xmlns && xmlns.match(/^http:\/\/www.w3.org\/1999\/xhtml/)) {
250
+ fetcher.addStatus(options.req, 'Has a default namespace for ' + 'XHTML. Switching to XHTMLHandler.\n');
251
+ let xhtmlHandler = new XHTMLHandler(this.response, dom);
252
+ return xhtmlHandler.parse(fetcher, responseText, options);
253
+ }
476
254
  }
477
- }]);
478
-
479
- return JsonLdHandler;
480
- }(Handler);
481
-
482
- JsonLdHandler.pattern = /application\/ld\+json/;
483
-
484
- var TextHandler = /*#__PURE__*/function (_Handler6) {
485
- _inherits(TextHandler, _Handler6);
486
-
487
- var _super6 = _createSuper(TextHandler);
488
-
489
- function TextHandler() {
490
- _classCallCheck(this, TextHandler);
491
255
 
492
- return _super6.apply(this, arguments);
256
+ // At this point we should check the namespace document (cache it!) and
257
+ // look for a GRDDL transform
258
+ // @@ Get namespace document <n>, parse it, look for <n> grddl:namespaceTransform ?y
259
+ // Apply ?y to dom
260
+ // We give up. What dialect is this?
261
+ return fetcher.failFetch(options, 'Unsupported dialect of XML: not RDF or XHTML namespace, etc.\n' + responseText.slice(0, 80), 901);
493
262
  }
263
+ }
264
+ XMLHandler.pattern = new RegExp('(text|application)/(.*)xml');
265
+ class HTMLHandler extends Handler {
266
+ static toString() {
267
+ return 'HTMLHandler';
268
+ }
269
+ static register(fetcher) {
270
+ fetcher.mediatypes['text/html'] = {
271
+ 'q': 0.9
272
+ };
273
+ }
274
+ parse(fetcher, responseText, options) {
275
+ let kb = fetcher.store;
494
276
 
495
- _createClass(TextHandler, [{
496
- key: "parse",
497
- value: function parse(fetcher, responseText, options) {
498
- // We only speak dialects of XML right now. Is this XML?
499
- // Look for an XML declaration
500
- if (isXML(responseText)) {
501
- fetcher.addStatus(options.req, 'Warning: ' + options.resource + " has an XML declaration. We'll assume " + "it's XML but its content-type wasn't XML.\n");
502
- var xmlHandler = new XMLHandler(this.response);
503
- return xmlHandler.parse(fetcher, responseText, options);
504
- } // Look for an XML declaration
505
-
506
-
507
- if (responseText.slice(0, 500).match(/xmlns:/)) {
508
- fetcher.addStatus(options.req, "May have an XML namespace. We'll assume " + "it's XML but its content-type wasn't XML.\n");
509
-
510
- var _xmlHandler = new XMLHandler(this.response);
511
-
512
- return _xmlHandler.parse(fetcher, responseText, options);
513
- } // We give up finding semantics - this is not an error, just no data
514
-
515
-
516
- fetcher.addStatus(options.req, 'Plain text document, no known RDF semantics.');
517
- return fetcher.doneFetch(options, this.response);
518
- }
519
- }], [{
520
- key: "toString",
521
- value: function toString() {
522
- return 'TextHandler';
523
- }
524
- }, {
525
- key: "register",
526
- value: function register(fetcher) {
527
- fetcher.mediatypes['text/plain'] = {
528
- 'q': 0.5
529
- };
277
+ // We only handle XHTML so we have to figure out if this is XML
278
+ // log.info("Sniffing HTML " + xhr.resource + " for XHTML.")
279
+ if (isXML(responseText)) {
280
+ fetcher.addStatus(options.req, "Has an XML declaration. We'll assume " + "it's XHTML as the content-type was text/html.\n");
281
+ let xhtmlHandler = new XHTMLHandler(this.response);
282
+ return xhtmlHandler.parse(fetcher, responseText, options);
530
283
  }
531
- }]);
532
-
533
- return TextHandler;
534
- }(Handler);
535
-
536
- TextHandler.pattern = new RegExp('text/plain');
537
284
 
538
- var N3Handler = /*#__PURE__*/function (_Handler7) {
539
- _inherits(N3Handler, _Handler7);
285
+ // DOCTYPE html
286
+ if (isXHTML(responseText)) {
287
+ fetcher.addStatus(options.req, 'Has XHTML DOCTYPE. Switching to XHTMLHandler.\n');
288
+ let xhtmlHandler = new XHTMLHandler(this.response);
289
+ return xhtmlHandler.parse(fetcher, responseText, options);
290
+ }
540
291
 
541
- var _super7 = _createSuper(N3Handler);
292
+ // xmlns
293
+ if (isXMLNS(responseText)) {
294
+ fetcher.addStatus(options.req, 'Has default namespace for XHTML, so switching to XHTMLHandler.\n');
295
+ let xhtmlHandler = new XHTMLHandler(this.response);
296
+ return xhtmlHandler.parse(fetcher, responseText, options);
297
+ }
542
298
 
543
- function N3Handler() {
544
- _classCallCheck(this, N3Handler);
299
+ // dc:title
300
+ // no need to escape '/' here
301
+ let titleMatch = new RegExp('<title>([\\s\\S]+?)</title>', 'im').exec(responseText);
302
+ if (titleMatch) {
303
+ kb.add(options.resource, ns.dc('title'), kb.rdfFactory.literal(titleMatch[1]), options.resource); // think about xml:lang later
304
+ }
545
305
 
546
- return _super7.apply(this, arguments);
306
+ kb.add(options.resource, ns.rdf('type'), ns.link('WebPage'), fetcher.appNode);
307
+ fetcher.addStatus(options.req, 'non-XML HTML document, not parsed for data.');
308
+ return fetcher.doneFetch(options, this.response);
547
309
  }
548
-
549
- _createClass(N3Handler, [{
550
- key: "parse",
551
- value: function parse(fetcher, responseText, options, response) {
552
- // Parse the text of this N3 file
553
- var kb = fetcher.store;
554
- var p = N3Parser(kb, kb, options.original.value, options.original.value, null, null, '', null); // p.loadBuf(xhr.responseText)
555
-
310
+ }
311
+ HTMLHandler.pattern = new RegExp('text/html');
312
+ class JsonLdHandler extends Handler {
313
+ static toString() {
314
+ return 'JsonLdHandler';
315
+ }
316
+ static register(fetcher) {
317
+ fetcher.mediatypes['application/ld+json'] = {
318
+ 'q': 0.9
319
+ };
320
+ }
321
+ parse(fetcher, responseText, options, response) {
322
+ const kb = fetcher.store;
323
+ return new Promise((resolve, reject) => {
556
324
  try {
557
- p.loadBuf(responseText);
325
+ jsonldParser(responseText, kb, options.original.value, () => {
326
+ resolve(fetcher.doneFetch(options, response));
327
+ });
558
328
  } catch (err) {
559
- var msg = 'Error trying to parse ' + options.resource + ' as Notation3:\n' + err; // not err.stack -- irrelevant
560
-
561
- return fetcher.failFetch(options, msg, 'parse_error', response);
329
+ const msg = 'Error trying to parse ' + options.resource + ' as JSON-LD:\n' + err; // not err.stack -- irrelevant
330
+ resolve(fetcher.failFetch(options, msg, 'parse_error', response));
562
331
  }
332
+ });
333
+ }
334
+ }
335
+ JsonLdHandler.pattern = /application\/ld\+json/;
336
+ class TextHandler extends Handler {
337
+ static toString() {
338
+ return 'TextHandler';
339
+ }
340
+ static register(fetcher) {
341
+ fetcher.mediatypes['text/plain'] = {
342
+ 'q': 0.5
343
+ };
344
+ }
345
+ parse(fetcher, responseText, options) {
346
+ // We only speak dialects of XML right now. Is this XML?
563
347
 
564
- fetcher.addStatus(options.req, 'N3 parsed: ' + p.statementCount + ' triples in ' + p.lines + ' lines.');
565
- fetcher.store.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
566
- return fetcher.doneFetch(options, this.response);
567
- }
568
- }], [{
569
- key: "toString",
570
- value: function toString() {
571
- return 'N3Handler';
348
+ // Look for an XML declaration
349
+ if (isXML(responseText)) {
350
+ fetcher.addStatus(options.req, 'Warning: ' + options.resource + " has an XML declaration. We'll assume " + "it's XML but its content-type wasn't XML.\n");
351
+ let xmlHandler = new XMLHandler(this.response);
352
+ return xmlHandler.parse(fetcher, responseText, options);
572
353
  }
573
- }, {
574
- key: "register",
575
- value: function register(fetcher) {
576
- fetcher.mediatypes['text/n3'] = {
577
- 'q': '1.0'
578
- }; // as per 2008 spec
579
-
580
- /*
581
- fetcher.mediatypes['application/x-turtle'] = {
582
- 'q': 1.0
583
- } // pre 2008
584
- */
585
354
 
586
- fetcher.mediatypes['text/turtle'] = {
587
- 'q': 1.0
588
- }; // post 2008
355
+ // Look for an XML declaration
356
+ if (responseText.slice(0, 500).match(/xmlns:/)) {
357
+ fetcher.addStatus(options.req, "May have an XML namespace. We'll assume " + "it's XML but its content-type wasn't XML.\n");
358
+ let xmlHandler = new XMLHandler(this.response);
359
+ return xmlHandler.parse(fetcher, responseText, options);
589
360
  }
590
- }]);
591
361
 
592
- return N3Handler;
593
- }(Handler);
362
+ // We give up finding semantics - this is not an error, just no data
363
+ fetcher.addStatus(options.req, 'Plain text document, no known RDF semantics.');
364
+ return fetcher.doneFetch(options, this.response);
365
+ }
366
+ }
367
+ TextHandler.pattern = new RegExp('text/plain');
368
+ class N3Handler extends Handler {
369
+ static toString() {
370
+ return 'N3Handler';
371
+ }
372
+ static register(fetcher) {
373
+ fetcher.mediatypes['text/n3'] = {
374
+ 'q': '1.0'
375
+ }; // as per 2008 spec
376
+ /*
377
+ fetcher.mediatypes['application/x-turtle'] = {
378
+ 'q': 1.0
379
+ } // pre 2008
380
+ */
381
+ fetcher.mediatypes['text/turtle'] = {
382
+ 'q': 1.0
383
+ }; // post 2008
384
+ }
594
385
 
386
+ parse(fetcher, responseText, options, response) {
387
+ // Parse the text of this N3 file
388
+ let kb = fetcher.store;
389
+ let p = N3Parser(kb, kb, options.original.value, options.original.value, null, null, '', null);
390
+ // p.loadBuf(xhr.responseText)
391
+ try {
392
+ p.loadBuf(responseText);
393
+ } catch (err) {
394
+ let msg = 'Error trying to parse ' + options.resource + ' as Notation3:\n' + err; // not err.stack -- irrelevant
395
+ return fetcher.failFetch(options, msg, 'parse_error', response);
396
+ }
397
+ fetcher.addStatus(options.req, 'N3 parsed: ' + p.statementCount + ' triples in ' + p.lines + ' lines.');
398
+ fetcher.store.add(options.original, ns.rdf('type'), ns.link('RDFDocument'), fetcher.appNode);
399
+ return fetcher.doneFetch(options, this.response);
400
+ }
401
+ }
595
402
  N3Handler.pattern = new RegExp('(application|text)/(x-)?(rdf\\+)?(n3|turtle)');
596
- var defaultHandlers = {
597
- RDFXMLHandler: RDFXMLHandler,
598
- XHTMLHandler: XHTMLHandler,
599
- XMLHandler: XMLHandler,
600
- HTMLHandler: HTMLHandler,
601
- TextHandler: TextHandler,
602
- N3Handler: N3Handler,
603
- JsonLdHandler: JsonLdHandler
403
+ const defaultHandlers = {
404
+ RDFXMLHandler,
405
+ XHTMLHandler,
406
+ XMLHandler,
407
+ HTMLHandler,
408
+ TextHandler,
409
+ N3Handler,
410
+ JsonLdHandler
604
411
  };
605
-
606
412
  function isXHTML(responseText) {
607
- var docTypeStart = responseText.indexOf('<!DOCTYPE html');
608
- var docTypeEnd = responseText.indexOf('>');
609
-
413
+ const docTypeStart = responseText.indexOf('<!DOCTYPE html');
414
+ const docTypeEnd = responseText.indexOf('>');
610
415
  if (docTypeStart === -1 || docTypeEnd === -1 || docTypeStart > docTypeEnd) {
611
416
  return false;
612
417
  }
613
-
614
418
  return responseText.substr(docTypeStart, docTypeEnd - docTypeStart).indexOf('XHTML') !== -1;
615
419
  }
616
-
617
420
  function isXML(responseText) {
618
- var match = responseText.match(/\s*<\?xml\s+version\s*=[^<>]+\?>/);
421
+ const match = responseText.match(/\s*<\?xml\s+version\s*=[^<>]+\?>/);
619
422
  return !!match;
620
423
  }
621
-
622
424
  function isXMLNS(responseText) {
623
- var match = responseText.match(/[^(<html)]*<html\s+[^<]*xmlns=['"]http:\/\/www.w3.org\/1999\/xhtml["'][^<]*>/);
425
+ const match = responseText.match(/[^(<html)]*<html\s+[^<]*xmlns=['"]http:\/\/www.w3.org\/1999\/xhtml["'][^<]*>/);
624
426
  return !!match;
625
427
  }
626
-
627
428
  /** Fetcher
628
429
  *
629
430
  * The Fetcher object is a helper object for a quadstore
@@ -632,7 +433,7 @@ function isXMLNS(responseText) {
632
433
  * figuring how to parse them. It will also refresh, remove, the data
633
434
  * and put back the data to the web.
634
435
  */
635
- var Fetcher = /*#__PURE__*/function () {
436
+ export default class Fetcher {
636
437
  /** Denoting this session */
637
438
 
638
439
  /**
@@ -656,59 +457,39 @@ var Fetcher = /*#__PURE__*/function () {
656
457
  /** fetchCallbacks[uri].push(callback) */
657
458
 
658
459
  /** Keep track of explicit 404s -> we can overwrite etc */
460
+
659
461
  // TODO: Document this
660
462
 
661
463
  /** Methods added by calling Util.callbackify in the constructor*/
662
- function Fetcher(store) {
663
- var _this = this;
664
-
665
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
666
-
667
- _classCallCheck(this, Fetcher);
668
464
 
465
+ constructor(store) {
466
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
669
467
  _defineProperty(this, "store", void 0);
670
-
671
468
  _defineProperty(this, "timeout", void 0);
672
-
673
469
  _defineProperty(this, "_fetch", void 0);
674
-
675
470
  _defineProperty(this, "mediatypes", void 0);
676
-
677
471
  _defineProperty(this, "appNode", void 0);
678
-
679
472
  _defineProperty(this, "requested", void 0);
680
-
681
473
  _defineProperty(this, "timeouts", void 0);
682
-
683
474
  _defineProperty(this, "redirectedTo", void 0);
684
-
685
475
  _defineProperty(this, "fetchQueue", void 0);
686
-
687
476
  _defineProperty(this, "fetchCallbacks", void 0);
688
-
689
477
  _defineProperty(this, "nonexistent", void 0);
690
-
691
478
  _defineProperty(this, "lookedUp", void 0);
692
-
693
479
  _defineProperty(this, "handlers", void 0);
694
-
695
480
  _defineProperty(this, "ns", void 0);
696
-
697
481
  _defineProperty(this, "fireCallbacks", void 0);
698
-
699
482
  this.store = store || new IndexedFormula();
700
483
  this.ns = getNS(this.store.rdfFactory);
701
- this.timeout = options.timeout || 30000; // solidFetcher is deprecated
484
+ this.timeout = options.timeout || 30000;
702
485
 
486
+ // solidFetcher is deprecated
703
487
  this._fetch = options.fetch || typeof global !== 'undefined' && (global.solidFetcher || global.solidFetch) || typeof window !== 'undefined' && (window.solidFetcher || window.solidFetch) || crossFetch;
704
-
705
488
  if (!this._fetch) {
706
489
  throw new Error('No _fetch function available for Fetcher');
707
490
  }
708
-
709
491
  this.appNode = this.store.rdfFactory.blankNode();
710
492
  this.store.fetcher = this; // Bi-linked
711
-
712
493
  this.requested = {};
713
494
  this.timeouts = {};
714
495
  this.redirectedTo = {};
@@ -724,258 +505,279 @@ var Fetcher = /*#__PURE__*/function () {
724
505
  '*/*': {
725
506
  'q': 0.1
726
507
  } // Must allow access to random content
508
+ };
727
509
 
728
- }; // Util.callbackify(this, ['request', 'recv', 'headers', 'load', 'fail',
510
+ // Util.callbackify(this, ['request', 'recv', 'headers', 'load', 'fail',
729
511
  // 'refresh', 'retract', 'done'])
730
512
  // In switching to fetch(), 'recv', 'headers' and 'load' do not make sense
731
-
732
513
  Util.callbackify(this, ['request', 'fail', 'refresh', 'retract', 'done']);
733
- Object.keys(options.handlers || defaultHandlers).map(function (key) {
734
- return _this.addHandler(defaultHandlers[key]);
735
- });
514
+ Object.keys(options.handlers || defaultHandlers).map(key => this.addHandler(defaultHandlers[key]));
736
515
  }
737
-
738
- _createClass(Fetcher, [{
739
- key: "load",
740
- value:
741
- /**
742
- * Promise-based load function
743
- *
744
- * Loads a web resource or resources into the store.
745
- *
746
- * A resource may be given as NamedNode object, or as a plain URI.
747
- * an array of resources will be given, in which they will be fetched in parallel.
748
- * By default, the HTTP headers are recorded also, in the same store, in a separate graph.
749
- * This allows code like editable() for example to test things about the resource.
750
- *
751
- * @param uri {Array<RDFlibNamedNode>|Array<string>|RDFlibNamedNode|string}
752
- *
753
- * @param [options={}] {Object}
754
- *
755
- * @param [options.fetch] {Function}
756
- *
757
- * @param [options.referringTerm] {RDFlibNamedNode} Referring term, the resource which
758
- * referred to this (for tracking bad links)
759
- *
760
- * @param [options.contentType] {string} Provided content type (for writes)
761
- *
762
- * @param [options.forceContentType] {string} Override the incoming header to
763
- * force the data to be treated as this content-type (for reads)
764
- *
765
- * @param [options.force] {boolean} Load the data even if loaded before.
766
- * Also sets the `Cache-Control:` header to `no-cache`
767
- *
768
- * @param [options.baseURI=docuri] {Node|string} Original uri to preserve
769
- * through proxying etc (`xhr.original`).
770
- *
771
- * @param [options.proxyUsed] {boolean} Whether this request is a retry via
772
- * a proxy (generally done from an error handler)
773
- *
774
- * @param [options.withCredentials] {boolean} flag for XHR/CORS etc
775
- *
776
- * @param [options.clearPreviousData] {boolean} Before we parse new data,
777
- * clear old, but only on status 200 responses
778
- *
779
- * @param [options.noMeta] {boolean} Prevents the addition of various metadata
780
- * triples (about the fetch request) to the store
781
- *
782
- * @param [options.noRDFa] {boolean}
783
- *
784
- * @returns {Promise<Result>}
785
- */
786
- function load(uri) {
787
- var _this2 = this;
788
-
789
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
790
- options = Object.assign({}, options); // Take a copy as we add stuff to the options!!
791
-
792
- if (uri instanceof Array) {
793
- return Promise.all(uri.map(function (x) {
794
- return _this2.load(x, Object.assign({}, options));
795
- }));
796
- }
797
-
798
- var uriIn = uri;
799
- var docuri = termValue(uriIn);
800
- docuri = docuri.split('#')[0];
801
- options = this.initFetchOptions(docuri, options);
802
- var initialisedOptions = this.initFetchOptions(docuri, options);
803
- return this.pendingFetchPromise(docuri, initialisedOptions.baseURI, initialisedOptions);
516
+ static crossSiteProxy(uri) {
517
+ if (Fetcher.crossSiteProxyTemplate) {
518
+ return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
519
+ } else {
520
+ return undefined;
804
521
  }
805
- }, {
806
- key: "pendingFetchPromise",
807
- value: function pendingFetchPromise(uri, originalUri, options) {
808
- var _this3 = this;
809
-
810
- var pendingPromise; // Check to see if some request is already dealing with this uri
811
-
812
- if (!options.force && this.fetchQueue[originalUri]) {
813
- pendingPromise = this.fetchQueue[originalUri];
522
+ }
523
+ static offlineOverride(uri) {
524
+ // Map the URI to a localhost proxy if we are running on localhost
525
+ // This is used for working offline, e.g. on planes.
526
+ // Is the script itself is running in localhost, then access all
527
+ // data in a localhost mirror.
528
+ // Do not remove without checking with TimBL
529
+ let requestedURI = uri;
530
+ var UI;
531
+ if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.preferences && UI.preferences.get('offlineModeUsingLocalhost')) {
532
+ if (requestedURI.slice(0, 7) === 'http://' && requestedURI.slice(7, 17) !== 'localhost/') {
533
+ requestedURI = 'http://localhost/' + requestedURI.slice(7);
534
+ log.warn('Localhost kludge for offline use: actually getting <' + requestedURI + '>');
814
535
  } else {
815
- pendingPromise = Promise.race([this.setRequestTimeout(uri, options), this.fetchUri(uri, options)]);
816
- this.fetchQueue[originalUri] = pendingPromise; // Clean up the queued promise after a time, if it's resolved
817
-
818
- this.cleanupFetchRequest(originalUri, undefined, this.timeout);
536
+ // log.warn("Localhost kludge NOT USED <" + requestedURI + ">")
819
537
  }
538
+ } else {
539
+ // log.warn("Localhost kludge OFF offline use: actually getting <" +
540
+ // requestedURI + ">")
541
+ }
542
+ return requestedURI;
543
+ }
544
+ static proxyIfNecessary(uri) {
545
+ var UI;
546
+ if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.isExtension) {
547
+ return uri;
548
+ } // Extension does not need proxy
820
549
 
821
- return pendingPromise.then(function (x) {
822
- if (uri in _this3.timeouts) {
823
- _this3.timeouts[uri].forEach(clearTimeout);
550
+ if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.localSiteMap) {
551
+ // nested dictionaries of URI parts from origin down
552
+ let hostpath = uri.split('/').slice(2); // the bit after the //
824
553
 
825
- delete _this3.timeouts[uri];
554
+ const lookup = (parts, index) => {
555
+ let z = index[parts.shift()];
556
+ if (!z) {
557
+ return null;
826
558
  }
827
-
828
- return x;
829
- });
830
- }
831
- /**
832
- * @param _options - DEPRECATED
833
- */
834
-
835
- }, {
836
- key: "cleanupFetchRequest",
837
- value: function cleanupFetchRequest(originalUri, _options, timeout) {
838
- var _this4 = this;
839
-
840
- if (_options !== undefined) {
841
- console.warn("_options is deprecated");
842
- }
843
-
844
- this.timeouts[originalUri] = (this.timeouts[originalUri] || []).concat(setTimeout(function () {
845
- if (!_this4.isPending(originalUri)) {
846
- delete _this4.fetchQueue[originalUri];
559
+ if (typeof z === 'string') {
560
+ return z + parts.join('/');
847
561
  }
848
- }, timeout));
849
- }
850
- }, {
851
- key: "initFetchOptions",
852
- value: function initFetchOptions(uri, options) {
853
- var kb = this.store;
854
- var isGet = !options.method || options.method.toUpperCase() === 'GET';
855
-
856
- if (!isGet) {
857
- options.force = true;
858
- }
859
-
860
- options.resource = kb.rdfFactory.namedNode(uri); // This might be proxified
861
-
862
- options.baseURI = options.baseURI || uri; // Preserve though proxying etc
863
-
864
- options.original = kb.rdfFactory.namedNode(options.baseURI);
865
- options.req = kb.bnode();
866
- options.headers = options.headers || new Headers();
867
-
868
- if (options.contentType) {
869
- // @ts-ignore
870
- options.headers['content-type'] = options.contentType;
871
- }
872
-
873
- if (options.force) {
874
- options.cache = 'no-cache';
875
- }
876
-
877
- var acceptString = this.acceptString(); // @ts-ignore
878
-
879
- options.headers['accept'] = acceptString;
880
- var requestedURI = Fetcher.offlineOverride(uri);
881
- options.requestedURI = requestedURI;
882
- Fetcher.setCredentials(requestedURI, options);
883
- var actualProxyURI = Fetcher.proxyIfNecessary(requestedURI);
884
-
885
- if (requestedURI !== actualProxyURI) {
886
- options.proxyUsed = true;
562
+ if (!parts) {
563
+ return null;
564
+ }
565
+ return lookup(parts, z);
566
+ };
567
+ const y = lookup(hostpath, $SolidTestEnvironment.localSiteMap);
568
+ if (y) {
569
+ return y;
887
570
  }
571
+ }
888
572
 
889
- options.actualProxyURI = actualProxyURI;
890
- return options;
573
+ // browser does 2014 on as https browser script not trusted
574
+ // If the web app origin is https: then the mixed content rules
575
+ // prevent it loading insecure http: stuff so we need proxy.
576
+ if (Fetcher.crossSiteProxyTemplate && typeof document !== 'undefined' && document.location && ('' + document.location).slice(0, 6) === 'https:' &&
577
+ // origin is secure
578
+ uri.slice(0, 5) === 'http:') {
579
+ // requested data is not
580
+ return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
891
581
  }
892
- /**
893
- * (The promise chain ends in either a `failFetch()` or a `doneFetch()`)
894
- *
895
- * @param docuri {string}
896
- * @param options {Object}
897
- *
898
- * @returns {Promise<Object>} fetch() result or an { error, status } object
899
- */
582
+ return uri;
583
+ }
900
584
 
901
- }, {
902
- key: "fetchUri",
903
- value: function fetchUri(docuri, options) {
904
- var _this5 = this;
585
+ /**
586
+ * Tests whether the uri's protocol is supported by the Fetcher.
587
+ * @param uri
588
+ */
589
+ static unsupportedProtocol(uri) {
590
+ let pcol = Uri.protocol(uri);
591
+ return pcol === 'tel' || pcol === 'mailto' || pcol === 'urn';
592
+ }
905
593
 
906
- if (!docuri) {
907
- return Promise.reject(new Error('Cannot fetch an empty uri'));
594
+ /** Decide on credentials using old XXHR api or new fetch() one
595
+ * @param requestedURI
596
+ * @param options
597
+ */
598
+ static setCredentials(requestedURI) {
599
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
600
+ // 2014 CORS problem:
601
+ // XMLHttpRequest cannot load http://www.w3.org/People/Berners-Lee/card.
602
+ // A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin'
603
+ // header when the credentials flag is true.
604
+ // @ Many ontology files under http: and need CORS wildcard ->
605
+ // can't have credentials
606
+ if (options.credentials === undefined) {
607
+ // Caller using new fetch convention
608
+ if (options.withCredentials !== undefined) {
609
+ // XHR style is what Fetcher specified before
610
+ options.credentials = options.withCredentials ? 'include' : 'omit';
611
+ } else {
612
+ options.credentials = 'include'; // default is to be logged on
908
613
  }
614
+ }
615
+ }
909
616
 
910
- if (Fetcher.unsupportedProtocol(docuri)) {
911
- return this.failFetch(options, 'fetcher: Unsupported protocol', 'unsupported_protocol');
617
+ /**
618
+ * Promise-based load function
619
+ *
620
+ * Loads a web resource or resources into the store.
621
+ *
622
+ * A resource may be given as NamedNode object, or as a plain URI.
623
+ * an array of resources will be given, in which they will be fetched in parallel.
624
+ * By default, the HTTP headers are recorded also, in the same store, in a separate graph.
625
+ * This allows code like editable() for example to test things about the resource.
626
+ *
627
+ * @param uri {Array<RDFlibNamedNode>|Array<string>|RDFlibNamedNode|string}
628
+ *
629
+ * @param [options={}] {Object}
630
+ *
631
+ * @param [options.fetch] {Function}
632
+ *
633
+ * @param [options.referringTerm] {RDFlibNamedNode} Referring term, the resource which
634
+ * referred to this (for tracking bad links)
635
+ *
636
+ * @param [options.contentType] {string} Provided content type (for writes)
637
+ *
638
+ * @param [options.forceContentType] {string} Override the incoming header to
639
+ * force the data to be treated as this content-type (for reads)
640
+ *
641
+ * @param [options.force] {boolean} Load the data even if loaded before.
642
+ * Also sets the `Cache-Control:` header to `no-cache`
643
+ *
644
+ * @param [options.baseURI=docuri] {Node|string} Original uri to preserve
645
+ * through proxying etc (`xhr.original`).
646
+ *
647
+ * @param [options.proxyUsed] {boolean} Whether this request is a retry via
648
+ * a proxy (generally done from an error handler)
649
+ *
650
+ * @param [options.withCredentials] {boolean} flag for XHR/CORS etc
651
+ *
652
+ * @param [options.clearPreviousData] {boolean} Before we parse new data,
653
+ * clear old, but only on status 200 responses
654
+ *
655
+ * @param [options.noMeta] {boolean} Prevents the addition of various metadata
656
+ * triples (about the fetch request) to the store
657
+ *
658
+ * @param [options.noRDFa] {boolean}
659
+ *
660
+ * @returns {Promise<Result>}
661
+ */
662
+ load(uri) {
663
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
664
+ options = Object.assign({}, options); // Take a copy as we add stuff to the options!!
665
+ if (uri instanceof Array) {
666
+ return Promise.all(uri.map(x => {
667
+ return this.load(x, Object.assign({}, options));
668
+ }));
669
+ }
670
+ const uriIn = uri;
671
+ let docuri = termValue(uriIn);
672
+ docuri = docuri.split('#')[0];
673
+ options = this.initFetchOptions(docuri, options);
674
+ const initialisedOptions = this.initFetchOptions(docuri, options);
675
+ return this.pendingFetchPromise(docuri, initialisedOptions.baseURI, initialisedOptions);
676
+ }
677
+ async pendingFetchPromise(uri, originalUri, options) {
678
+ let pendingPromise;
679
+
680
+ // Check to see if some request is already dealing with this uri
681
+ if (!options.force && (await this.fetchQueue[originalUri])) {
682
+ pendingPromise = this.fetchQueue[originalUri];
683
+ } else {
684
+ pendingPromise = Promise.race([this.setRequestTimeout(uri, options), this.fetchUri(uri, options)]);
685
+ this.fetchQueue[originalUri] = pendingPromise;
686
+
687
+ // Clean up the queued promise after a time, if it's resolved
688
+ this.cleanupFetchRequest(originalUri, undefined, this.timeout);
689
+ }
690
+ return pendingPromise.then(x => {
691
+ if (uri in this.timeouts) {
692
+ this.timeouts[uri].forEach(clearTimeout);
693
+ delete this.timeouts[uri];
912
694
  }
695
+ return x;
696
+ });
697
+ }
913
698
 
914
- var state = this.getState(docuri);
915
-
916
- if (!options.force) {
917
- if (state === 'fetched') {
918
- // URI already fetched and added to store
919
- return Promise.resolve( // @ts-ignore This is not a valid response object
920
- this.doneFetch(options, {
921
- status: 200,
922
- ok: true,
923
- statusText: 'Already loaded into quadstore.'
924
- }));
925
- }
926
-
927
- if (state === 'failed' && this.requested[docuri] === 404) {
928
- // Remember nonexistence
929
- var _message = 'Previously failed: ' + this.requested[docuri]; // @ts-ignore This is not a valid response object
930
-
931
-
932
- var dummyResponse = {
933
- url: docuri,
934
- // This does not comply to Fetch spec, it can be a string value in rdflib
935
- status: this.requested[docuri],
936
- statusText: _message,
937
- responseText: _message,
938
- headers: new Headers(),
939
- // Headers() ???
940
- ok: false,
941
- body: null,
942
- bodyUsed: false,
943
- size: 0,
944
- timeout: 0
945
- };
946
- return this.failFetch(options, _message, this.requested[docuri], dummyResponse);
947
- }
948
- } else {
949
- // options.force == true
950
- delete this.nonexistent[docuri];
699
+ /**
700
+ * @param _options - DEPRECATED
701
+ */
702
+ cleanupFetchRequest(originalUri, _options, timeout) {
703
+ if (_options !== undefined) {
704
+ console.warn("_options is deprecated");
705
+ }
706
+ this.timeouts[originalUri] = (this.timeouts[originalUri] || []).concat(setTimeout(() => {
707
+ if (!this.isPending(originalUri)) {
708
+ delete this.fetchQueue[originalUri];
951
709
  }
710
+ }, timeout));
711
+ }
712
+ initFetchOptions(uri, options) {
713
+ let kb = this.store;
714
+ let isGet = !options.method || options.method.toUpperCase() === 'GET';
715
+ if (!isGet) {
716
+ options.force = true;
717
+ }
718
+ options.resource = kb.rdfFactory.namedNode(uri); // This might be proxified
719
+ options.baseURI = options.baseURI || uri; // Preserve though proxying etc
720
+ options.original = kb.rdfFactory.namedNode(options.baseURI);
721
+ options.req = kb.bnode();
722
+ options.headers = options.headers || new Headers();
723
+ if (options.contentType) {
724
+ // @ts-ignore
725
+ options.headers['content-type'] = options.contentType;
726
+ }
727
+ if (options.force) {
728
+ options.cache = 'no-cache';
729
+ }
730
+ let acceptString = this.acceptString();
731
+ // @ts-ignore
732
+ options.headers['accept'] = acceptString;
733
+ let requestedURI = Fetcher.offlineOverride(uri);
734
+ options.requestedURI = requestedURI;
735
+ Fetcher.setCredentials(requestedURI, options);
736
+ let actualProxyURI = Fetcher.proxyIfNecessary(requestedURI);
737
+ if (requestedURI !== actualProxyURI) {
738
+ options.proxyUsed = true;
739
+ }
740
+ options.actualProxyURI = actualProxyURI;
741
+ return options;
742
+ }
952
743
 
953
- this.fireCallbacks('request', [docuri]);
954
- this.requested[docuri] = true; // mark this uri as 'requested'
955
-
956
- if (!options.noMeta) {
957
- this.saveRequestMetadata(docuri, options);
744
+ /**
745
+ * (The promise chain ends in either a `failFetch()` or a `doneFetch()`)
746
+ *
747
+ * @param docuri {string}
748
+ * @param options {Object}
749
+ *
750
+ * @returns {Promise<Object>} fetch() result or an { error, status } object
751
+ */
752
+ fetchUri(docuri, options) {
753
+ if (!docuri) {
754
+ return Promise.reject(new Error('Cannot fetch an empty uri'));
755
+ }
756
+ if (Fetcher.unsupportedProtocol(docuri)) {
757
+ return this.failFetch(options, 'fetcher: Unsupported protocol', 'unsupported_protocol');
758
+ }
759
+ let state = this.getState(docuri);
760
+ if (!options.force) {
761
+ if (state === 'fetched') {
762
+ // URI already fetched and added to store
763
+ return Promise.resolve(
764
+ // @ts-ignore This is not a valid response object
765
+ this.doneFetch(options, {
766
+ status: 200,
767
+ ok: true,
768
+ statusText: 'Already loaded into quadstore.'
769
+ }));
958
770
  }
959
-
960
- var actualProxyURI = options.actualProxyURI; // Map might get mistakenly added into headers
961
- // error TS2339: Property 'map' does not exist on type 'Headers'.
962
-
963
- /* let map
964
- if (options.headers && map in options.headers) {
965
- delete options.headers.map
966
- } */
967
-
968
- return this._fetch(actualProxyURI, options).then(function (response) {
969
- return _this5.handleResponse(response, docuri, options);
970
- }, function (error) {
971
- // @@ handleError?
972
- // @ts-ignore Invalid response object
973
- var dummyResponse = {
974
- url: actualProxyURI,
975
- status: 999,
976
- // @@ what number/string should fetch failures report?
977
- statusText: (error.name || 'network failure') + ': ' + (error.errno || error.code || error.type),
978
- responseText: error.message,
771
+ if (state === 'failed' && this.requested[docuri] === 404) {
772
+ // Remember nonexistence
773
+ let message = 'Previously failed: ' + this.requested[docuri];
774
+ // @ts-ignore This is not a valid response object
775
+ let dummyResponse = {
776
+ url: docuri,
777
+ // This does not comply to Fetch spec, it can be a string value in rdflib
778
+ status: this.requested[docuri],
779
+ statusText: message,
780
+ responseText: message,
979
781
  headers: new Headers(),
980
782
  // Headers() ???
981
783
  ok: false,
@@ -984,1203 +786,888 @@ var Fetcher = /*#__PURE__*/function () {
984
786
  size: 0,
985
787
  timeout: 0
986
788
  };
987
- console.log('Fetcher: <' + actualProxyURI + '> Non-HTTP fetch exception: ' + error);
988
- return _this5.handleError(dummyResponse, docuri, options); // possible credentials retry
989
- // return this.failFetch(options, 'fetch failed: ' + error, 999, dummyResponse) // Fake status code: fetch exception
990
- // handleError expects a response so we fake some important bits.
991
-
992
- /*
993
- this.handleError(, docuri, options)
994
- */
995
- });
996
- }
997
- /**
998
- * Asks for a doc to be loaded if necessary then calls back
999
- *
1000
- * Calling methods:
1001
- * nowOrWhenFetched (uri, userCallback)
1002
- * nowOrWhenFetched (uri, options, userCallback)
1003
- * nowOrWhenFetched (uri, referringTerm, userCallback, options) <-- old
1004
- * nowOrWhenFetched (uri, referringTerm, userCallback) <-- old
1005
- *
1006
- * Options include:
1007
- * referringTerm The document in which this link was found.
1008
- * this is valuable when finding the source of bad URIs
1009
- * force boolean. Never mind whether you have tried before,
1010
- * load this from scratch.
1011
- * forceContentType Override the incoming header to force the data to be
1012
- * treated as this content-type.
1013
- *
1014
- * Callback function takes:
1015
- *
1016
- * ok True if the fetch worked, and got a 200 response.
1017
- * False if any error happened
1018
- *
1019
- * errmessage Text error message if not OK.
1020
- *
1021
- * response The fetch Response object (was: XHR) if there was was one
1022
- * includes response.status as the HTTP status if any.
1023
- */
1024
-
1025
- }, {
1026
- key: "nowOrWhenFetched",
1027
- value: function nowOrWhenFetched(uriIn, p2, userCallback) {
1028
- var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1029
- var uri = termValue(uriIn);
1030
-
1031
- if (typeof p2 === 'function') {
1032
- // nowOrWhenFetched (uri, userCallback)
1033
- userCallback = p2;
1034
- } else if (typeof p2 === 'undefined') {// original calling signature
1035
- // referringTerm = undefined
1036
- } else if (isNamedNode(p2)) {
1037
- // referringTerm = p2
1038
- options.referringTerm = p2;
1039
- } else {
1040
- // nowOrWhenFetched (uri, options, userCallback)
1041
- options = p2;
789
+ return this.failFetch(options, message, this.requested[docuri], dummyResponse);
1042
790
  }
791
+ } else {
792
+ // options.force == true
793
+ delete this.nonexistent[docuri];
794
+ }
795
+ this.fireCallbacks('request', [docuri]);
796
+ this.requested[docuri] = true; // mark this uri as 'requested'
797
+
798
+ if (!options.noMeta) {
799
+ this.saveRequestMetadata(docuri, options);
800
+ }
801
+ let {
802
+ actualProxyURI
803
+ } = options;
804
+
805
+ // Map might get mistakenly added into headers
806
+ // error TS2339: Property 'map' does not exist on type 'Headers'.
807
+ /* let map
808
+ if (options.headers && map in options.headers) {
809
+ delete options.headers.map
810
+ } */
811
+
812
+ return this._fetch(actualProxyURI, options).then(response => this.handleResponse(response, docuri, options), error => {
813
+ // @@ handleError?
814
+ // @ts-ignore Invalid response object
815
+ let dummyResponse = {
816
+ url: actualProxyURI,
817
+ status: 999,
818
+ // @@ what number/string should fetch failures report?
819
+ statusText: (error.name || 'network failure') + ': ' + (error.errno || error.code || error.type),
820
+ responseText: error.message,
821
+ headers: new Headers(),
822
+ // Headers() ???
823
+ ok: false,
824
+ body: null,
825
+ bodyUsed: false,
826
+ size: 0,
827
+ timeout: 0
828
+ };
829
+ console.log('Fetcher: <' + actualProxyURI + '> Non-HTTP fetch exception: ' + error);
830
+ return this.handleError(dummyResponse, docuri, options); // possible credentials retry
831
+ // return this.failFetch(options, 'fetch failed: ' + error, 999, dummyResponse) // Fake status code: fetch exception
1043
832
 
1044
- this.load(uri, options).then(function (fetchResponse) {
1045
- if (userCallback) {
1046
- if (fetchResponse) {
1047
- if (fetchResponse.ok) {
1048
- userCallback(true, 'OK', fetchResponse);
1049
- } else {
1050
- // console.log('@@@ fetcher.js Should not take this path !!!!!!!!!!!!')
1051
- var oops = 'HTTP error: Status ' + fetchResponse.status + ' (' + fetchResponse.statusText + ')';
1052
-
1053
- if (fetchResponse.responseText) {
1054
- oops += ' ' + fetchResponse.responseText; // not in 404, dns error, nock failure
1055
- }
1056
-
1057
- console.log(oops + ' fetching ' + uri);
1058
- userCallback(false, oops, fetchResponse);
1059
- }
833
+ // handleError expects a response so we fake some important bits.
834
+ /*
835
+ this.handleError(, docuri, options)
836
+ */
837
+ });
838
+ }
839
+
840
+ /**
841
+ * Asks for a doc to be loaded if necessary then calls back
842
+ *
843
+ * Calling methods:
844
+ * nowOrWhenFetched (uri, userCallback)
845
+ * nowOrWhenFetched (uri, options, userCallback)
846
+ * nowOrWhenFetched (uri, referringTerm, userCallback, options) <-- old
847
+ * nowOrWhenFetched (uri, referringTerm, userCallback) <-- old
848
+ *
849
+ * Options include:
850
+ * referringTerm The document in which this link was found.
851
+ * this is valuable when finding the source of bad URIs
852
+ * force boolean. Never mind whether you have tried before,
853
+ * load this from scratch.
854
+ * forceContentType Override the incoming header to force the data to be
855
+ * treated as this content-type.
856
+ *
857
+ * Callback function takes:
858
+ *
859
+ * ok True if the fetch worked, and got a 200 response.
860
+ * False if any error happened
861
+ *
862
+ * errmessage Text error message if not OK.
863
+ *
864
+ * response The fetch Response object (was: XHR) if there was was one
865
+ * includes response.status as the HTTP status if any.
866
+ */
867
+ nowOrWhenFetched(uriIn, p2, userCallback) {
868
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
869
+ const uri = termValue(uriIn);
870
+ if (typeof p2 === 'function') {
871
+ // nowOrWhenFetched (uri, userCallback)
872
+ userCallback = p2;
873
+ } else if (typeof p2 === 'undefined') {// original calling signature
874
+ // referringTerm = undefined
875
+ } else if (isNamedNode(p2)) {
876
+ // referringTerm = p2
877
+ options.referringTerm = p2;
878
+ } else {
879
+ // nowOrWhenFetched (uri, options, userCallback)
880
+ options = p2;
881
+ }
882
+ this.load(uri, options).then(fetchResponse => {
883
+ if (userCallback) {
884
+ if (fetchResponse) {
885
+ if (fetchResponse.ok) {
886
+ userCallback(true, 'OK', fetchResponse);
1060
887
  } else {
1061
- var _oops = '@@ nowOrWhenFetched: no response object!';
1062
- console.log(_oops);
1063
- userCallback(false, _oops);
1064
- }
1065
- }
1066
- }, function (err) {
1067
- var message = err.message || err.statusText;
1068
- message = 'Failed to load <' + uri + '> ' + message;
1069
- console.log(message);
888
+ // console.log('@@@ fetcher.js Should not take this path !!!!!!!!!!!!')
889
+ let oops = 'HTTP error: Status ' + fetchResponse.status + ' (' + fetchResponse.statusText + ')';
890
+ if (fetchResponse.responseText) {
891
+ oops += ' ' + fetchResponse.responseText; // not in 404, dns error, nock failure
892
+ }
1070
893
 
1071
- if (err.response && err.response.status) {
1072
- message += ' status: ' + err.response.status;
894
+ console.log(oops + ' fetching ' + uri);
895
+ userCallback(false, oops, fetchResponse);
896
+ }
897
+ } else {
898
+ let oops = '@@ nowOrWhenFetched: no response object!';
899
+ console.log(oops);
900
+ userCallback(false, oops);
1073
901
  }
902
+ }
903
+ }, function (err) {
904
+ var message = err.message || err.statusText;
905
+ message = 'Failed to load <' + uri + '> ' + message;
906
+ console.log(message);
907
+ if (err.response && err.response.status) {
908
+ message += ' status: ' + err.response.status;
909
+ }
910
+ userCallback(false, message, err.response);
911
+ });
912
+ }
1074
913
 
1075
- userCallback(false, message, err.response);
1076
- });
914
+ /**
915
+ * Records a status message (as a literal node) by appending it to the
916
+ * request's metadata status collection.
917
+ *
918
+ */
919
+ addStatus(req, statusMessage) {
920
+ // <Debug about="parsePerformance">
921
+ let now = new Date();
922
+ statusMessage = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '.' + now.getMilliseconds() + '] ' + statusMessage;
923
+ // </Debug>
924
+ let kb = this.store;
925
+ const statusNode = kb.the(req, this.ns.link('status'));
926
+ if (isCollection(statusNode)) {
927
+ statusNode.append(kb.rdfFactory.literal(statusMessage));
928
+ } else {
929
+ log.warn('web.js: No list to add to: ' + statusNode + ',' + statusMessage);
1077
930
  }
1078
- /**
1079
- * Records a status message (as a literal node) by appending it to the
1080
- * request's metadata status collection.
1081
- *
1082
- */
1083
-
1084
- }, {
1085
- key: "addStatus",
1086
- value: function addStatus(req, statusMessage) {
1087
- // <Debug about="parsePerformance">
1088
- var now = new Date();
1089
- statusMessage = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '.' + now.getMilliseconds() + '] ' + statusMessage; // </Debug>
1090
-
1091
- var kb = this.store;
1092
- var statusNode = kb.the(req, this.ns.link('status'));
931
+ }
1093
932
 
1094
- if (isCollection(statusNode)) {
1095
- statusNode.append(kb.rdfFactory.literal(statusMessage));
933
+ /**
934
+ * Records errors in the system on failure:
935
+ *
936
+ * - Adds an entry to the request status collection
937
+ * - Adds an error triple with the fail message to the metadata
938
+ * - Fires the 'fail' callback
939
+ * - Rejects with an error result object, which has a response object if any
940
+ */
941
+ failFetch(options, errorMessage, statusCode, response) {
942
+ this.addStatus(options.req, errorMessage);
943
+ if (!options.noMeta) {
944
+ this.store.add(options.original, this.ns.link('error'), this.store.rdfFactory.literal(errorMessage));
945
+ }
946
+ let meth = (options.method || 'GET').toUpperCase();
947
+ let isGet = meth === 'GET' || meth === 'HEAD';
948
+ if (isGet) {
949
+ // only cache the status code on GET or HEAD
950
+ if (!options.resource.equals(options.original)) {
951
+ // console.log('@@ Recording failure ' + meth + ' original ' + options.original +option '( as ' + options.resource + ') : ' + statusCode)
1096
952
  } else {
1097
- log.warn('web.js: No list to add to: ' + statusNode + ',' + statusMessage);
953
+ // console.log('@@ Recording ' + meth + ' failure for ' + options.original + ': ' + statusCode)
1098
954
  }
955
+ this.requested[Uri.docpart(options.original.value)] = statusCode;
956
+ this.fireCallbacks('fail', [options.original.value, errorMessage]);
1099
957
  }
1100
- /**
1101
- * Records errors in the system on failure:
1102
- *
1103
- * - Adds an entry to the request status collection
1104
- * - Adds an error triple with the fail message to the metadata
1105
- * - Fires the 'fail' callback
1106
- * - Rejects with an error result object, which has a response object if any
1107
- */
1108
-
1109
- }, {
1110
- key: "failFetch",
1111
- value: function failFetch(options, errorMessage, statusCode, response) {
1112
- this.addStatus(options.req, errorMessage);
1113
-
1114
- if (!options.noMeta) {
1115
- this.store.add(options.original, this.ns.link('error'), this.store.rdfFactory.literal(errorMessage));
1116
- }
1117
-
1118
- var meth = (options.method || 'GET').toUpperCase();
1119
- var isGet = meth === 'GET' || meth === 'HEAD';
958
+ var err = new Error('Fetcher: ' + errorMessage);
1120
959
 
1121
- if (isGet) {
1122
- // only cache the status code on GET or HEAD
1123
- if (!options.resource.equals(options.original)) {// console.log('@@ Recording failure ' + meth + ' original ' + options.original +option '( as ' + options.resource + ') : ' + statusCode)
1124
- } else {// console.log('@@ Recording ' + meth + ' failure for ' + options.original + ': ' + statusCode)
1125
- }
1126
-
1127
- this.requested[Uri.docpart(options.original.value)] = statusCode;
1128
- this.fireCallbacks('fail', [options.original.value, errorMessage]);
1129
- }
1130
-
1131
- var err = new Error('Fetcher: ' + errorMessage); // err.ok = false // Is taken as a response, will work too @@ phase out?
1132
-
1133
- err.status = statusCode;
1134
- err.statusText = errorMessage;
1135
- err.response = response;
1136
- return Promise.reject(err);
1137
- } // in the why part of the quad distinguish between HTML and HTTP header
1138
- // Reverse is set iif the link was rev= as opposed to rel=
1139
-
1140
- }, {
1141
- key: "linkData",
1142
- value: function linkData(originalUri, rel, uri, why, reverse) {
1143
- if (!uri) return;
1144
- var kb = this.store;
1145
- var predicate; // See http://www.w3.org/TR/powder-dr/#httplink for describedby 2008-12-10
1146
-
1147
- var obj = kb.rdfFactory.namedNode(Uri.join(uri, originalUri.value));
1148
-
1149
- if (rel === 'alternate' || rel === 'seeAlso' || rel === 'meta' || rel === 'describedby') {
1150
- if (obj.value === originalUri.value) {
1151
- return;
1152
- }
1153
-
1154
- predicate = this.ns.rdfs('seeAlso');
1155
- } else if (rel === 'type') {
1156
- predicate = kb.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
1157
- } else {
1158
- // See https://www.iana.org/assignments/link-relations/link-relations.xml
1159
- // Alas not yet in RDF yet for each predicate
1160
- // encode space in e.g. rel="shortcut icon"
1161
- predicate = kb.rdfFactory.namedNode(Uri.join(encodeURIComponent(rel), 'http://www.iana.org/assignments/link-relations/'));
1162
- }
960
+ // err.ok = false // Is taken as a response, will work too @@ phase out?
961
+ err.status = statusCode;
962
+ err.statusText = errorMessage;
963
+ err.response = response;
964
+ return Promise.reject(err);
965
+ }
1163
966
 
1164
- if (reverse) {
1165
- kb.add(obj, predicate, originalUri, why);
1166
- } else {
1167
- kb.add(originalUri, predicate, obj, why);
967
+ // in the why part of the quad distinguish between HTML and HTTP header
968
+ // Reverse is set iif the link was rev= as opposed to rel=
969
+ linkData(originalUri, rel, uri, why, reverse) {
970
+ if (!uri) return;
971
+ let kb = this.store;
972
+ let predicate;
973
+ // See http://www.w3.org/TR/powder-dr/#httplink for describedby 2008-12-10
974
+ let obj = kb.rdfFactory.namedNode(Uri.join(uri, originalUri.value));
975
+ if (rel === 'alternate' || rel === 'seeAlso' || rel === 'meta' || rel === 'describedby') {
976
+ if (obj.value === originalUri.value) {
977
+ return;
1168
978
  }
979
+ predicate = this.ns.rdfs('seeAlso');
980
+ } else if (rel === 'type') {
981
+ predicate = kb.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type');
982
+ } else {
983
+ // See https://www.iana.org/assignments/link-relations/link-relations.xml
984
+ // Alas not yet in RDF yet for each predicate
985
+ // encode space in e.g. rel="shortcut icon"
986
+ predicate = kb.rdfFactory.namedNode(Uri.join(encodeURIComponent(rel), 'http://www.iana.org/assignments/link-relations/'));
987
+ }
988
+ if (reverse) {
989
+ kb.add(obj, predicate, originalUri, why);
990
+ } else {
991
+ kb.add(originalUri, predicate, obj, why);
1169
992
  }
1170
- }, {
1171
- key: "parseLinkHeader",
1172
- value: function parseLinkHeader(linkHeader, originalUri, reqNode) {
1173
- if (!linkHeader) {
1174
- return;
1175
- } // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*")))*(,|$)/g
1176
- // const paramexp = /[^()<>@,;:"/[]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*"))/g
1177
- // From https://www.dcode.fr/regular-expression-simplificator:
1178
- // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} t]+=["]))*[,$]/g
1179
- // const paramexp = /[^\\<>@,;:"\/\[\]?={} \t]+=["])/g
1180
- // Original:
1181
-
1182
-
1183
- var linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
1184
- var paramexp = /[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
1185
- var matches = linkHeader.match(linkexp);
1186
- if (matches == null) return;
1187
-
1188
- for (var i = 0; i < matches.length; i++) {
1189
- var split = matches[i].split('>');
1190
- var href = split[0].substring(1);
1191
- var ps = split[1];
1192
- var s = ps.match(paramexp);
1193
- if (s == null) return;
1194
-
1195
- for (var j = 0; j < s.length; j++) {
1196
- var p = s[j];
1197
- var paramsplit = p.split('='); // var name = paramsplit[0]
1198
-
1199
- var rel = paramsplit[1].replace(/["']/g, ''); // '"
1200
-
1201
- this.linkData(originalUri, rel, href, reqNode);
1202
- }
993
+ }
994
+ parseLinkHeader(linkHeader, originalUri, reqNode) {
995
+ if (!linkHeader) {
996
+ return;
997
+ }
998
+
999
+ // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*")))*(,|$)/g
1000
+ // const paramexp = /[^()<>@,;:"/[]?={} \t]+=(([^()<>@,;:"/[]?={} \t]+)|("[^"]*"))/g
1001
+
1002
+ // From https://www.dcode.fr/regular-expression-simplificator:
1003
+ // const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} t]+=["]))*[,$]/g
1004
+ // const paramexp = /[^\\<>@,;:"\/\[\]?={} \t]+=["])/g
1005
+ // Original:
1006
+ const linkexp = /<[^>]*>\s*(\s*;\s*[^()<>@,;:"/[\]?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*")))*(,|$)/g;
1007
+ const paramexp = /[^\(\)<>@,;:"\/\[\]\?={} \t]+=(([^\(\)<>@,;:"\/\[\]\?={} \t]+)|("[^"]*"))/g;
1008
+ const matches = linkHeader.match(linkexp);
1009
+ if (matches == null) return;
1010
+ for (let i = 0; i < matches.length; i++) {
1011
+ let split = matches[i].split('>');
1012
+ let href = split[0].substring(1);
1013
+ let ps = split[1];
1014
+ let s = ps.match(paramexp);
1015
+ if (s == null) return;
1016
+ for (let j = 0; j < s.length; j++) {
1017
+ let p = s[j];
1018
+ let paramsplit = p.split('=');
1019
+ // var name = paramsplit[0]
1020
+ let rel = paramsplit[1].replace(/["']/g, ''); // '"
1021
+ this.linkData(originalUri, rel, href, reqNode);
1203
1022
  }
1204
1023
  }
1205
- }, {
1206
- key: "doneFetch",
1207
- value: function doneFetch(options, response) {
1208
- this.addStatus(options.req, 'Done.');
1209
- this.requested[options.original.value] = 'done';
1210
- this.fireCallbacks('done', [options.original.value]);
1211
- response.req = options.req; // Set the request meta blank node
1024
+ }
1025
+ doneFetch(options, response) {
1026
+ this.addStatus(options.req, 'Done.');
1027
+ this.requested[options.original.value] = 'done';
1028
+ this.fireCallbacks('done', [options.original.value]);
1029
+ response.req = options.req; // Set the request meta blank node
1212
1030
 
1213
- return response;
1214
- }
1215
- /**
1216
- * Note two nodes are now smushed
1217
- * If only one was flagged as looked up, then the new node is looked up again,
1218
- * which will make sure all the URIs are dereferenced
1219
- */
1031
+ return response;
1032
+ }
1220
1033
 
1221
- }, {
1222
- key: "nowKnownAs",
1223
- value: function nowKnownAs(was, now) {
1224
- if (this.lookedUp[was.value]) {
1225
- // Transfer userCallback
1226
- if (!this.lookedUp[now.value]) {
1227
- this.lookUpThing(now, was);
1228
- }
1229
- } else if (this.lookedUp[now.value]) {
1230
- if (!this.lookedUp[was.value]) {
1231
- this.lookUpThing(was, now);
1232
- }
1034
+ /**
1035
+ * Note two nodes are now smushed
1036
+ * If only one was flagged as looked up, then the new node is looked up again,
1037
+ * which will make sure all the URIs are dereferenced
1038
+ */
1039
+ nowKnownAs(was, now) {
1040
+ if (this.lookedUp[was.value]) {
1041
+ // Transfer userCallback
1042
+ if (!this.lookedUp[now.value]) {
1043
+ this.lookUpThing(now, was);
1233
1044
  }
1234
- }
1235
- /**
1236
- * Writes back to the web what we have in the store for this uri
1237
- */
1238
-
1239
- }, {
1240
- key: "putBack",
1241
- value: function putBack(uri) {
1242
- var _this6 = this;
1243
-
1244
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1245
- var uriSting = termValue(uri);
1246
- var doc = new RDFlibNamedNode(uriSting).doc(); // strip off #
1247
-
1248
- options.contentType = options["content-type"] || options["Content-Type"] || options.contentType || TurtleContentType;
1249
-
1250
- if (options.contentType === 'application/ld+json') {
1251
- return new Promise(function (resolve, reject) {
1252
- serialize(doc, _this6.store, doc.uri, options.contentType, function (err, jsonString) {
1253
- if (err) {
1254
- reject(err);
1255
- } else {
1256
- // @ts-ignore
1257
- options.data = jsonString;
1258
-
1259
- _this6.webOperation('PUT', uri, options).then(function (res) {
1260
- return resolve(res);
1261
- }).catch(function (error) {
1262
- return reject(error);
1263
- });
1264
- }
1265
- });
1266
- });
1045
+ } else if (this.lookedUp[now.value]) {
1046
+ if (!this.lookedUp[was.value]) {
1047
+ this.lookUpThing(was, now);
1267
1048
  }
1268
-
1269
- options.data = serialize(doc, this.store, doc.value, options.contentType);
1270
- return this.webOperation('PUT', uriSting, options);
1271
1049
  }
1272
- }, {
1273
- key: "webCopy",
1274
- value: function webCopy(here, there, contentType) {
1275
- var _this7 = this;
1050
+ }
1276
1051
 
1277
- return this.webOperation('GET', here).then(function (result) {
1278
- return _this7.webOperation('PUT', // change to binary from text
1279
- there, {
1280
- data: result.responseText,
1281
- contentType: contentType
1052
+ /**
1053
+ * Writes back to the web what we have in the store for this uri
1054
+ */
1055
+ putBack(uri) {
1056
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1057
+ const uriSting = termValue(uri);
1058
+ let doc = new RDFlibNamedNode(uriSting).doc(); // strip off #
1059
+ options.contentType = options["content-type"] || options["Content-Type"] || options.contentType || TurtleContentType;
1060
+ if (options.contentType === 'application/ld+json') {
1061
+ return new Promise((resolve, reject) => {
1062
+ serialize(doc, this.store, doc.uri, options.contentType, (err, jsonString) => {
1063
+ if (err) {
1064
+ reject(err);
1065
+ } else {
1066
+ // @ts-ignore
1067
+ options.data = jsonString;
1068
+ this.webOperation('PUT', uri, options).then(res => resolve(res)).catch(error => reject(error));
1069
+ }
1282
1070
  });
1283
1071
  });
1284
1072
  }
1285
- }, {
1286
- key: "delete",
1287
- value: function _delete(uri, options) {
1288
- var _this8 = this;
1289
-
1290
- return this.webOperation('DELETE', uri, options).then(function (response) {
1291
- _this8.requested[uri] = 404;
1292
- _this8.nonexistent[uri] = true;
1293
-
1294
- _this8.unload(_this8.store.rdfFactory.namedNode(uri));
1295
-
1296
- return response;
1073
+ options.data = serialize(doc, this.store, doc.value, options.contentType);
1074
+ return this.webOperation('PUT', uriSting, options);
1075
+ }
1076
+ webCopy(here, there, contentType) {
1077
+ return this.webOperation('GET', here).then(result => {
1078
+ return this.webOperation('PUT',
1079
+ // change to binary from text
1080
+ there, {
1081
+ data: result.responseText,
1082
+ contentType
1297
1083
  });
1298
- }
1299
- /** Create an empty resource if it really does not exist
1300
- * Be absolutely sure something does not exist before creating a new empty file
1301
- * as otherwise existing could be deleted.
1302
- * @param doc - The resource
1303
- */
1304
-
1305
- }, {
1306
- key: "createIfNotExists",
1307
- value: function () {
1308
- var _createIfNotExists = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(doc) {
1309
- var contentType,
1310
- data,
1311
- fetcher,
1312
- response,
1313
- _args = arguments;
1314
- return _regeneratorRuntime.wrap(function _callee$(_context) {
1315
- while (1) {
1316
- switch (_context.prev = _context.next) {
1317
- case 0:
1318
- contentType = _args.length > 1 && _args[1] !== undefined ? _args[1] : TurtleContentType;
1319
- data = _args.length > 2 && _args[2] !== undefined ? _args[2] : '';
1320
- fetcher = this;
1321
- _context.prev = 3;
1322
- _context.next = 6;
1323
- return fetcher.load(doc);
1324
-
1325
- case 6:
1326
- response = _context.sent;
1327
- _context.next = 29;
1328
- break;
1329
-
1330
- case 9:
1331
- _context.prev = 9;
1332
- _context.t0 = _context["catch"](3);
1333
-
1334
- if (!(_context.t0.response.status === 404)) {
1335
- _context.next = 27;
1336
- break;
1337
- }
1338
-
1339
- console.log('createIfNotExists: doc does NOT exist, will create... ' + doc);
1340
- _context.prev = 13;
1341
- _context.next = 16;
1342
- return fetcher.webOperation('PUT', doc.value, {
1343
- data: data,
1344
- contentType: contentType
1345
- });
1346
-
1347
- case 16:
1348
- response = _context.sent;
1349
- _context.next = 23;
1350
- break;
1351
-
1352
- case 19:
1353
- _context.prev = 19;
1354
- _context.t1 = _context["catch"](13);
1355
- console.log('createIfNotExists doc FAILED: ' + doc + ': ' + _context.t1);
1356
- throw _context.t1;
1357
-
1358
- case 23:
1359
- delete fetcher.requested[doc.value]; // delete cached 404 error
1360
- // console.log('createIfNotExists doc created ok ' + doc)
1361
-
1362
- return _context.abrupt("return", response);
1363
-
1364
- case 27:
1365
- console.log('createIfNotExists doc load error NOT 404: ' + doc + ': ' + _context.t0);
1366
- throw _context.t0;
1367
-
1368
- case 29:
1369
- return _context.abrupt("return", response);
1370
-
1371
- case 30:
1372
- case "end":
1373
- return _context.stop();
1374
- }
1375
- }
1376
- }, _callee, this, [[3, 9], [13, 19]]);
1377
- }));
1378
-
1379
- function createIfNotExists(_x) {
1380
- return _createIfNotExists.apply(this, arguments);
1381
- }
1382
-
1383
- return createIfNotExists;
1384
- }()
1385
- /**
1386
- * @param parentURI URI of parent container
1387
- * @param folderName - Optional folder name (slug)
1388
- * @param data - Optional folder metadata
1389
- */
1390
-
1391
- }, {
1392
- key: "createContainer",
1393
- value: function createContainer(parentURI, folderName, data) {
1394
- var headers = {
1395
- // Force the right mime type for containers
1396
- 'content-type': TurtleContentType,
1397
- 'link': this.ns.ldp('BasicContainer') + '; rel="type"'
1398
- };
1399
-
1400
- if (folderName) {
1401
- headers['slug'] = folderName;
1402
- } // @ts-ignore These headers lack some of the required operators.
1403
-
1404
-
1405
- var options = {
1406
- headers: headers
1407
- };
1408
-
1409
- if (data) {
1410
- options.body = data;
1411
- }
1412
-
1413
- return this.webOperation('POST', parentURI, options);
1414
- }
1415
- }, {
1416
- key: "invalidateCache",
1417
- value: function invalidateCache(iri) {
1418
- var uri = termValue(iri);
1419
- var fetcher = this; // @ts-ignore
1420
-
1421
- if (fetcher.fetchQueue && fetcher.fetchQueue[uri]) {
1422
- console.log('Internal error - fetchQueue exists ' + uri);
1423
- var promise = fetcher.fetchQueue[uri];
1084
+ });
1085
+ }
1086
+ delete(uri, options) {
1087
+ return this.webOperation('DELETE', uri, options).then(response => {
1088
+ this.requested[uri] = 404;
1089
+ this.nonexistent[uri] = true;
1090
+ this.unload(this.store.rdfFactory.namedNode(uri));
1091
+ return response;
1092
+ });
1093
+ }
1424
1094
 
1425
- if (promise['PromiseStatus'] === 'resolved') {
1426
- delete fetcher.fetchQueue[uri];
1427
- } else {
1428
- // pending
1429
- delete fetcher.fetchQueue[uri];
1430
- console.log('*** Fetcher: pending fetchQueue deleted ' + uri);
1095
+ /** Create an empty resource if it really does not exist
1096
+ * Be absolutely sure something does not exist before creating a new empty file
1097
+ * as otherwise existing could be deleted.
1098
+ * @param doc - The resource
1099
+ */
1100
+ async createIfNotExists(doc) {
1101
+ let contentType = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : TurtleContentType;
1102
+ let data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
1103
+ const fetcher = this;
1104
+ try {
1105
+ var response = await fetcher.load(doc);
1106
+ } catch (err) {
1107
+ // @ts-ignore
1108
+ if (err.response.status === 404) {
1109
+ console.log('createIfNotExists: doc does NOT exist, will create... ' + doc);
1110
+ try {
1111
+ response = await fetcher.webOperation('PUT', doc.value, {
1112
+ data,
1113
+ contentType
1114
+ });
1115
+ } catch (err) {
1116
+ console.log('createIfNotExists doc FAILED: ' + doc + ': ' + err);
1117
+ throw err;
1431
1118
  }
1432
- }
1433
-
1434
- if (fetcher.requested[uri] && fetcher.requested[uri] !== 'done' && fetcher.requested[uri] !== 'failed' && fetcher.requested[uri] !== 404) {
1435
- var msg = "Rdflib: fetcher: Destructive operation on <".concat(fetcher.requested[uri], "> file being fetched! ") + uri;
1436
- console.error(msg); // alert(msg)
1119
+ delete fetcher.requested[doc.value]; // delete cached 404 error
1120
+ // console.log('createIfNotExists doc created ok ' + doc)
1121
+ return response;
1437
1122
  } else {
1438
- delete fetcher.requested[uri]; // invalidate read cache -- @@ messes up logic if request in progress ??
1439
-
1440
- delete fetcher.nonexistent[uri];
1123
+ console.log('createIfNotExists doc load error NOT 404: ' + doc + ': ' + err);
1124
+ throw err;
1441
1125
  }
1442
1126
  }
1443
- /**
1444
- * A generic web operation, at the fetch() level.
1445
- * does not involve the quad store.
1446
- *
1447
- * Returns promise of Response
1448
- * If data is returned, copies it to response.responseText before returning
1449
- */
1450
-
1451
- }, {
1452
- key: "webOperation",
1453
- value: function webOperation(method, uriIn) {
1454
- var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1455
- var uri = termValue(uriIn);
1456
- options.method = method;
1457
- options.body = options.data || options.body;
1458
- options.force = true;
1459
- var fetcher = this;
1460
-
1461
- if (options.body && !options.contentType) {
1462
- throw new Error('Web operation sending data must have a defined contentType.');
1463
- }
1127
+ // console.log('createIfNotExists: doc exists, all good: ' + doc)
1128
+ return response;
1129
+ }
1464
1130
 
1465
- if (options.contentType) {
1466
- options.headers = options.headers || {};
1467
- options.headers['content-type'] = options.contentType;
1131
+ /**
1132
+ * @param parentURI URI of parent container
1133
+ * @param folderName - Optional folder name (slug)
1134
+ * @param data - Optional folder metadata
1135
+ */
1136
+ createContainer(parentURI, folderName, data) {
1137
+ let headers = {
1138
+ // Force the right mime type for containers
1139
+ 'content-type': TurtleContentType,
1140
+ 'link': this.ns.ldp('BasicContainer') + '; rel="type"'
1141
+ };
1142
+ if (folderName) {
1143
+ headers['slug'] = folderName;
1144
+ }
1145
+
1146
+ // @ts-ignore These headers lack some of the required operators.
1147
+ let options = {
1148
+ headers
1149
+ };
1150
+ if (data) {
1151
+ options.body = data;
1152
+ }
1153
+ return this.webOperation('POST', parentURI, options);
1154
+ }
1155
+ invalidateCache(iri) {
1156
+ const uri = termValue(iri);
1157
+ const fetcher = this;
1158
+ // @ts-ignore
1159
+ if (fetcher.fetchQueue && fetcher.fetchQueue[uri]) {
1160
+ console.log('Internal error - fetchQueue exists ' + uri);
1161
+ var promise = fetcher.fetchQueue[uri];
1162
+ if (promise['PromiseStatus'] === 'resolved') {
1163
+ delete fetcher.fetchQueue[uri];
1164
+ } else {
1165
+ // pending
1166
+ delete fetcher.fetchQueue[uri];
1167
+ console.log('*** Fetcher: pending fetchQueue deleted ' + uri);
1468
1168
  }
1169
+ }
1170
+ if (fetcher.requested[uri] && fetcher.requested[uri] !== 'done' && fetcher.requested[uri] !== 'failed' && fetcher.requested[uri] !== 404) {
1171
+ let msg = `Rdflib: fetcher: Destructive operation on <${fetcher.requested[uri]}> file being fetched! ` + uri;
1172
+ console.error(msg);
1173
+ // alert(msg)
1174
+ } else {
1175
+ delete fetcher.requested[uri]; // invalidate read cache -- @@ messes up logic if request in progress ??
1176
+ delete fetcher.nonexistent[uri];
1177
+ }
1178
+ }
1469
1179
 
1470
- Fetcher.setCredentials(uri, options);
1471
- return new Promise(function (resolve, reject) {
1472
- fetcher._fetch(uri, options).then(function (response) {
1473
- if (response.ok) {
1474
- if (method === 'PUT' || method === 'PATCH' || method === 'POST' || method === 'DELETE') {
1475
- fetcher.invalidateCache(uri);
1476
- } // response.body with Chrome can't be relied on
1477
-
1478
-
1479
- if (response.text) {
1480
- // Was: response.body https://github.com/linkeddata/rdflib.js/issues/506
1481
- response.text().then(function (data) {
1482
- response.responseText = data;
1483
- resolve(response);
1484
- });
1485
- } else {
1180
+ /**
1181
+ * A generic web operation, at the fetch() level.
1182
+ * does not involve the quad store.
1183
+ *
1184
+ * Returns promise of Response
1185
+ * If data is returned, copies it to response.responseText before returning
1186
+ */
1187
+ webOperation(method, uriIn) {
1188
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1189
+ const uri = termValue(uriIn);
1190
+ options.method = method;
1191
+ options.body = options.data || options.body;
1192
+ options.force = true;
1193
+ const fetcher = this;
1194
+ if (options.body && !options.contentType) {
1195
+ throw new Error('Web operation sending data must have a defined contentType.');
1196
+ }
1197
+ if (options.contentType) {
1198
+ options.headers = options.headers || {};
1199
+ options.headers['content-type'] = options.contentType;
1200
+ }
1201
+ Fetcher.setCredentials(uri, options);
1202
+ return new Promise(function (resolve, reject) {
1203
+ fetcher._fetch(uri, options).then(response => {
1204
+ if (response.ok) {
1205
+ if (method === 'PUT' || method === 'PATCH' || method === 'POST' || method === 'DELETE') {
1206
+ fetcher.invalidateCache(uri);
1207
+ } // response.body with Chrome can't be relied on
1208
+ if (response.text) {
1209
+ // Was: response.body https://github.com/linkeddata/rdflib.js/issues/506
1210
+ response.text().then(data => {
1211
+ response.responseText = data;
1486
1212
  resolve(response);
1487
- }
1213
+ });
1488
1214
  } else {
1489
- var msg = 'Web error: ' + response.status;
1490
- if (response.statusText) msg += ' (' + response.statusText + ')';
1491
- msg += ' on ' + method + ' of <' + uri + '>';
1492
- if (response.responseText) msg += ': ' + response.responseText;
1493
- var e2 = new Error(msg);
1494
- e2.response = response;
1495
- reject(e2);
1215
+ resolve(response);
1496
1216
  }
1497
- }, function (err) {
1498
- var msg = 'Fetch error for ' + method + ' of <' + uri + '>:' + err;
1499
- reject(new Error(msg));
1500
- });
1501
- });
1502
- }
1503
- /**
1504
- * Looks up something.
1505
- * Looks up all the URIs a things has.
1506
- *
1507
- * @param term - canonical term for the thing whose URI is
1508
- * to be dereferenced
1509
- * @param rterm - the resource which referred to this
1510
- * (for tracking bad links)
1511
- */
1512
-
1513
- }, {
1514
- key: "lookUpThing",
1515
- value: function lookUpThing(term, rterm) {
1516
- var _this9 = this;
1517
-
1518
- var uris = this.store.uris(term); // Get all URIs
1519
-
1520
- uris = uris.map(function (u) {
1521
- return Uri.docpart(u);
1522
- }); // Drop hash fragments
1523
-
1524
- uris.forEach(function (u) {
1525
- _this9.lookedUp[u] = true;
1526
- }); // @ts-ignore Recursive type
1527
-
1528
- return this.load(uris, {
1529
- referringTerm: rterm
1217
+ } else {
1218
+ let msg = 'Web error: ' + response.status;
1219
+ if (response.statusText) msg += ' (' + response.statusText + ')';
1220
+ msg += ' on ' + method + ' of <' + uri + '>';
1221
+ if (response.responseText) msg += ': ' + response.responseText;
1222
+ let e2 = new Error(msg);
1223
+ e2.response = response;
1224
+ reject(e2);
1225
+ }
1226
+ }, err => {
1227
+ let msg = 'Fetch error for ' + method + ' of <' + uri + '>:' + err;
1228
+ reject(new Error(msg));
1530
1229
  });
1531
- }
1532
- /**
1533
- * Looks up response header.
1534
- *
1535
- * @returns {Array|undefined} a list of header values found in a stored HTTP
1536
- * response, or [] if response was found but no header found,
1537
- * or undefined if no response is available.
1538
- * Looks for { [] link:requestedURI ?uri; link:response [ httph:header-name ?value ] }
1539
- */
1540
-
1541
- }, {
1542
- key: "getHeader",
1543
- value: function getHeader(doc, header) {
1544
- var kb = this.store; // look for the URI (AS A STRING NOT A NODE) for a stored request
1545
-
1546
- var docuri = doc.value;
1547
- var requests = kb.each(undefined, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri));
1548
-
1549
- for (var r = 0; r < requests.length; r++) {
1550
- var request = requests[r];
1230
+ });
1231
+ }
1551
1232
 
1552
- if (request !== undefined) {
1553
- var _response = kb.any(request, this.ns.link('response'));
1233
+ /**
1234
+ * Looks up something.
1235
+ * Looks up all the URIs a things has.
1236
+ *
1237
+ * @param term - canonical term for the thing whose URI is
1238
+ * to be dereferenced
1239
+ * @param rterm - the resource which referred to this
1240
+ * (for tracking bad links)
1241
+ */
1242
+ lookUpThing(term, rterm) {
1243
+ let uris = this.store.uris(term); // Get all URIs
1244
+ uris = uris.map(u => Uri.docpart(u)); // Drop hash fragments
1554
1245
 
1555
- if (_response !== undefined && kb.anyValue(_response, this.ns.http('status')) && kb.anyValue(_response, this.ns.http('status')).startsWith('2')) {
1556
- // Only look at success returns - not 401 error messagess etc
1557
- var results = kb.each(_response, this.ns.httph(header.toLowerCase()));
1246
+ uris.forEach(u => {
1247
+ this.lookedUp[u] = true;
1248
+ });
1558
1249
 
1559
- if (results.length) {
1560
- return results.map(function (v) {
1561
- return v.value;
1562
- });
1563
- }
1250
+ // @ts-ignore Recursive type
1251
+ return this.load(uris, {
1252
+ referringTerm: rterm
1253
+ });
1254
+ }
1564
1255
 
1565
- return [];
1256
+ /**
1257
+ * Looks up response header.
1258
+ *
1259
+ * @returns {Array|undefined} a list of header values found in a stored HTTP
1260
+ * response, or [] if response was found but no header found,
1261
+ * or undefined if no response is available.
1262
+ * Looks for { [] link:requestedURI ?uri; link:response [ httph:header-name ?value ] }
1263
+ */
1264
+ getHeader(doc, header) {
1265
+ const kb = this.store; // look for the URI (AS A STRING NOT A NODE) for a stored request
1266
+ const docuri = doc.value;
1267
+ const requests = kb.each(undefined, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri));
1268
+ for (let r = 0; r < requests.length; r++) {
1269
+ let request = requests[r];
1270
+ if (request !== undefined) {
1271
+ let response = kb.any(request, this.ns.link('response'));
1272
+ if (response !== undefined && kb.anyValue(response, this.ns.http('status')) && kb.anyValue(response, this.ns.http('status')).startsWith('2')) {
1273
+ // Only look at success returns - not 401 error messagess etc
1274
+ let results = kb.each(response, this.ns.httph(header.toLowerCase()));
1275
+ if (results.length) {
1276
+ return results.map(v => {
1277
+ return v.value;
1278
+ });
1566
1279
  }
1280
+ return [];
1567
1281
  }
1568
1282
  }
1569
-
1570
- return undefined;
1571
1283
  }
1572
- }, {
1573
- key: "saveRequestMetadata",
1574
- value: function saveRequestMetadata(docuri, options) {
1575
- var req = options.req;
1576
- var kb = this.store;
1577
- var rterm = options.referringTerm;
1578
- this.addStatus(options.req, 'Accept: ' + options.headers['accept']);
1579
-
1580
- if (isNamedNode(rterm)) {
1581
- kb.add(kb.rdfFactory.namedNode(docuri), this.ns.link('requestedBy'), rterm, this.appNode);
1284
+ return undefined;
1285
+ }
1286
+ saveRequestMetadata(docuri, options) {
1287
+ let req = options.req;
1288
+ let kb = this.store;
1289
+ let rterm = options.referringTerm;
1290
+ this.addStatus(options.req, 'Accept: ' + options.headers['accept']);
1291
+ if (isNamedNode(rterm)) {
1292
+ kb.add(kb.rdfFactory.namedNode(docuri), this.ns.link('requestedBy'), rterm, this.appNode);
1293
+ }
1294
+ if (options.original && options.original.value !== docuri) {
1295
+ kb.add(req, this.ns.link('orginalURI'), kb.rdfFactory.literal(options.original.value), this.appNode);
1296
+ }
1297
+ const now = new Date();
1298
+ const timeNow = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ';
1299
+ kb.add(req, this.ns.rdfs('label'), kb.rdfFactory.literal(timeNow + ' Request for ' + docuri), this.appNode);
1300
+ // We store the docuri as a string, not as a node,
1301
+ // see https://github.com/linkeddata/rdflib.js/pull/427#pullrequestreview-447910061
1302
+ kb.add(req, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri), this.appNode);
1303
+ kb.add(req, this.ns.link('status'), kb.collection(), this.appNode);
1304
+ }
1305
+ saveResponseMetadata(response, options) {
1306
+ const kb = this.store;
1307
+ let responseNode = kb.bnode();
1308
+ kb.add(options.req, this.ns.link('response'), responseNode, responseNode);
1309
+ kb.add(responseNode, this.ns.http('status'), kb.rdfFactory.literal(response.status), responseNode);
1310
+ kb.add(responseNode, this.ns.http('statusText'), kb.rdfFactory.literal(response.statusText), responseNode);
1311
+
1312
+ // Save the response headers
1313
+ response.headers.forEach((value, header) => {
1314
+ kb.add(responseNode, this.ns.httph(header), this.store.rdfFactory.literal(value), responseNode);
1315
+ if (header === 'content-type') {
1316
+ kb.add(options.resource, this.ns.rdf('type'), kb.rdfFactory.namedNode(Util.mediaTypeClass(value).value), responseNode);
1582
1317
  }
1583
-
1584
- if (options.original && options.original.value !== docuri) {
1585
- kb.add(req, this.ns.link('orginalURI'), kb.rdfFactory.literal(options.original.value), this.appNode);
1318
+ });
1319
+ return responseNode;
1320
+ }
1321
+ objectRefresh(term) {
1322
+ let uris = this.store.uris(term); // Get all URIs
1323
+ if (typeof uris !== 'undefined') {
1324
+ for (let i = 0; i < uris.length; i++) {
1325
+ this.refresh(this.store.rdfFactory.namedNode(Uri.docpart(uris[i])));
1326
+ // what about rterm?
1586
1327
  }
1587
-
1588
- var now = new Date();
1589
- var timeNow = '[' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds() + '] ';
1590
- kb.add(req, this.ns.rdfs('label'), kb.rdfFactory.literal(timeNow + ' Request for ' + docuri), this.appNode); // We store the docuri as a string, not as a node,
1591
- // see https://github.com/linkeddata/rdflib.js/pull/427#pullrequestreview-447910061
1592
-
1593
- kb.add(req, this.ns.link('requestedURI'), kb.rdfFactory.literal(docuri), this.appNode);
1594
- kb.add(req, this.ns.link('status'), kb.collection(), this.appNode);
1595
1328
  }
1596
- }, {
1597
- key: "saveResponseMetadata",
1598
- value: function saveResponseMetadata(response, options) {
1599
- var _this10 = this;
1600
-
1601
- var kb = this.store;
1602
- var responseNode = kb.bnode();
1603
- kb.add(options.req, this.ns.link('response'), responseNode, responseNode);
1604
- kb.add(responseNode, this.ns.http('status'), kb.rdfFactory.literal(response.status), responseNode);
1605
- kb.add(responseNode, this.ns.http('statusText'), kb.rdfFactory.literal(response.statusText), responseNode); // Save the response headers
1329
+ }
1606
1330
 
1607
- response.headers.forEach(function (value, header) {
1608
- kb.add(responseNode, _this10.ns.httph(header), _this10.store.rdfFactory.literal(value), responseNode);
1331
+ /* refresh Reload data from a given document
1332
+ **
1333
+ ** @param term - An RDF Named Node for the eodcument in question
1334
+ ** @param userCallback - A function userCallback(ok, message, response)
1335
+ */
1336
+ refresh(term, userCallback) {
1337
+ // sources_refresh
1338
+ this.fireCallbacks('refresh', arguments);
1339
+ this.nowOrWhenFetched(term, {
1340
+ force: true,
1341
+ clearPreviousData: true
1342
+ }, userCallback);
1343
+ }
1609
1344
 
1610
- if (header === 'content-type') {
1611
- kb.add(options.resource, _this10.ns.rdf('type'), kb.rdfFactory.namedNode(Util.mediaTypeClass(value).value), responseNode);
1612
- }
1613
- });
1614
- return responseNode;
1345
+ /* refreshIfExpired Conditional refresh if Expired
1346
+ **
1347
+ ** @param term - An RDF Named Node for the eodcument in question
1348
+ ** @param userCallback - A function userCallback(ok, message, response)
1349
+ */
1350
+ refreshIfExpired(term, userCallback) {
1351
+ let exp = this.getHeader(term, 'Expires');
1352
+ if (!exp || new Date(exp[0]).getTime() <= new Date().getTime()) {
1353
+ this.refresh(term, userCallback);
1354
+ } else {
1355
+ userCallback(true, 'Not expired', {});
1615
1356
  }
1616
- }, {
1617
- key: "objectRefresh",
1618
- value: function objectRefresh(term) {
1619
- var uris = this.store.uris(term); // Get all URIs
1620
-
1621
- if (typeof uris !== 'undefined') {
1622
- for (var i = 0; i < uris.length; i++) {
1623
- this.refresh(this.store.rdfFactory.namedNode(Uri.docpart(uris[i]))); // what about rterm?
1624
- }
1625
- }
1357
+ }
1358
+ retract(term) {
1359
+ // sources_retract
1360
+ this.store.removeMany(undefined, undefined, undefined, term);
1361
+ if (term.value) {
1362
+ delete this.requested[Uri.docpart(term.value)];
1626
1363
  }
1627
- /* refresh Reload data from a given document
1628
- **
1629
- ** @param term - An RDF Named Node for the eodcument in question
1630
- ** @param userCallback - A function userCallback(ok, message, response)
1631
- */
1632
-
1633
- }, {
1634
- key: "refresh",
1635
- value: function refresh(term, userCallback) {
1636
- // sources_refresh
1637
- this.fireCallbacks('refresh', arguments);
1638
- this.nowOrWhenFetched(term, {
1639
- force: true,
1640
- clearPreviousData: true
1641
- }, userCallback);
1642
- }
1643
- /* refreshIfExpired Conditional refresh if Expired
1644
- **
1645
- ** @param term - An RDF Named Node for the eodcument in question
1646
- ** @param userCallback - A function userCallback(ok, message, response)
1647
- */
1648
-
1649
- }, {
1650
- key: "refreshIfExpired",
1651
- value: function refreshIfExpired(term, userCallback) {
1652
- var exp = this.getHeader(term, 'Expires');
1653
-
1654
- if (!exp || new Date(exp[0]).getTime() <= new Date().getTime()) {
1655
- this.refresh(term, userCallback);
1656
- } else {
1657
- userCallback(true, 'Not expired', {});
1658
- }
1364
+ this.fireCallbacks('retract', arguments);
1365
+ }
1366
+ getState(docuri) {
1367
+ if (typeof this.requested[docuri] === 'undefined') {
1368
+ return 'unrequested';
1369
+ } else if (this.requested[docuri] === true) {
1370
+ return 'requested';
1371
+ } else if (this.requested[docuri] === 'done') {
1372
+ return 'fetched';
1373
+ } else if (this.requested[docuri] === 'redirected') {
1374
+ return this.getState(this.redirectedTo[docuri]);
1375
+ } else {
1376
+ // An non-200 HTTP error status
1377
+ return 'failed';
1659
1378
  }
1660
- }, {
1661
- key: "retract",
1662
- value: function retract(term) {
1663
- // sources_retract
1664
- this.store.removeMany(undefined, undefined, undefined, term);
1379
+ }
1380
+ isPending(docuri) {
1381
+ // sources_pending
1382
+ // doing anyStatementMatching is wasting time
1383
+ // if it's not pending: false -> flailed
1384
+ // 'done' -> done 'redirected' -> redirected
1385
+ return this.requested[docuri] === true;
1386
+ }
1387
+ unload(term) {
1388
+ this.store.removeDocument(term);
1389
+ delete this.requested[term.value]; // So it can be load2ed again
1390
+ }
1665
1391
 
1666
- if (term.value) {
1667
- delete this.requested[Uri.docpart(term.value)];
1668
- }
1392
+ addHandler(handler) {
1393
+ this.handlers.push(handler);
1394
+ handler.register(this);
1395
+ }
1396
+ retryNoCredentials(docuri, options) {
1397
+ console.log('Fetcher: CORS: RETRYING with NO CREDENTIALS for ' + options.resource);
1398
+ options.retriedWithNoCredentials = true; // protect against being called twice
1399
+
1400
+ delete this.requested[docuri]; // forget the original request happened
1401
+ delete this.fetchQueue[docuri];
1402
+ // Note: XHR property was withCredentials, but fetch property is just credentials
1403
+ let newOptions = Object.assign({}, options, {
1404
+ credentials: 'omit'
1405
+ });
1406
+ this.addStatus(options.req, 'Abort: Will retry with credentials SUPPRESSED to see if that helps');
1407
+ return this.load(docuri, newOptions);
1408
+ }
1669
1409
 
1670
- this.fireCallbacks('retract', arguments);
1671
- }
1672
- }, {
1673
- key: "getState",
1674
- value: function getState(docuri) {
1675
- if (typeof this.requested[docuri] === 'undefined') {
1676
- return 'unrequested';
1677
- } else if (this.requested[docuri] === true) {
1678
- return 'requested';
1679
- } else if (this.requested[docuri] === 'done') {
1680
- return 'fetched';
1681
- } else if (this.requested[docuri] === 'redirected') {
1682
- return this.getState(this.redirectedTo[docuri]);
1683
- } else {
1684
- // An non-200 HTTP error status
1685
- return 'failed';
1686
- }
1687
- }
1688
- }, {
1689
- key: "isPending",
1690
- value: function isPending(docuri) {
1691
- // sources_pending
1692
- // doing anyStatementMatching is wasting time
1693
- // if it's not pending: false -> flailed
1694
- // 'done' -> done 'redirected' -> redirected
1695
- return this.requested[docuri] === true;
1696
- }
1697
- }, {
1698
- key: "unload",
1699
- value: function unload(term) {
1700
- this.store.removeDocument(term);
1701
- delete this.requested[term.value]; // So it can be load2ed again
1702
- }
1703
- }, {
1704
- key: "addHandler",
1705
- value: function addHandler(handler) {
1706
- this.handlers.push(handler);
1707
- handler.register(this);
1708
- }
1709
- }, {
1710
- key: "retryNoCredentials",
1711
- value: function retryNoCredentials(docuri, options) {
1712
- console.log('Fetcher: CORS: RETRYING with NO CREDENTIALS for ' + options.resource);
1713
- options.retriedWithNoCredentials = true; // protect against being called twice
1714
-
1715
- delete this.requested[docuri]; // forget the original request happened
1716
-
1717
- delete this.fetchQueue[docuri]; // Note: XHR property was withCredentials, but fetch property is just credentials
1718
-
1719
- var newOptions = Object.assign({}, options, {
1720
- credentials: 'omit'
1721
- });
1722
- this.addStatus(options.req, 'Abort: Will retry with credentials SUPPRESSED to see if that helps');
1723
- return this.load(docuri, newOptions);
1724
- }
1725
- /**
1726
- * Tests whether a request is being made to a cross-site URI (for purposes
1727
- * of retrying with a proxy)
1728
- */
1410
+ /**
1411
+ * Tests whether a request is being made to a cross-site URI (for purposes
1412
+ * of retrying with a proxy)
1413
+ */
1414
+ isCrossSite(uri) {
1415
+ // Mashup situation, not node etc
1416
+ if (typeof document === 'undefined' || !document.location) {
1417
+ return false;
1418
+ }
1419
+ const hostpart = Uri.hostpart;
1420
+ const here = '' + document.location;
1421
+ return (hostpart(here) && hostpart(uri) && hostpart(here)) !== hostpart(uri);
1422
+ }
1729
1423
 
1730
- }, {
1731
- key: "isCrossSite",
1732
- value: function isCrossSite(uri) {
1733
- // Mashup situation, not node etc
1734
- if (typeof document === 'undefined' || !document.location) {
1735
- return false;
1424
+ /**
1425
+ * Called when there's a network error in fetch(), or a response
1426
+ * with status of 0.
1427
+ */
1428
+ handleError(response, docuri, options) {
1429
+ if (this.isCrossSite(docuri)) {
1430
+ // Make sure we haven't retried already
1431
+ if (options.credentials && options.credentials === 'include' && !options.retriedWithNoCredentials) {
1432
+ return this.retryNoCredentials(docuri, options);
1736
1433
  }
1737
1434
 
1738
- var hostpart = Uri.hostpart;
1739
- var here = '' + document.location;
1740
- return (hostpart(here) && hostpart(uri) && hostpart(here)) !== hostpart(uri);
1741
- }
1742
- /**
1743
- * Called when there's a network error in fetch(), or a response
1744
- * with status of 0.
1745
- */
1746
-
1747
- }, {
1748
- key: "handleError",
1749
- value: function handleError(response, docuri, options) {
1750
- if (this.isCrossSite(docuri)) {
1751
- // Make sure we haven't retried already
1752
- if (options.credentials && options.credentials === 'include' && !options.retriedWithNoCredentials) {
1753
- return this.retryNoCredentials(docuri, options);
1754
- } // Now attempt retry via proxy
1755
-
1756
-
1757
- var proxyUri = Fetcher.crossSiteProxy(docuri);
1758
-
1759
- if (proxyUri && !options.proxyUsed) {
1760
- console.log('web: Direct failed so trying proxy ' + proxyUri);
1761
- return this.redirectToProxy(proxyUri, options);
1762
- }
1435
+ // Now attempt retry via proxy
1436
+ let proxyUri = Fetcher.crossSiteProxy(docuri);
1437
+ if (proxyUri && !options.proxyUsed) {
1438
+ console.log('web: Direct failed so trying proxy ' + proxyUri);
1439
+ return this.redirectToProxy(proxyUri, options);
1763
1440
  }
1764
-
1765
- var message;
1766
-
1767
- if (response instanceof Error) {
1768
- message = 'Fetch error: ' + response.message;
1769
- } else {
1770
- message = response.statusText;
1771
-
1772
- if (response.responseText) {
1773
- message += " ".concat(response.responseText);
1774
- }
1775
- } // This is either not a CORS error, or retries have been made
1776
-
1777
-
1778
- return this.failFetch(options, message, response.status || 998, response);
1779
- } // deduce some things from the HTTP transaction
1780
-
1781
- }, {
1782
- key: "addType",
1783
- value: function addType(rdfType, req, kb, locURI) {
1784
- // add type to all redirected resources too
1785
- var prev = req;
1786
-
1787
- if (locURI) {
1788
- var reqURI = kb.any(prev, this.ns.link('requestedURI'));
1789
-
1790
- if (reqURI && reqURI.value !== locURI) {
1791
- kb.add(kb.rdfFactory.namedNode(locURI), this.ns.rdf('type'), rdfType, this.appNode);
1792
- }
1441
+ }
1442
+ var message;
1443
+ if (response instanceof Error) {
1444
+ message = 'Fetch error: ' + response.message;
1445
+ } else {
1446
+ message = response.statusText;
1447
+ if (response.responseText) {
1448
+ message += ` ${response.responseText}`;
1793
1449
  }
1450
+ }
1794
1451
 
1795
- for (;;) {
1796
- var doc = kb.any(prev, this.ns.link('requestedURI'));
1797
-
1798
- if (doc && doc.value) {
1799
- kb.add(kb.rdfFactory.namedNode(doc.value), this.ns.rdf('type'), rdfType, this.appNode);
1800
- } // convert Literal
1801
-
1802
-
1803
- prev = kb.any(undefined, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#redirectedRequest'), prev);
1804
-
1805
- if (!prev) {
1806
- break;
1807
- }
1808
-
1809
- var response = kb.any(prev, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#response'));
1810
-
1811
- if (!response) {
1812
- break;
1813
- }
1814
-
1815
- var redirection = kb.any(response, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/http#status'));
1816
-
1817
- if (!redirection) {
1818
- break;
1819
- } // @ts-ignore always true?
1820
-
1452
+ // This is either not a CORS error, or retries have been made
1453
+ return this.failFetch(options, message, response.status || 998, response);
1454
+ }
1821
1455
 
1822
- if (redirection !== '301' && redirection !== '302') {
1823
- break;
1824
- }
1456
+ // deduce some things from the HTTP transaction
1457
+ addType(rdfType, req, kb, locURI) {
1458
+ // add type to all redirected resources too
1459
+ let prev = req;
1460
+ if (locURI) {
1461
+ var reqURI = kb.any(prev, this.ns.link('requestedURI'));
1462
+ if (reqURI && reqURI.value !== locURI) {
1463
+ kb.add(kb.rdfFactory.namedNode(locURI), this.ns.rdf('type'), rdfType, this.appNode);
1825
1464
  }
1826
1465
  }
1827
- /**
1828
- * Handle fetch() response
1829
- */
1830
-
1831
- }, {
1832
- key: "handleResponse",
1833
- value: function handleResponse(response, docuri, options) {
1834
- var _this11 = this;
1835
-
1836
- var kb = this.store;
1837
- var headers = response.headers;
1838
- var reqNode = options.req;
1839
- var responseNode = this.saveResponseMetadata(response, options);
1840
- var contentType = this.normalizedContentType(options, headers) || '';
1841
- var contentLocation = headers.get('content-location'); // this.fireCallbacks('recv', xhr.args)
1842
- // this.fireCallbacks('headers', [{uri: docuri, headers: xhr.headers}])
1843
- // Check for masked errors (CORS, etc)
1844
-
1845
- if (response.status === 0) {
1846
- console.log('Masked error - status 0 for ' + docuri);
1847
- return this.handleError(response, docuri, options);
1466
+ for (;;) {
1467
+ const doc = kb.any(prev, this.ns.link('requestedURI'));
1468
+ if (doc && doc.value) {
1469
+ kb.add(kb.rdfFactory.namedNode(doc.value), this.ns.rdf('type'), rdfType, this.appNode);
1470
+ } // convert Literal
1471
+ prev = kb.any(undefined, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#redirectedRequest'), prev);
1472
+ if (!prev) {
1473
+ break;
1848
1474
  }
1849
-
1850
- if (response.status >= 400) {
1851
- if (response.status === 404) {
1852
- this.nonexistent[options.original.value] = true;
1853
- this.nonexistent[docuri] = true;
1854
- }
1855
-
1856
- return this.saveErrorResponse(response, responseNode).then(function () {
1857
- var errorMessage = options.resource + ' ' + response.statusText;
1858
- return _this11.failFetch(options, errorMessage, response.status, response);
1859
- });
1475
+ var response = kb.any(prev, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/link#response'));
1476
+ if (!response) {
1477
+ break;
1860
1478
  }
1861
-
1862
- var diffLocation = null;
1863
- var absContentLocation = null;
1864
-
1865
- if (contentLocation) {
1866
- absContentLocation = Uri.join(contentLocation, docuri);
1867
-
1868
- if (absContentLocation !== docuri) {
1869
- diffLocation = absContentLocation;
1870
- }
1479
+ var redirection = kb.any(response, kb.rdfFactory.namedNode('http://www.w3.org/2007/ont/http#status'));
1480
+ if (!redirection) {
1481
+ break;
1871
1482
  }
1872
-
1873
- if (response.status === 200) {
1874
- this.addType(this.ns.link('Document'), reqNode, kb, docuri);
1875
-
1876
- if (diffLocation) {
1877
- this.addType(this.ns.link('Document'), reqNode, kb, diffLocation);
1878
- } // Before we parse new data clear old but only on 200
1879
-
1880
-
1881
- if (options.clearPreviousData) {
1882
- kb.removeDocument(options.resource);
1883
- }
1884
-
1885
- var isImage = contentType.includes('image/') || contentType.includes('application/pdf');
1886
-
1887
- if (contentType && isImage) {
1888
- this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, docuri);
1889
-
1890
- if (diffLocation) {
1891
- this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, diffLocation);
1892
- }
1893
- }
1894
- } // If we have already got the thing at this location, abort
1895
-
1896
-
1897
- if (contentLocation) {
1898
- if (!options.force && diffLocation && this.requested[absContentLocation] === 'done') {
1899
- // we have already fetched this
1900
- // should we smush too?
1901
- // log.info("HTTP headers indicate we have already" + " retrieved " +
1902
- // xhr.resource + " as " + absContentLocation + ". Aborting.")
1903
- return this.doneFetch(options, response);
1904
- }
1905
-
1906
- this.requested[absContentLocation] = true;
1483
+ // @ts-ignore always true?
1484
+ if (redirection !== '301' && redirection !== '302') {
1485
+ break;
1907
1486
  }
1908
-
1909
- this.parseLinkHeader(headers.get('link'), options.original, reqNode);
1910
- var handler = this.handlerForContentType(contentType, response);
1911
-
1912
- if (!handler) {
1913
- // Not a problem, we just don't extract data
1914
- this.addStatus(reqNode, 'Fetch over. No data handled.');
1915
- return this.doneFetch(options, response);
1916
- }
1917
-
1918
- return response.text() // @ts-ignore Types seem right
1919
- .then(function (responseText) {
1920
- response.responseText = responseText;
1921
- return handler.parse(_this11, responseText, options, response);
1922
- });
1923
1487
  }
1924
- }, {
1925
- key: "saveErrorResponse",
1926
- value: function saveErrorResponse(response, responseNode) {
1927
- var _this12 = this;
1488
+ }
1928
1489
 
1929
- var kb = this.store;
1930
- return response.text().then(function (content) {
1931
- if (content.length > 10) {
1932
- kb.add(responseNode, _this12.ns.http('content'), kb.rdfFactory.literal(content), responseNode);
1933
- }
1490
+ /**
1491
+ * Handle fetch() response
1492
+ */
1493
+ handleResponse(response, docuri, options) {
1494
+ const kb = this.store;
1495
+ const headers = response.headers;
1496
+ const reqNode = options.req;
1497
+ const responseNode = this.saveResponseMetadata(response, options);
1498
+ const contentType = this.normalizedContentType(options, headers) || '';
1499
+ let contentLocation = headers.get('content-location');
1500
+
1501
+ // this.fireCallbacks('recv', xhr.args)
1502
+ // this.fireCallbacks('headers', [{uri: docuri, headers: xhr.headers}])
1503
+
1504
+ // Check for masked errors (CORS, etc)
1505
+ if (response.status === 0) {
1506
+ console.log('Masked error - status 0 for ' + docuri);
1507
+ return this.handleError(response, docuri, options);
1508
+ }
1509
+ if (response.status >= 400) {
1510
+ if (response.status === 404) {
1511
+ this.nonexistent[options.original.value] = true;
1512
+ this.nonexistent[docuri] = true;
1513
+ }
1514
+ return this.saveErrorResponse(response, responseNode).then(() => {
1515
+ let errorMessage = options.resource + ' ' + response.statusText;
1516
+ return this.failFetch(options, errorMessage, response.status, response);
1934
1517
  });
1935
1518
  }
1936
- }, {
1937
- key: "handlerForContentType",
1938
- value: function handlerForContentType(contentType, response) {
1939
- if (!contentType) {
1940
- return null;
1519
+ var diffLocation = null;
1520
+ var absContentLocation = null;
1521
+ if (contentLocation) {
1522
+ absContentLocation = Uri.join(contentLocation, docuri);
1523
+ if (absContentLocation !== docuri) {
1524
+ diffLocation = absContentLocation;
1941
1525
  }
1942
-
1943
- var Handler = this.handlers.find(function (handler) {
1944
- return contentType.match(handler.pattern);
1945
- }); // @ts-ignore in practice all Handlers have constructors.
1946
-
1947
- return Handler ? new Handler(response) : null;
1948
1526
  }
1949
- }, {
1950
- key: "guessContentType",
1951
- value: function guessContentType(uri) {
1952
- return CONTENT_TYPE_BY_EXT[uri.split('.').pop()];
1953
- }
1954
- }, {
1955
- key: "normalizedContentType",
1956
- value: function normalizedContentType(options, headers) {
1957
- if (options.forceContentType) {
1958
- return options.forceContentType;
1959
- }
1960
-
1961
- var contentType = headers.get('content-type');
1962
-
1963
- if (!contentType || contentType.includes('application/octet-stream')) {
1964
- var guess = this.guessContentType(options.resource.value);
1965
-
1966
- if (guess) {
1967
- return guess;
1968
- }
1969
- }
1970
-
1971
- var protocol = Uri.protocol(options.resource.value);
1972
-
1973
- if (!contentType && ['file', 'chrome'].includes(protocol)) {
1974
- return 'text/xml';
1527
+ if (response.status === 200) {
1528
+ this.addType(this.ns.link('Document'), reqNode, kb, docuri);
1529
+ if (diffLocation) {
1530
+ this.addType(this.ns.link('Document'), reqNode, kb, diffLocation);
1975
1531
  }
1976
1532
 
1977
- return contentType;
1978
- }
1979
- /**
1980
- * Sends a new request to the specified uri. (Extracted from `onerrorFactory()`)
1981
- */
1982
-
1983
- }, {
1984
- key: "redirectToProxy",
1985
- value: function redirectToProxy(newURI, options) {
1986
- var _this13 = this;
1987
-
1988
- this.addStatus(options.req, 'BLOCKED -> Cross-site Proxy to <' + newURI + '>');
1989
- options.proxyUsed = true;
1990
- var kb = this.store;
1991
- var oldReq = options.req; // request metadata blank node
1992
-
1993
- if (!options.noMeta) {
1994
- kb.add(oldReq, this.ns.link('redirectedTo'), kb.rdfFactory.namedNode(newURI), oldReq);
1995
- this.addStatus(oldReq, 'redirected to new request'); // why
1533
+ // Before we parse new data clear old but only on 200
1534
+ if (options.clearPreviousData) {
1535
+ kb.removeDocument(options.resource);
1996
1536
  }
1997
-
1998
- this.requested[options.resource.value] = 'redirected';
1999
- this.redirectedTo[options.resource.value] = newURI;
2000
- var newOptions = Object.assign({}, options);
2001
- newOptions.baseURI = options.resource.value;
2002
- return this.fetchUri(newURI, newOptions).then(function (response) {
2003
- if (!newOptions.noMeta) {
2004
- kb.add(oldReq, _this13.ns.link('redirectedRequest'), newOptions.req, _this13.appNode);
1537
+ let isImage = contentType.includes('image/') || contentType.includes('application/pdf');
1538
+ if (contentType && isImage) {
1539
+ this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, docuri);
1540
+ if (diffLocation) {
1541
+ this.addType(kb.rdfFactory.namedNode('http://purl.org/dc/terms/Image'), reqNode, kb, diffLocation);
2005
1542
  }
2006
-
2007
- return response;
2008
- });
2009
- }
2010
- }, {
2011
- key: "setRequestTimeout",
2012
- value: function setRequestTimeout(uri, options) {
2013
- var _this14 = this;
2014
-
2015
- return new Promise(function (resolve) {
2016
- _this14.timeouts[uri] = (_this14.timeouts[uri] || []).concat(setTimeout(function () {
2017
- if (_this14.isPending(uri) && !options.retriedWithNoCredentials && !options.proxyUsed) {
2018
- resolve(_this14.failFetch(options, "Request to ".concat(uri, " timed out"), 'timeout'));
2019
- }
2020
- }, _this14.timeout));
2021
- });
2022
- }
2023
- }, {
2024
- key: "addFetchCallback",
2025
- value: function addFetchCallback(uri, callback) {
2026
- if (!this.fetchCallbacks[uri]) {
2027
- this.fetchCallbacks[uri] = [callback];
2028
- } else {
2029
- this.fetchCallbacks[uri].push(callback);
2030
1543
  }
2031
1544
  }
2032
- }, {
2033
- key: "acceptString",
2034
- value: function acceptString() {
2035
- var acceptstring = '';
2036
-
2037
- for (var mediaType in this.mediatypes) {
2038
- if (acceptstring !== '') {
2039
- acceptstring += ', ';
2040
- }
2041
-
2042
- acceptstring += mediaType;
2043
1545
 
2044
- for (var property in this.mediatypes[mediaType]) {
2045
- acceptstring += ';' + property + '=' + this.mediatypes[mediaType][property];
2046
- }
2047
- }
2048
-
2049
- return acceptstring;
2050
- } // var updatesVia = new $rdf.UpdatesVia(this) // Subscribe to headers
2051
- // @@@@@@@@ This is turned off because it causes a websocket to be set up for ANY fetch
2052
- // whether we want to track it ot not. including ontologies loaed though the XSSproxy
2053
-
2054
- }], [{
2055
- key: "crossSiteProxy",
2056
- value: function crossSiteProxy(uri) {
2057
- if (Fetcher.crossSiteProxyTemplate) {
2058
- return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
2059
- } else {
2060
- return undefined;
1546
+ // If we have already got the thing at this location, abort
1547
+ if (contentLocation) {
1548
+ if (!options.force && diffLocation && this.requested[absContentLocation] === 'done') {
1549
+ // we have already fetched this
1550
+ // should we smush too?
1551
+ // log.info("HTTP headers indicate we have already" + " retrieved " +
1552
+ // xhr.resource + " as " + absContentLocation + ". Aborting.")
1553
+ return this.doneFetch(options, response);
2061
1554
  }
2062
- }
2063
- }, {
2064
- key: "offlineOverride",
2065
- value: function offlineOverride(uri) {
2066
- // Map the URI to a localhost proxy if we are running on localhost
2067
- // This is used for working offline, e.g. on planes.
2068
- // Is the script itself is running in localhost, then access all
2069
- // data in a localhost mirror.
2070
- // Do not remove without checking with TimBL
2071
- var requestedURI = uri;
2072
- var UI;
2073
-
2074
- if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.preferences && UI.preferences.get('offlineModeUsingLocalhost')) {
2075
- if (requestedURI.slice(0, 7) === 'http://' && requestedURI.slice(7, 17) !== 'localhost/') {
2076
- requestedURI = 'http://localhost/' + requestedURI.slice(7);
2077
- log.warn('Localhost kludge for offline use: actually getting <' + requestedURI + '>');
2078
- } else {// log.warn("Localhost kludge NOT USED <" + requestedURI + ">")
2079
- }
2080
- } else {// log.warn("Localhost kludge OFF offline use: actually getting <" +
2081
- // requestedURI + ">")
1555
+ this.requested[absContentLocation] = true;
1556
+ }
1557
+ this.parseLinkHeader(headers.get('link'), options.original, reqNode);
1558
+ let handler = this.handlerForContentType(contentType, response);
1559
+ if (!handler) {
1560
+ // Not a problem, we just don't extract data
1561
+ this.addStatus(reqNode, 'Fetch over. No data handled.');
1562
+ return this.doneFetch(options, response);
1563
+ }
1564
+ return response.text()
1565
+ // @ts-ignore Types seem right
1566
+ .then(responseText => {
1567
+ response.responseText = responseText;
1568
+ return handler.parse(this, responseText, options, response);
1569
+ });
1570
+ }
1571
+ saveErrorResponse(response, responseNode) {
1572
+ let kb = this.store;
1573
+ return response.text().then(content => {
1574
+ if (content.length > 10) {
1575
+ kb.add(responseNode, this.ns.http('content'), kb.rdfFactory.literal(content), responseNode);
2082
1576
  }
2083
-
2084
- return requestedURI;
1577
+ });
1578
+ }
1579
+ handlerForContentType(contentType, response) {
1580
+ if (!contentType) {
1581
+ return null;
2085
1582
  }
2086
- }, {
2087
- key: "proxyIfNecessary",
2088
- value: function proxyIfNecessary(uri) {
2089
- var UI;
2090
-
2091
- if (typeof window !== 'undefined' && window.panes && (UI = window.panes.UI) && UI.isExtension) {
2092
- return uri;
2093
- } // Extension does not need proxy
2094
-
2095
-
2096
- if (typeof $SolidTestEnvironment !== 'undefined' && $SolidTestEnvironment.localSiteMap) {
2097
- // nested dictionaries of URI parts from origin down
2098
- var hostpath = uri.split('/').slice(2); // the bit after the //
2099
-
2100
- var lookup = function lookup(parts, index) {
2101
- var z = index[parts.shift()];
2102
-
2103
- if (!z) {
2104
- return null;
2105
- }
2106
-
2107
- if (typeof z === 'string') {
2108
- return z + parts.join('/');
2109
- }
2110
-
2111
- if (!parts) {
2112
- return null;
2113
- }
2114
-
2115
- return lookup(parts, z);
2116
- };
2117
-
2118
- var y = lookup(hostpath, $SolidTestEnvironment.localSiteMap);
2119
-
2120
- if (y) {
2121
- return y;
2122
- }
2123
- } // browser does 2014 on as https browser script not trusted
2124
- // If the web app origin is https: then the mixed content rules
2125
- // prevent it loading insecure http: stuff so we need proxy.
2126
-
1583
+ let Handler = this.handlers.find(handler => {
1584
+ return contentType.match(handler.pattern);
1585
+ });
2127
1586
 
2128
- if (Fetcher.crossSiteProxyTemplate && typeof document !== 'undefined' && document.location && ('' + document.location).slice(0, 6) === 'https:' && // origin is secure
2129
- uri.slice(0, 5) === 'http:') {
2130
- // requested data is not
2131
- return Fetcher.crossSiteProxyTemplate.replace('{uri}', encodeURIComponent(uri));
1587
+ // @ts-ignore in practice all Handlers have constructors.
1588
+ return Handler ? new Handler(response) : null;
1589
+ }
1590
+ guessContentType(uri) {
1591
+ return CONTENT_TYPE_BY_EXT[uri.split('.').pop()];
1592
+ }
1593
+ normalizedContentType(options, headers) {
1594
+ if (options.forceContentType) {
1595
+ return options.forceContentType;
1596
+ }
1597
+ let contentType = headers.get('content-type');
1598
+ if (!contentType || contentType.includes('application/octet-stream')) {
1599
+ let guess = this.guessContentType(options.resource.value);
1600
+ if (guess) {
1601
+ return guess;
2132
1602
  }
2133
-
2134
- return uri;
2135
1603
  }
2136
- /**
2137
- * Tests whether the uri's protocol is supported by the Fetcher.
2138
- * @param uri
2139
- */
2140
-
2141
- }, {
2142
- key: "unsupportedProtocol",
2143
- value: function unsupportedProtocol(uri) {
2144
- var pcol = Uri.protocol(uri);
2145
- return pcol === 'tel' || pcol === 'mailto' || pcol === 'urn';
1604
+ let protocol = Uri.protocol(options.resource.value);
1605
+ if (!contentType && ['file', 'chrome'].includes(protocol)) {
1606
+ return 'text/xml';
2146
1607
  }
2147
- /** Decide on credentials using old XXHR api or new fetch() one
2148
- * @param requestedURI
2149
- * @param options
2150
- */
1608
+ return contentType;
1609
+ }
2151
1610
 
2152
- }, {
2153
- key: "setCredentials",
2154
- value: function setCredentials(requestedURI) {
2155
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
2156
-
2157
- // 2014 CORS problem:
2158
- // XMLHttpRequest cannot load http://www.w3.org/People/Berners-Lee/card.
2159
- // A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin'
2160
- // header when the credentials flag is true.
2161
- // @ Many ontology files under http: and need CORS wildcard ->
2162
- // can't have credentials
2163
- if (options.credentials === undefined) {
2164
- // Caller using new fetch convention
2165
- if (options.withCredentials !== undefined) {
2166
- // XHR style is what Fetcher specified before
2167
- options.credentials = options.withCredentials ? 'include' : 'omit';
2168
- } else {
2169
- options.credentials = 'include'; // default is to be logged on
1611
+ /**
1612
+ * Sends a new request to the specified uri. (Extracted from `onerrorFactory()`)
1613
+ */
1614
+ redirectToProxy(newURI, options) {
1615
+ this.addStatus(options.req, 'BLOCKED -> Cross-site Proxy to <' + newURI + '>');
1616
+ options.proxyUsed = true;
1617
+ const kb = this.store;
1618
+ const oldReq = options.req; // request metadata blank node
1619
+
1620
+ if (!options.noMeta) {
1621
+ kb.add(oldReq, this.ns.link('redirectedTo'), kb.rdfFactory.namedNode(newURI), oldReq);
1622
+ this.addStatus(oldReq, 'redirected to new request'); // why
1623
+ }
1624
+
1625
+ this.requested[options.resource.value] = 'redirected';
1626
+ this.redirectedTo[options.resource.value] = newURI;
1627
+ let newOptions = Object.assign({}, options);
1628
+ newOptions.baseURI = options.resource.value;
1629
+ return this.fetchUri(newURI, newOptions).then(response => {
1630
+ if (!newOptions.noMeta) {
1631
+ kb.add(oldReq, this.ns.link('redirectedRequest'), newOptions.req, this.appNode);
1632
+ }
1633
+ return response;
1634
+ });
1635
+ }
1636
+ setRequestTimeout(uri, options) {
1637
+ return new Promise(resolve => {
1638
+ this.timeouts[uri] = (this.timeouts[uri] || []).concat(setTimeout(() => {
1639
+ if (this.isPending(uri) && !options.retriedWithNoCredentials && !options.proxyUsed) {
1640
+ resolve(this.failFetch(options, `Request to ${uri} timed out`, 'timeout'));
2170
1641
  }
1642
+ }, this.timeout));
1643
+ });
1644
+ }
1645
+ addFetchCallback(uri, callback) {
1646
+ if (!this.fetchCallbacks[uri]) {
1647
+ this.fetchCallbacks[uri] = [callback];
1648
+ } else {
1649
+ this.fetchCallbacks[uri].push(callback);
1650
+ }
1651
+ }
1652
+ acceptString() {
1653
+ let acceptstring = '';
1654
+ for (let mediaType in this.mediatypes) {
1655
+ if (acceptstring !== '') {
1656
+ acceptstring += ', ';
1657
+ }
1658
+ acceptstring += mediaType;
1659
+ for (let property in this.mediatypes[mediaType]) {
1660
+ acceptstring += ';' + property + '=' + this.mediatypes[mediaType][property];
2171
1661
  }
2172
1662
  }
2173
- }]);
2174
-
2175
- return Fetcher;
2176
- }();
2177
-
1663
+ return acceptstring;
1664
+ }
1665
+ // var updatesVia = new $rdf.UpdatesVia(this) // Subscribe to headers
1666
+ // @@@@@@@@ This is turned off because it causes a websocket to be set up for ANY fetch
1667
+ // whether we want to track it ot not. including ontologies loaed though the XSSproxy
1668
+ }
2178
1669
  _defineProperty(Fetcher, "HANDLERS", void 0);
2179
-
2180
1670
  _defineProperty(Fetcher, "CONTENT_TYPE_BY_EXT", void 0);
2181
-
2182
1671
  _defineProperty(Fetcher, "crossSiteProxyTemplate", void 0);
2183
-
2184
- export { Fetcher as default };
2185
1672
  Fetcher.HANDLERS = defaultHandlers;
2186
1673
  Fetcher.CONTENT_TYPE_BY_EXT = CONTENT_TYPE_BY_EXT;