rdflib 2.3.0 → 2.3.1-07daeac2

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/n3parser.js CHANGED
@@ -191,9 +191,19 @@ var ws = new RegExp("^[ \\t]*", 'g');
191
191
  var signed_integer = new RegExp("^[-+]?[0-9]+", 'g');
192
192
  var number_syntax = new RegExp("^([-+]?[0-9]+)(\\.[0-9]+)?([eE][-+]?[0-9]+)?", 'g');
193
193
  var datetime_syntax = new RegExp('^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9](T[0-9][0-9]:[0-9][0-9](:[0-9][0-9](\\.[0-9]*)?)?)?Z?');
194
+
195
+ // Reused in tight loops to detect whitespace or comment after a dot
196
+ var wsOrHash = new RegExp("[\\s#]");
194
197
  var digitstring = new RegExp("^[0-9]+", 'g');
195
198
  var interesting = new RegExp("[\\\\\\r\\n\\\"]", 'g');
196
199
  var langcode = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*", 'g');
200
+
201
+ // Returns true when a dot at position i should terminate a name,
202
+ // i.e., when the next character is whitespace, a comment start, or EOF
203
+ function dotTerminatesName(str, i) {
204
+ var next = str.charAt(i + 1);
205
+ return next === '' || wsOrHash.test(next);
206
+ }
197
207
  function createSinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) {
198
208
  return new SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why);
199
209
  }
