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