rdflib 2.2.34 → 2.2.35-0ebb696c

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