@@ -682,6 +692,16 @@ class SinkParser {
682
692
  if (j < 0) {
683
693
  throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when ']' expected after [ <propertyList>");
684
694
  }
695
+ if (str.slice(j, j + 1) == ".") {
696
+ // If a dot is found after a blank node, treat it as a statement terminator.
697
+ // Do NOT consume the '.' here: statement terminators are handled centrally by
698
+ // checkDot() (called by directiveOrStatement after statement()). Consuming the dot
699
+ // locally would bypass that unified logic and could cause inconsistencies.
700
+ // We do consume ']' below because it is a structural closer of the blank node,
701
+ // not a statement terminator.
702
+ res.push(subj);
703
+ return j; // leave '.' for checkDot()
704
+ }
685
705
  if (str.slice(j, j + 1) != "]") {
686
706
  throw BadSyntax(this._thisDoc, this.lines, str, j, "']' expected");
687
707
  }
@@ -1130,7 +1150,17 @@ class SinkParser {
1130
1150
  return -1;
1131
1151
  }
1132
1152
  var i = j;
1133
- while (i < pyjslib_len(str) && _notNameChars.indexOf(str.charAt(i)) < 0) {
1153
+ while (i < pyjslib_len(str)) {
1154
+ var c = str.charAt(i);
1155
+ if (c === '.') {
1156
+ if (dotTerminatesName(str, i)) {
1157
+ break; // treat as statement terminator, not part of name
1158
+ }
1159
+ // else: accept '.' as part of name
1160
+ } else if (_notNameChars.indexOf(c) >= 0) {
1161
+ // Other invalid characters terminate the name
1162
+ break;
1163
+ }
1134
1164
  var i = i + 1;
1135
1165
  }
1136
1166
  res.push(str.slice(j, i));
@@ -1156,12 +1186,15 @@ class SinkParser {
1156
1186
  var i = i + 1;
1157
1187
  while (i < pyjslib_len(str)) {
1158
1188
  var c = str.charAt(i);
1159
- if (_notNameChars.indexOf(c) < 0) {
1160
- var ln = ln + c;
1161
- var i = i + 1;
1162
- } else {
1189
+ if (c === '.') {
1190
+ if (dotTerminatesName(str, i)) {
1191
+ break; // dot ends the name here
1192
+ }
1193
+ } else if (_notNameChars.indexOf(c) >= 0) {
1163
1194
  break;
1164
1195
  }
1196
+ var ln = ln + c;
1197
+ var i = i + 1;
1165
1198
  }
1166
1199
  } else {
1167
1200
  var ln = "";
@@ -1172,12 +1205,15 @@ class SinkParser {
1172
1205
  var ln = "";
1173
1206
  while (i < pyjslib_len(str)) {
1174
1207
  var c = str.charAt(i);
1175
- if (_notNameChars.indexOf(c) < 0) {
1176
- var ln = ln + c;
1177
- var i = i + 1;
1178
- } else {
1208
+ if (c === '.') {
1209
+ if (dotTerminatesName(str, i)) {
1210
+ break; // dot ends the name here
1211
+ }
1212
+ } else if (_notNameChars.indexOf(c) >= 0) {
1179
1213
  break;
1180
1214
  }
1215
+ var ln = ln + c;
1216
+ var i = i + 1;
1181
1217
  }
1182
1218
  res.push(new pyjslib_Tuple([pfx, ln]));
1183
1219
  return i;
package/lib/parse.js CHANGED
@@ -29,9 +29,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
29
29
  * @param contentType - The MIME content type string for the input - defaults to text/turtle
30
30
  * @param [callback] - The callback to call when the data has been loaded
31
31
  */
32
- function parse(str, kb, base) {
33
- let contentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'text/turtle';
34
- let callback = arguments.length > 4 ? arguments[4] : undefined;
32
+ function parse(str, kb, base, contentType = 'text/turtle', callback) {
35
33
  contentType = contentType || _types.TurtleContentType;
36
34
  contentType = contentType.split(';')[0];
37
35
  try {
package/lib/serialize.js CHANGED
@@ -47,7 +47,8 @@ contentType, callback, options) {
47
47
  return executeCallback(null, documentString);
48
48
  case _types.TurtleContentType:
49
49
  case _types.TurtleLegacyContentType:
50
- sz.setFlags('si'); // Suppress = for sameAs and => for implies
50
+ // Suppress = for sameAs and => for implies; preserve any user-specified flags (e.g., 'o')
51
+ sz.setFlags('si' + (opts.flags ? ' ' + opts.flags : ''));
51
52
  documentString = sz.statementsToN3(newSts);
52
53
  return executeCallback(null, documentString);
53
54
  case _types.NTriplesContentType:
@@ -55,7 +56,8 @@ contentType, callback, options) {
55
56
  documentString = sz.statementsToNTriples(newSts);
56
57
  return executeCallback(null, documentString);
57
58
  case _types.JSONLDContentType:
58
- sz.setFlags('si dr'); // turtle + dr (means no default, no relative prefix)
59
+ // turtle + dr (means no default, no relative prefix); preserve user flags
60
+ sz.setFlags('si dr' + (opts.flags ? ' ' + opts.flags : ''));
59
61
  documentString = sz.statementsToJsonld(newSts); // convert via turtle
60
62
  return executeCallback(null, documentString);
61
63
  case _types.NQuadsContentType:
@@ -13,15 +13,21 @@ export class Serializer {
13
13
  store: any;
14
14
  rdfFactory: any;
15
15
  xsd: {
16
- boolean: NamedNode;
17
- dateTime: NamedNode;
18
- decimal: NamedNode;
19
- double: NamedNode;
20
- integer: NamedNode;
21
- langString: NamedNode;
22
- string: NamedNode;
16
+ boolean: import("./named-node").default;
17
+ dateTime: import("./named-node").default;
18
+ decimal: import("./named-node").default;
19
+ double: import("./named-node").default;
20
+ integer: import("./named-node").default;
21
+ langString: import("./named-node").default;
22
+ string: import("./named-node").default;
23
23
  };
24
24
  setBase(base: any): Serializer;
25
+ /**
26
+ * Set serializer behavior flags. Letters can be combined with spaces.
27
+ * Examples: 'si', 'deinprstux', 'si dr', 'o'.
28
+ * Notable flags:
29
+ * - 'o': do not abbreviate to a prefixed name when the local part contains a dot
30
+ */
25
31
  setFlags(flags: any): Serializer;
26
32
  toStr(x: any): any;
27
33
  fromStr(s: any): any;
@@ -51,6 +57,7 @@ export class Serializer {
51
57
  toN3(f: any): string;
52
58
  _notQNameChars: string;
53
59
  _notNameChars: string;
60
+ isValidPNLocal(local: any): boolean;
54
61
  explicitURI(uri: any): string;
55
62
  statementsToNTriples(sts: any): string;
56
63
  statementsToN3(sts: any): string;
@@ -65,4 +72,3 @@ export class Serializer {
65
72
  statementsToXML(sts: any): string;
66
73
  statementsToJsonld(sts: any): string;
67
74
  }
68
- import NamedNode from './named-node';
package/lib/serializer.js CHANGED
@@ -7,14 +7,12 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.Serializer = void 0;
8
8
  exports.default = createSerializer;
9
9
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
- var _namedNode = _interopRequireDefault(require("./named-node"));
11
- var _blankNode = _interopRequireDefault(require("./blank-node"));
10
+ var ttl2jsonld = _interopRequireWildcard(require("@frogcat/ttl2jsonld"));
11
+ var _solidNamespace = _interopRequireDefault(require("solid-namespace"));
12
+ var _canonicalDataFactory = _interopRequireDefault(require("./factories/canonical-data-factory"));
12
13
  var Uri = _interopRequireWildcard(require("./uri"));
13
14
  var Util = _interopRequireWildcard(require("./utils-js"));
14
- var _canonicalDataFactory = _interopRequireDefault(require("./factories/canonical-data-factory"));
15
15
  var _xsd = require("./xsd");
16
- var _solidNamespace = _interopRequireDefault(require("solid-namespace"));
17
- var ttl2jsonld = _interopRequireWildcard(require("@frogcat/ttl2jsonld"));
18
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
19
17
  /* Serialization of RDF Graphs
20
18
  **
@@ -30,7 +28,8 @@ function createSerializer(store) {
30
28
  ;
31
29
  class Serializer {
32
30
  constructor(store) {
33
- (0, _defineProperty2.default)(this, "_notQNameChars", '\t\r\n !"#$%&\'()*.,+/;<=>?@[\\]^`{|}~');
31
+ (0, _defineProperty2.default)(this, "_notQNameChars", '\t\r\n !"#$%&\'()*,+/;<=>?@[\\]^`{|}~');
32
+ // issue#228
34
33
  (0, _defineProperty2.default)(this, "_notNameChars", this._notQNameChars + ':');
35
34
  // stringToN3: String escaping for N3
36
35
  (0, _defineProperty2.default)(this, "validPrefix", new RegExp(/^[a-zA-Z][a-zA-Z0-9]*$/));
@@ -52,7 +51,7 @@ class Serializer {
52
51
 
53
52
  this.namespacesUsed = []; // Count actually used and so needed in @prefixes
54
53
  this.keywords = ['a']; // The only one we generate at the moment
55
- this.prefixchars = 'abcdefghijklmnopqustuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
54
+ this.prefixchars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
56
55
  this.incoming = null; // Array not calculated yet
57
56
  this.formulas = []; // remembering original formulae from hashes
58
57
  this.store = store;
@@ -63,6 +62,13 @@ class Serializer {
63
62
  this.base = base;
64
63
  return this;
65
64
  }
65
+
66
+ /**
67
+ * Set serializer behavior flags. Letters can be combined with spaces.
68
+ * Examples: 'si', 'deinprstux', 'si dr', 'o'.
69
+ * Notable flags:
70
+ * - 'o': do not abbreviate to a prefixed name when the local part contains a dot
71
+ */
66
72
  setFlags(flags) {
67
73
  this.flags = flags || '';
68
74
  return this;
@@ -172,7 +178,7 @@ class Serializer {
172
178
  if (slash >= 0) p = p.slice(slash + 1);
173
179
  var i = 0;
174
180
  while (i < p.length) {
175
- if (this.prefixchars.indexOf(p[i])) {
181
+ if (this.prefixchars.indexOf(p[i]) >= 0) {
176
182
  i++;
177
183
  } else {
178
184
  break;
@@ -253,6 +259,28 @@ class Serializer {
253
259
  toN3(f) {
254
260
  return this.statementsToN3(f.statements);
255
261
  }
262
+ // Validate if a string is a valid PN_LOCAL per Turtle 1.1 spec
263
+ // Allows dots inside the local name but not as trailing character
264
+ // Also allows empty local names (for URIs ending in / or #)
265
+ isValidPNLocal(local) {
266
+ // Empty local name is valid (e.g., ex: for http://example.com/)
267
+ if (local.length === 0) return true;
268
+
269
+ // Cannot end with a dot
270
+ if (local[local.length - 1] === '.') return false;
271
+
272
+ // Check each character (allow dots mid-string)
273
+ for (var i = 0; i < local.length; i++) {
274
+ var ch = local[i];
275
+ // Dot is allowed unless it's the last character (checked above)
276
+ if (ch === '.') continue;
277
+ // Other characters must not be in the blacklist
278
+ if (this._notNameChars.indexOf(ch) >= 0) {
279
+ return false;
280
+ }
281
+ }
282
+ return true;
283
+ }
256
284
  explicitURI(uri) {
257
285
  if (this.flags.indexOf('r') < 0 && this.base) {
258
286
  uri = Uri.refTo(this.base, uri);
@@ -615,13 +643,17 @@ class Serializer {
615
643
  if (j >= 0 && this.flags.indexOf('p') < 0 && (
616
644
  // Can split at namespace but only if http[s]: URI or file: or ws[s] (why not others?)
617
645
  uri.indexOf('http') === 0 || uri.indexOf('ws') === 0 || uri.indexOf('file') === 0)) {
618
- var canSplit = true;
619
- for (var k = j + 1; k < uri.length; k++) {
620
- if (this._notNameChars.indexOf(uri[k]) >= 0) {
621
- canSplit = false;
622
- break;
623
- }
624
- }
646
+ var localid = uri.slice(j + 1);
647
+ var namesp = uri.slice(0, j + 1);
648
+ // Don't split if namespace is just the protocol (e.g., https://)
649
+ // A valid namespace should have content after the protocol
650
+ var minNamespaceLength = uri.indexOf('://') + 4; // e.g., "http://x" minimum
651
+ // Also don't split if namespace is the base directory (would serialize as relative URI)
652
+ var baseDir = this.base ? this.base.slice(0, Math.max(this.base.lastIndexOf('/'), this.base.lastIndexOf('#')) + 1) : null;
653
+ var namespaceIsBaseDir = baseDir && namesp === baseDir;
654
+ // If flag 'o' is present, forbid dots in local part when abbreviating
655
+ var forbidDotLocal = this.flags.indexOf('o') >= 0 && localid.indexOf('.') >= 0;
656
+ var canSplit = !namespaceIsBaseDir && !forbidDotLocal && namesp.length > minNamespaceLength && this.isValidPNLocal(localid);
625
657
  /*
626
658
  if (uri.slice(0, j + 1) === this.base + '#') { // base-relative
627
659
  if (canSplit) {
@@ -632,8 +664,6 @@ class Serializer {
632
664
  }
633
665
  */
634
666
  if (canSplit) {
635
- var localid = uri.slice(j + 1);
636
- var namesp = uri.slice(0, j + 1);
637
667
  if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
638
668
  // d -> suppress default
639
669
  if (this.flags.indexOf('k') >= 0 && this.keyords.indexOf(localid) < 0) {
@@ -854,7 +884,7 @@ class Serializer {
854
884
  results = results.concat(['<' + t + ' rdf:resource="' + relURI(st.object) + '"/>']);
855
885
  break;
856
886
  case 'Literal':
857
- results = results.concat(['<' + t + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + t + '>']);
887
+ results = results.concat(['<' + t + (st.object.language ? ' xml:lang="' + st.object.language + '"' : st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"') + '>' + escapeForXML(st.object.value) + '</' + t + '>']);
858
888
  break;
859
889
  case 'Collection':
860
890
  results = results.concat(['<' + t + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + t + '>']);
@@ -905,7 +935,7 @@ class Serializer {
905
935
  results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + relURI(st.object) + '"/>']);
906
936
  break;
907
937
  case 'Literal':
908
- results = results.concat(['<' + qname(st.predicate) + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.value) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + qname(st.predicate) + '>']);
938
+ results = results.concat(['<' + qname(st.predicate) + (st.object.language ? ' xml:lang="' + st.object.language + '"' : st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.value) + '"') + '>' + escapeForXML(st.object.value) + '</' + qname(st.predicate) + '>']);
909
939
  break;
910
940
  case 'Collection':
911
941
  results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
package/lib/store.js CHANGED
@@ -100,8 +100,7 @@ class IndexedFormula extends _formula.default {
100
100
  * @param [opts.rdfArrayRemove] - Function which removes statements from the store
101
101
  * @param [opts.dataCallback] - Callback when a statement is added to the store, will not trigger when adding duplicates
102
102
  */
103
- constructor(features) {
104
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
103
+ constructor(features, opts = {}) {
105
104
  super(undefined, undefined, undefined, undefined, opts);
106
105
  // IN future - allow pass array of statements to constructor
107
106
  /**
@@ -387,8 +387,7 @@ class UpdateManager {
387
387
  /**
388
388
  * @private
389
389
  */
390
- fire(uri, query, callbackFunction) {
391
- let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
390
+ fire(uri, query, callbackFunction, options = {}) {
392
391
  return Promise.resolve().then(() => {
393
392
  if (!uri) {
394
393
  throw new Error('No URI given for remote editing operation: ' + query);
@@ -676,8 +675,7 @@ class UpdateManager {
676
675
  * @param insertions - Statement or statements to be inserted.
677
676
  * @returns a promise
678
677
  */
679
- updateMany(deletions) {
680
- let insertions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
678
+ updateMany(deletions, insertions = []) {
681
679
  const docs = deletions.concat(insertions).map(st => st.why);
682
680
  const thisUpdater = this;
683
681
  const uniqueDocs = [];
@@ -790,8 +788,7 @@ _:patch
790
788
  * OR returns a promise
791
789
  * @param options - Options for the fetch call
792
790
  */
793
- update(deletions, insertions, callback, secondTry) {
794
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
791
+ update(deletions, insertions, callback, secondTry, options = {}) {
795
792
  if (!callback) {
796
793
  var thisUpdater = this;
797
794
  return new Promise(function (resolve, reject) {
@@ -934,8 +931,7 @@ _:patch
934
931
  callback(undefined, false, 'Exception in update: ' + e + '\n' + Util.stackString(e));
935
932
  }
936
933
  }
937
- updateDav(doc, ds, is, callbackFunction) {
938
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
934
+ updateDav(doc, ds, is, callbackFunction, options = {}) {
939
935
  let kb = this.store;
940
936
  // The code below is derived from Kenny's UpdateCenter.js
941
937
  var request = kb.any(doc, this.ns.link('request'));
@@ -992,8 +988,7 @@ _:patch
992
988
  * @param callbackFunction
993
989
  * @param options
994
990
  */
995
- updateLocalFile(doc, ds, is, callbackFunction) {
996
- let options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
991
+ updateLocalFile(doc, ds, is, callbackFunction, options = {}) {
997
992
  const kb = this.store;
998
993
  // console.log('Writing back to local file\n')
999
994
 
package/lib/utils.js CHANGED
@@ -89,8 +89,7 @@ function arrayToStatements(rdfFactory, subject, data) {
89
89
  }, subject);
90
90
  return statements;
91
91
  }
92
- function ArrayIndexOf(arr, item) {
93
- let i = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
92
+ function ArrayIndexOf(arr, item, i = 0) {
94
93
  var length = arr.length;
95
94
  if (i < 0) i = length + i;
96
95
  for (; i < length; i++) {
package/lib/variable.js CHANGED
@@ -23,8 +23,7 @@ class Variable extends _nodeInternal.default {
23
23
  * Initializes this variable
24
24
  * @param name The variable's name
25
25
  */
26
- constructor() {
27
- let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
26
+ constructor(name = '') {
28
27
  super(name);
29
28
  (0, _defineProperty2.default)(this, "termType", _types.VariableTermType);
30
29
  /** The base string for a variable's name */
package/lib/xsd.js CHANGED
@@ -7,8 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.createXSD = createXSD;
8
8
  exports.default = void 0;
9
9
  var _canonicalDataFactory = _interopRequireDefault(require("./factories/canonical-data-factory"));
10
- function createXSD() {
11
- let localFactory = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _canonicalDataFactory.default;
10
+ function createXSD(localFactory = _canonicalDataFactory.default) {
12
11
  return {
13
12
  boolean: localFactory.namedNode("http://www.w3.org/2001/XMLSchema#boolean"),
14
13
  dateTime: localFactory.namedNode("http://www.w3.org/2001/XMLSchema#dateTime"),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rdflib",
3
3
  "description": "an RDF library for node.js. Suitable for client and server side.",
4
- "version": "2.3.0",
4
+ "version": "2.3.1-07daeac2",
5
5
  "private": false,
6
6
  "browserslist": [
7
7
  "> 0.5%"
@@ -44,49 +44,50 @@
44
44
  "homepage": "http://github.com/linkeddata/rdflib.js",
45
45
  "bugs": "http://github.com/linkeddata/rdflib.js/issues",
46
46
  "dependencies": {
47
- "@babel/runtime": "^7.26.9",
47
+ "@babel/runtime": "^7.28.4",
48
48
  "@frogcat/ttl2jsonld": "^0.0.10",
49
49
  "@rdfjs/types": "^2.0.1",
50
50
  "@xmldom/xmldom": "^0.8.10",
51
- "cross-fetch": "^3.2.0",
52
- "jsonld": "^8.3.3",
53
- "n3": "^1.23.1",
51
+ "cross-fetch": "^4.1.0",
52
+ "jsonld": "^9.0.0",
53
+ "n3": "^1.26.0",
54
54
  "solid-namespace": "^0.5.4"
55
55
  },
56
56
  "devDependencies": {
57
- "@babel/cli": "^7.26.4",
58
- "@babel/core": "^7.26.9",
57
+ "@babel/cli": "^7.28.3",
58
+ "@babel/core": "^7.28.5",
59
59
  "@babel/plugin-proposal-class-properties": "^7.18.6",
60
- "@babel/plugin-transform-runtime": "^7.26.9",
61
- "@babel/preset-env": "^7.26.9",
62
- "@babel/preset-typescript": "^7.26.0",
63
- "@babel/register": "^7.25.9",
60
+ "@babel/plugin-transform-runtime": "^7.28.5",
61
+ "@babel/preset-env": "^7.28.5",
62
+ "@babel/preset-typescript": "^7.28.5",
63
+ "@babel/register": "^7.28.3",
64
64
  "@types/chai": "^4.3.20",
65
65
  "@types/dirty-chai": "^2.0.5",
66
- "@types/express": "^4.17.21",
66
+ "@types/express": "^4.17.25",
67
67
  "@types/jsonld": "^1.5.15",
68
68
  "@types/mocha": "^10.0.10",
69
69
  "@types/sinon-chai": "^3.2.12",
70
- "babel-loader": "^9.2.1",
70
+ "babel-loader": "^10.0.0",
71
71
  "chai": "^4.5.0",
72
- "diff": "^5.2.0",
72
+ "colors": "^1.4.0",
73
+ "diff": "^8.0.2",
73
74
  "dirty-chai": "^2.0.1",
74
- "eslint": "^9.20.1",
75
- "fs-grep": "0.0.5",
76
- "locate-path": "^7.2.0",
77
- "mocha": "^10.8.2",
75
+ "eslint": "^9.39.1",
76
+ "locate-path": "^8.0.0",
77
+ "mocha": "^11.7.5",
78
78
  "nock": "^13.5.6",
79
79
  "node-fetch": "^3.3.2",
80
- "node-polyfill-webpack-plugin": "^2.0.1",
81
- "sinon": "^15.2.0",
80
+ "node-polyfill-webpack-plugin": "^4.1.0",
81
+ "rimraf": "^6.1.2",
82
+ "sinon": "^21.0.0",
82
83
  "sinon-chai": "^3.7.0",
83
- "source-map-loader": "^4.0.2",
84
+ "source-map-loader": "^5.0.0",
84
85
  "ts-node": "^10.9.2",
85
- "typedoc": "^0.25.13",
86
+ "typedoc": "^0.28.15",
86
87
  "typescript": "^5.0.4",
87
- "webpack": "^5.98.0",
88
- "webpack-cli": "^5.1.4",
89
- "webpack-dev-server": "^4.15.2"
88
+ "webpack": "^5.103.0",
89
+ "webpack-cli": "^6.0.1",
90
+ "webpack-dev-server": "^5.2.2"
90
91
  },
91
92
  "scripts": {
92
93
  "build": "babel src --extensions \".ts,.js\" -d lib",
@@ -101,8 +102,8 @@
101
102
  "test": "npm run test:unit && npm run test:serialize && npm run test:types",
102
103
  "test:clean": "rimraf tests/serialize/,*",
103
104
  "test:serialize": "npm run build && npm run test:serialize:all && npm run test:clean",
104
- "test:serialize:all": "npm run test:serialize:1 && npm run test:serialize:2 && npm run test:serialize:3 && npm run test:serialize:4 && npm run test:serialize:5 && npm run test:serialize:6 && npm run test:serialize:7 && npm run test:serialize:8 && npm run test:serialize:10 && npm run test:serialize:11 && npm run test:serialize:12 && npm run test:serialize:13 && npm run test:serialize:14 && npm run test:serialize:15",
105
- "test:serialize:1": "cd ./tests/serialize && node ./data.js -in=t1.ttl -format=application/rdf+xml -out=,t1.xml && fs-grep http://www.w3.org/2001/XMLSchema#integer ,t1.xml",
105
+ "test:serialize:all": "npm run test:serialize:1 && npm run test:serialize:2 && npm run test:serialize:3 && npm run test:serialize:4 && npm run test:serialize:5 && npm run test:serialize:6 && npm run test:serialize:7 && npm run test:serialize:8 && npm run test:serialize:10 && npm run test:serialize:11 && npm run test:serialize:12 && npm run test:serialize:13 && npm run test:serialize:14 && npm run test:serialize:15 && npm run test:serialize:16 && npm run test:serialize:17 && npm run test:serialize:18",
106
+ "test:serialize:1": "cd ./tests/serialize && node ./data.js -in=t1.ttl -format=application/rdf+xml -out=,t1.xml && node diff ,t1.xml t1-ref.xml",
106
107
  "test:serialize:2": "cd ./tests/serialize && node ./data.js -in=t2.ttl -format=application/rdf+xml -out=,t2.xml && node diff ,t2.xml t2-ref.xml",
107
108
  "test:serialize:3": "cd ./tests/serialize && node ./data.js -in=t3.ttl -format=application/rdf+xml -out=,t3.xml && node diff ,t3.xml t3-ref.xml",
108
109
  "test:serialize:4": "cd ./tests/serialize && node ./data.js -in=t3.ttl -out=,t4.ttl && node diff ,t4.ttl t4-ref.ttl",
@@ -117,6 +118,8 @@
117
118
  "test:serialize:14": "cd ./tests/serialize && node ./data.js -in=t14.html -format=text/turtle -out=,t14.ttl && node diff ,t14.ttl t14-ref.ttl",
118
119
  "test:serialize:15": "cd ./tests/serialize && node ./data.js -in=t15.html -format=text/turtle -out=,t15.ttl && node diff ,t15.ttl t15-ref.ttl",
119
120
  "test:serialize:16": "cd ./tests/serialize && node ./data.js -in=t1.ttl -format=application/ld+json -out=,t1.jsonld && node diff ,t1.jsonld t16-ref.jsonld",
121
+ "test:serialize:17": "cd ./tests/serialize && node ./data.js -in=t17.ttl -format=application/rdf+xml -out=,t17.xml && node diff ,t17.xml t17-ref.xml",
122
+ "test:serialize:18": "cd ./tests/serialize && node ./data.js -in=t18.ttl -format=application/rdf+xml -out=,t18.xml && node diff ,t18.xml t18-ref.xml",
120
123
  "test:types": "tsc --noEmit --target es2019 --moduleResolution node tests/types/*.ts",
121
124
  "test:unit": "mocha --growl --require ./tests/babel-register.js tests/unit/**-test.*",
122
125
  "test:unit:egp": "mocha --require ./tests/babel-register.js tests/unit/fetcher-egp-test.js",
package/src/n3parser.js CHANGED
@@ -212,10 +212,20 @@ var signed_integer = new RegExp("^[-+]?[0-9]+", 'g');
212
212
  var number_syntax = new RegExp("^([-+]?[0-9]+)(\\.[0-9]+)?([eE][-+]?[0-9]+)?", 'g');
213
213
  var datetime_syntax = new RegExp('^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9](T[0-9][0-9]:[0-9][0-9](:[0-9][0-9](\\.[0-9]*)?)?)?Z?');
214
214
 
215
+ // Reused in tight loops to detect whitespace or comment after a dot
216
+ var wsOrHash = new RegExp("[\\s#]");
217
+
215
218
  var digitstring = new RegExp("^[0-9]+", 'g');
216
219
  var interesting = new RegExp("[\\\\\\r\\n\\\"]", 'g');
217
220
  var langcode = new RegExp("^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*", 'g');
218
221
 
222
+ // Returns true when a dot at position i should terminate a name,
223
+ // i.e., when the next character is whitespace, a comment start, or EOF
224
+ function dotTerminatesName(str, i) {
225
+ var next = str.charAt(i + 1);
226
+ return next === '' || wsOrHash.test(next);
227
+ }
228
+
219
229
  function createSinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why) {
220
230
  return new SinkParser(store, openFormula, thisDoc, baseURI, genPrefix, metaURI, flags, why);
221
231
  }
@@ -554,7 +564,7 @@ export class SinkParser {
554
564
  <- prop -<
555
565
  _operator_*/
556
566
 
557
- var j = this.skipSpace(str, i);
567
+ var j = this.skipSpace(str, i);
558
568
  if ((j < 0)) {
559
569
  return j;
560
570
  }
@@ -703,22 +713,17 @@ export class SinkParser {
703
713
  if ((j >= 0)) {
704
714
  var subj = objs[0];
705
715
  if ((pyjslib_len(objs) > 1)) {
706
-
707
716
  var __obj = new pyjslib_Iterator(objs);
708
717
  try {
709
718
  while (true) {
710
719
  var obj = __obj.next();
711
-
712
-
713
720
  this.makeStatement(new pyjslib_Tuple([this._context, this._store.sym(DAML_sameAs_URI), subj, obj]));
714
-
715
721
  }
716
722
  } catch (e) {
717
723
  if (e != StopIteration) {
718
724
  throw e;
719
725
  }
720
726
  }
721
-
722
727
  }
723
728
  var j = this.skipSpace(str, j);
724
729
  if ((j < 0)) {
@@ -743,6 +748,16 @@ export class SinkParser {
743
748
  if ((j < 0)) {
744
749
  throw BadSyntax(this._thisDoc, this.lines, str, i, "EOF when ']' expected after [ <propertyList>");
745
750
  }
751
+ if ((str.slice( j, ( j + 1 ) ) == ".")) {
752
+ // If a dot is found after a blank node, treat it as a statement terminator.
753
+ // Do NOT consume the '.' here: statement terminators are handled centrally by
754
+ // checkDot() (called by directiveOrStatement after statement()). Consuming the dot
755
+ // locally would bypass that unified logic and could cause inconsistencies.
756
+ // We do consume ']' below because it is a structural closer of the blank node,
757
+ // not a statement terminator.
758
+ res.push(subj);
759
+ return j; // leave '.' for checkDot()
760
+ }
746
761
  if ((str.slice( j, ( j + 1 ) ) != "]")) {
747
762
  throw BadSyntax(this._thisDoc, this.lines, str, j, "']' expected");
748
763
  }
@@ -1208,7 +1223,17 @@ export class SinkParser {
1208
1223
  return -1;
1209
1224
  }
1210
1225
  var i = j;
1211
- while ((i < pyjslib_len(str)) && (_notNameChars.indexOf(str.charAt(i)) < 0)) {
1226
+ while ((i < pyjslib_len(str))) {
1227
+ var c = str.charAt(i);
1228
+ if (c === '.') {
1229
+ if (dotTerminatesName(str, i)) {
1230
+ break; // treat as statement terminator, not part of name
1231
+ }
1232
+ // else: accept '.' as part of name
1233
+ } else if (_notNameChars.indexOf(c) >= 0) {
1234
+ // Other invalid characters terminate the name
1235
+ break;
1236
+ }
1212
1237
  var i = ( i + 1 ) ;
1213
1238
  }
1214
1239
  res.push(str.slice( j, i));
@@ -1235,13 +1260,15 @@ export class SinkParser {
1235
1260
  var i = ( i + 1 ) ;
1236
1261
  while ((i < pyjslib_len(str))) {
1237
1262
  var c = str.charAt(i);
1238
- if ((_notNameChars.indexOf(c) < 0)) {
1239
- var ln = ( ln + c ) ;
1240
- var i = ( i + 1 ) ;
1241
- }
1242
- else {
1263
+ if (c === '.') {
1264
+ if (dotTerminatesName(str, i)) {
1265
+ break; // dot ends the name here
1266
+ }
1267
+ } else if (_notNameChars.indexOf(c) >= 0) {
1243
1268
  break;
1244
1269
  }
1270
+ var ln = ( ln + c ) ;
1271
+ var i = ( i + 1 ) ;
1245
1272
  }
1246
1273
  }
1247
1274
  else {
@@ -1253,13 +1280,15 @@ export class SinkParser {
1253
1280
  var ln = "";
1254
1281
  while ((i < pyjslib_len(str))) {
1255
1282
  var c = str.charAt(i);
1256
- if ((_notNameChars.indexOf(c) < 0)) {
1257
- var ln = ( ln + c ) ;
1258
- var i = ( i + 1 ) ;
1259
- }
1260
- else {
1283
+ if (c === '.') {
1284
+ if (dotTerminatesName(str, i)) {
1285
+ break; // dot ends the name here
1286
+ }
1287
+ } else if (_notNameChars.indexOf(c) >= 0) {
1261
1288
  break;
1262
1289
  }
1290
+ var ln = ( ln + c ) ;
1291
+ var i = ( i + 1 ) ;
1263
1292
  }
1264
1293
  res.push(new pyjslib_Tuple([pfx, ln]));
1265
1294
  return i;