rdflib 2.2.10 → 2.2.12-5f141ca2

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