n3 1.24.2 → 1.25.1

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.
package/lib/BaseIRI.js ADDED
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _Util = require("./Util");
8
+ // Do not handle base IRIs without scheme, and currently unsupported cases:
9
+ // - file: IRIs (which could also use backslashes)
10
+ // - IRIs containing /. or /.. or //
11
+ const INVALID_OR_UNSUPPORTED = /^:?[^:?#]*(?:[?#]|$)|^file:|^[^:]*:\/*[^?#]+?\/(?:\.\.?(?:\/|$)|\/)/i;
12
+ const CURRENT = './';
13
+ const PARENT = '../';
14
+ const QUERY = '?';
15
+ const FRAGMENT = '#';
16
+ class BaseIRI {
17
+ constructor(base) {
18
+ this.base = base;
19
+ this._baseLength = 0;
20
+ this._baseMatcher = null;
21
+ this._pathReplacements = new Array(base.length + 1);
22
+ }
23
+ static supports(base) {
24
+ return !INVALID_OR_UNSUPPORTED.test(base);
25
+ }
26
+ _getBaseMatcher() {
27
+ if (this._baseMatcher) return this._baseMatcher;
28
+ if (!BaseIRI.supports(this.base)) return this._baseMatcher = /.^/;
29
+
30
+ // Extract the scheme
31
+ const scheme = /^[^:]*:\/*/.exec(this.base)[0];
32
+ const regexHead = ['^', (0, _Util.escapeRegex)(scheme)];
33
+ const regexTail = [];
34
+
35
+ // Generate a regex for every path segment
36
+ const segments = [],
37
+ segmenter = /[^/?#]*([/?#])/y;
38
+ let segment,
39
+ query = 0,
40
+ fragment = 0,
41
+ last = segmenter.lastIndex = scheme.length;
42
+ while (!query && !fragment && (segment = segmenter.exec(this.base))) {
43
+ // Truncate base resolution path at fragment start
44
+ if (segment[1] === FRAGMENT) fragment = segmenter.lastIndex - 1;else {
45
+ // Create regex that matches the segment
46
+ regexHead.push((0, _Util.escapeRegex)(segment[0]), '(?:');
47
+ regexTail.push(')?');
48
+
49
+ // Create dedicated query string replacement
50
+ if (segment[1] !== QUERY) segments.push(last = segmenter.lastIndex);else {
51
+ query = last = segmenter.lastIndex;
52
+ fragment = this.base.indexOf(FRAGMENT, query);
53
+ this._pathReplacements[query] = QUERY;
54
+ }
55
+ }
56
+ }
57
+
58
+ // Precalculate parent path substitutions
59
+ for (let i = 0; i < segments.length; i++) this._pathReplacements[segments[i]] = PARENT.repeat(segments.length - i - 1);
60
+ this._pathReplacements[segments[segments.length - 1]] = CURRENT;
61
+
62
+ // Add the remainder of the base IRI (without fragment) to the regex
63
+ this._baseLength = fragment > 0 ? fragment : this.base.length;
64
+ regexHead.push((0, _Util.escapeRegex)(this.base.substring(last, this._baseLength)), query ? '(?:#|$)' : '(?:[?#]|$)');
65
+ return this._baseMatcher = new RegExp([...regexHead, ...regexTail].join(''));
66
+ }
67
+ toRelative(iri) {
68
+ // Unsupported or non-matching base IRI
69
+ const match = this._getBaseMatcher().exec(iri);
70
+ if (!match) return iri;
71
+
72
+ // Exact base IRI match
73
+ const length = match[0].length;
74
+ if (length === this._baseLength && length === iri.length) return '';
75
+
76
+ // Parent path match
77
+ const parentPath = this._pathReplacements[length];
78
+ if (parentPath) {
79
+ const suffix = iri.substring(length);
80
+ // Don't abbreviate unsupported path
81
+ if (parentPath !== QUERY && /(?:^|\/)(?:\/|..?(?:[/#?]|$))/.test(suffix) &&
82
+ // fast test
83
+ /^(?:[^#?]*?\/)?(?:\/|\.\.?(?:[/#?]|$))/.test(suffix))
84
+ // rigorous test
85
+ return iri;
86
+ // Omit ./ with fragment or query string
87
+ if (parentPath === CURRENT && /^[^?#]/.test(suffix)) return suffix;
88
+ // Append suffix to relative parent path
89
+ return parentPath + suffix;
90
+ }
91
+
92
+ // Fragment or query string, so include delimiter
93
+ return iri.substring(length - 1);
94
+ }
95
+ }
96
+ exports.default = BaseIRI;
package/lib/N3Lexer.js CHANGED
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _buffer = require("buffer");
8
- var _queueMicrotask = _interopRequireDefault(require("queue-microtask"));
9
8
  var _IRIs = _interopRequireDefault(require("./IRIs"));
10
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
10
  // **N3Lexer** tokenizes N3 documents.
@@ -475,7 +474,7 @@ class N3Lexer {
475
474
  if (typeof input === 'string') {
476
475
  this._input = this._readStartingBom(input);
477
476
  // If a callback was passed, asynchronously call it
478
- if (typeof callback === 'function') (0, _queueMicrotask.default)(() => this._tokenizeToEnd(callback, true));
477
+ if (typeof callback === 'function') queueMicrotask(() => this._tokenizeToEnd(callback, true));
479
478
  // If no callback was passed, tokenize synchronously and return
480
479
  else {
481
480
  const tokens = [];
package/lib/N3Writer.js CHANGED
@@ -7,6 +7,8 @@ exports.default = void 0;
7
7
  var _IRIs = _interopRequireDefault(require("./IRIs"));
8
8
  var _N3DataFactory = _interopRequireWildcard(require("./N3DataFactory"));
9
9
  var _N3Util = require("./N3Util");
10
+ var _BaseIRI = _interopRequireDefault(require("./BaseIRI"));
11
+ var _Util = require("./Util");
10
12
  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); }
11
13
  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; }
12
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -77,8 +79,7 @@ class N3Writer {
77
79
  this._prefixIRIs = Object.create(null);
78
80
  options.prefixes && this.addPrefixes(options.prefixes);
79
81
  if (options.baseIRI) {
80
- this._baseMatcher = new RegExp(`^${escapeRegex(options.baseIRI)}${options.baseIRI.endsWith('/') ? '' : '[#?]'}`);
81
- this._baseLength = options.baseIRI.length;
82
+ this._baseIri = new _BaseIRI.default(options.baseIRI);
82
83
  }
83
84
  } else {
84
85
  this._lineMode = true;
@@ -156,7 +157,9 @@ class N3Writer {
156
157
  }
157
158
  let iri = entity.value;
158
159
  // Use relative IRIs if requested and possible
159
- if (this._baseMatcher && this._baseMatcher.test(iri)) iri = iri.substr(this._baseLength);
160
+ if (this._baseIri) {
161
+ iri = this._baseIri.toRelative(iri);
162
+ }
160
163
  // Escape special characters
161
164
  if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer);
162
165
  // Try to represent the IRI as prefixed name
@@ -283,7 +286,7 @@ class N3Writer {
283
286
  IRIlist += IRIlist ? `|${prefixIRI}` : prefixIRI;
284
287
  prefixList += (prefixList ? '|' : '') + this._prefixIRIs[prefixIRI];
285
288
  }
286
- IRIlist = escapeRegex(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
289
+ IRIlist = (0, _Util.escapeRegex)(IRIlist, /[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
287
290
  this._prefixRegex = new RegExp(`^(?:${prefixList})[^\/]*$|` + `^(${IRIlist})([_a-zA-Z0-9][\\-_a-zA-Z0-9]*)$`);
288
291
  }
289
292
  // End a prefix block with a newline
@@ -379,7 +382,4 @@ function characterReplacer(character) {
379
382
  }
380
383
  }
381
384
  return result;
382
- }
383
- function escapeRegex(regex) {
384
- return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
385
385
  }
package/lib/Util.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.escapeRegex = escapeRegex;
7
+ function escapeRegex(regex) {
8
+ return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
9
+ }
package/lib/index.js CHANGED
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ Object.defineProperty(exports, "BaseIRI", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _BaseIRI.default;
10
+ }
11
+ });
6
12
  Object.defineProperty(exports, "BlankNode", {
7
13
  enumerable: true,
8
14
  get: function () {
@@ -141,6 +147,7 @@ var _N3StreamParser = _interopRequireDefault(require("./N3StreamParser"));
141
147
  var _N3StreamWriter = _interopRequireDefault(require("./N3StreamWriter"));
142
148
  var Util = _interopRequireWildcard(require("./N3Util"));
143
149
  exports.Util = Util;
150
+ var _BaseIRI = _interopRequireDefault(require("./BaseIRI"));
144
151
  var _N3DataFactory = _interopRequireWildcard(require("./N3DataFactory"));
145
152
  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); }
146
153
  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; }
@@ -158,6 +165,7 @@ var _default = exports.default = {
158
165
  StreamWriter: _N3StreamWriter.default,
159
166
  Util,
160
167
  Reasoner: _N3Reasoner.default,
168
+ BaseIRI: _BaseIRI.default,
161
169
  DataFactory: _N3DataFactory.default,
162
170
  Term: _N3DataFactory.Term,
163
171
  NamedNode: _N3DataFactory.NamedNode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n3",
3
- "version": "1.24.2",
3
+ "version": "1.25.1",
4
4
  "description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",
5
5
  "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",
6
6
  "keywords": [
@@ -25,7 +25,6 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "buffer": "^6.0.3",
28
- "queue-microtask": "^1.1.2",
29
28
  "readable-stream": "^4.0.0"
30
29
  },
31
30
  "devDependencies": {
package/src/BaseIRI.js ADDED
@@ -0,0 +1,102 @@
1
+ import { escapeRegex } from './Util';
2
+
3
+ // Do not handle base IRIs without scheme, and currently unsupported cases:
4
+ // - file: IRIs (which could also use backslashes)
5
+ // - IRIs containing /. or /.. or //
6
+ const INVALID_OR_UNSUPPORTED = /^:?[^:?#]*(?:[?#]|$)|^file:|^[^:]*:\/*[^?#]+?\/(?:\.\.?(?:\/|$)|\/)/i;
7
+ const CURRENT = './';
8
+ const PARENT = '../';
9
+ const QUERY = '?';
10
+ const FRAGMENT = '#';
11
+
12
+ export default class BaseIRI {
13
+ constructor(base) {
14
+ this.base = base;
15
+ this._baseLength = 0;
16
+ this._baseMatcher = null;
17
+ this._pathReplacements = new Array(base.length + 1);
18
+ }
19
+
20
+ static supports(base) {
21
+ return !INVALID_OR_UNSUPPORTED.test(base);
22
+ }
23
+
24
+ _getBaseMatcher() {
25
+ if (this._baseMatcher)
26
+ return this._baseMatcher;
27
+ if (!BaseIRI.supports(this.base))
28
+ return this._baseMatcher = /.^/;
29
+
30
+ // Extract the scheme
31
+ const scheme = /^[^:]*:\/*/.exec(this.base)[0];
32
+ const regexHead = ['^', escapeRegex(scheme)];
33
+ const regexTail = [];
34
+
35
+ // Generate a regex for every path segment
36
+ const segments = [], segmenter = /[^/?#]*([/?#])/y;
37
+ let segment, query = 0, fragment = 0, last = segmenter.lastIndex = scheme.length;
38
+ while (!query && !fragment && (segment = segmenter.exec(this.base))) {
39
+ // Truncate base resolution path at fragment start
40
+ if (segment[1] === FRAGMENT)
41
+ fragment = segmenter.lastIndex - 1;
42
+ else {
43
+ // Create regex that matches the segment
44
+ regexHead.push(escapeRegex(segment[0]), '(?:');
45
+ regexTail.push(')?');
46
+
47
+ // Create dedicated query string replacement
48
+ if (segment[1] !== QUERY)
49
+ segments.push(last = segmenter.lastIndex);
50
+ else {
51
+ query = last = segmenter.lastIndex;
52
+ fragment = this.base.indexOf(FRAGMENT, query);
53
+ this._pathReplacements[query] = QUERY;
54
+ }
55
+ }
56
+ }
57
+
58
+ // Precalculate parent path substitutions
59
+ for (let i = 0; i < segments.length; i++)
60
+ this._pathReplacements[segments[i]] = PARENT.repeat(segments.length - i - 1);
61
+ this._pathReplacements[segments[segments.length - 1]] = CURRENT;
62
+
63
+ // Add the remainder of the base IRI (without fragment) to the regex
64
+ this._baseLength = fragment > 0 ? fragment : this.base.length;
65
+ regexHead.push(
66
+ escapeRegex(this.base.substring(last, this._baseLength)),
67
+ query ? '(?:#|$)' : '(?:[?#]|$)',
68
+ );
69
+ return this._baseMatcher = new RegExp([...regexHead, ...regexTail].join(''));
70
+ }
71
+
72
+ toRelative(iri) {
73
+ // Unsupported or non-matching base IRI
74
+ const match = this._getBaseMatcher().exec(iri);
75
+ if (!match)
76
+ return iri;
77
+
78
+ // Exact base IRI match
79
+ const length = match[0].length;
80
+ if (length === this._baseLength && length === iri.length)
81
+ return '';
82
+
83
+ // Parent path match
84
+ const parentPath = this._pathReplacements[length];
85
+ if (parentPath) {
86
+ const suffix = iri.substring(length);
87
+ // Don't abbreviate unsupported path
88
+ if (parentPath !== QUERY &&
89
+ /(?:^|\/)(?:\/|..?(?:[/#?]|$))/.test(suffix) && // fast test
90
+ /^(?:[^#?]*?\/)?(?:\/|\.\.?(?:[/#?]|$))/.test(suffix)) // rigorous test
91
+ return iri;
92
+ // Omit ./ with fragment or query string
93
+ if (parentPath === CURRENT && /^[^?#]/.test(suffix))
94
+ return suffix;
95
+ // Append suffix to relative parent path
96
+ return parentPath + suffix;
97
+ }
98
+
99
+ // Fragment or query string, so include delimiter
100
+ return iri.substring(length - 1);
101
+ }
102
+ }
package/src/N3Lexer.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // **N3Lexer** tokenizes N3 documents.
2
2
  import { Buffer } from 'buffer';
3
- import queueMicrotask from 'queue-microtask';
4
3
  import namespaces from './IRIs';
5
4
 
6
5
  const { xsd } = namespaces;
package/src/N3Writer.js CHANGED
@@ -2,6 +2,8 @@
2
2
  import namespaces from './IRIs';
3
3
  import { default as N3DataFactory, Term } from './N3DataFactory';
4
4
  import { isDefaultGraph } from './N3Util';
5
+ import BaseIRI from './BaseIRI';
6
+ import { escapeRegex } from './Util';
5
7
 
6
8
  const DEFAULTGRAPH = N3DataFactory.defaultGraph();
7
9
 
@@ -58,9 +60,7 @@ export default class N3Writer {
58
60
  this._prefixIRIs = Object.create(null);
59
61
  options.prefixes && this.addPrefixes(options.prefixes);
60
62
  if (options.baseIRI) {
61
- this._baseMatcher = new RegExp(`^${escapeRegex(options.baseIRI)
62
- }${options.baseIRI.endsWith('/') ? '' : '[#?]'}`);
63
- this._baseLength = options.baseIRI.length;
63
+ this._baseIri = new BaseIRI(options.baseIRI);
64
64
  }
65
65
  }
66
66
  else {
@@ -153,8 +153,9 @@ export default class N3Writer {
153
153
  }
154
154
  let iri = entity.value;
155
155
  // Use relative IRIs if requested and possible
156
- if (this._baseMatcher && this._baseMatcher.test(iri))
157
- iri = iri.substr(this._baseLength);
156
+ if (this._baseIri) {
157
+ iri = this._baseIri.toRelative(iri);
158
+ }
158
159
  // Escape special characters
159
160
  if (escape.test(iri))
160
161
  iri = iri.replace(escapeAll, characterReplacer);
@@ -394,7 +395,3 @@ function characterReplacer(character) {
394
395
  }
395
396
  return result;
396
397
  }
397
-
398
- function escapeRegex(regex) {
399
- return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
400
- }
package/src/Util.js ADDED
@@ -0,0 +1,3 @@
1
+ export function escapeRegex(regex) {
2
+ return regex.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
3
+ }
package/src/index.js CHANGED
@@ -7,6 +7,7 @@ import Reasoner, { getRulesFromDataset } from './N3Reasoner';
7
7
  import StreamParser from './N3StreamParser';
8
8
  import StreamWriter from './N3StreamWriter';
9
9
  import * as Util from './N3Util';
10
+ import BaseIRI from './BaseIRI';
10
11
 
11
12
  import {
12
13
  default as DataFactory,
@@ -36,6 +37,7 @@ export {
36
37
  StreamWriter,
37
38
  Util,
38
39
  Reasoner,
40
+ BaseIRI,
39
41
 
40
42
  DataFactory,
41
43
 
@@ -65,6 +67,7 @@ export default {
65
67
  StreamWriter,
66
68
  Util,
67
69
  Reasoner,
70
+ BaseIRI,
68
71
 
69
72
  DataFactory,
70
73