@netwerk-digitaal-erfgoed/network-of-terms-query 6.2.9 → 6.2.11
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/CHANGELOG.md +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +55 -4
- package/dist/test-utils.js +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/query.ts +62 -7
- package/src/test-utils.ts +1 -1
- package/test/query.test.ts +3 -2
- package/vite.config.ts +5 -5
package/CHANGELOG.md
CHANGED
package/dist/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAGA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAGA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,IAAI,EAAoB,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,SAAS,EAAiB,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAkDrD,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,YAAY,GAAG,WAAW,CAAC;AAE7D,qBAAa,aAAa;IAEtB,QAAQ,CAAC,MAAM,EAAE,WAAW;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM;gBADtB,MAAM,EAAE,WAAW,EACnB,cAAc,EAAE,MAAM;CAElC;AAED,qBAAa,KAAK;IAEd,QAAQ,CAAC,YAAY,EAAE,YAAY;IACnC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;gBADb,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,IAAI,EAAE;CAEzB;AAED,qBAAa,KAAK;IAEd,QAAQ,CAAC,YAAY,EAAE,YAAY;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM;gBADf,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,MAAM;CAE3B;AAED,qBAAa,YAAa,SAAQ,KAAK;aAEjB,YAAY,EAAE,YAAY;gBAA1B,YAAY,EAAE,YAAY,EAC5C,SAAS,EAAE,MAAM;CAIpB;AAED,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,GAAE;QAAE,QAAQ,CAAC,EAAE,WAAW,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAA;KAAO;IAK1E;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,EAAE;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,KAAK,EAAE,MAAM,CAAC;KACf,GAAG;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAA;KAAE;IAarE,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC;IAyBnB,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM;IAWjE,GAAG,CACP,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,YAAY,EAC1B,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAM,GACtC,OAAO,CAAC,aAAa,CAAC;CAuG1B"}
|
package/dist/query.js
CHANGED
|
@@ -10,6 +10,46 @@ import { BindingsFactory } from '@comunica/utils-bindings-factory';
|
|
|
10
10
|
import { DataFactory } from 'rdf-data-factory';
|
|
11
11
|
import { sourceQueriesHistogram } from './instrumentation.js';
|
|
12
12
|
import { config } from './config.js';
|
|
13
|
+
/**
|
|
14
|
+
* Check if a query requires string substitution instead of initialBindings.
|
|
15
|
+
* Workaround for Comunica v5 traqula bug that crashes with:
|
|
16
|
+
* - SERVICE clauses
|
|
17
|
+
* - VALUES combination
|
|
18
|
+
*/
|
|
19
|
+
function requiresStringSubstitution(query) {
|
|
20
|
+
const hasService = /\bSERVICE\b/i.test(query);
|
|
21
|
+
const hasValues = /\bVALUES\b/i.test(query);
|
|
22
|
+
return hasService || hasValues;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Substitute bindings directly into a SPARQL query string.
|
|
26
|
+
* This is a workaround for Comunica v5's initialBindings bug with SERVICE clauses.
|
|
27
|
+
*/
|
|
28
|
+
function substituteBindings(query, bindings) {
|
|
29
|
+
let result = query;
|
|
30
|
+
for (const [name, term] of Object.entries(bindings)) {
|
|
31
|
+
const pattern = new RegExp(`\\?${name}\\b`, 'g');
|
|
32
|
+
if (term.termType === 'NamedNode') {
|
|
33
|
+
result = result.replace(pattern, `<${term.value}>`);
|
|
34
|
+
}
|
|
35
|
+
else if (term.termType === 'Literal') {
|
|
36
|
+
const literal = term;
|
|
37
|
+
const datatype = literal.datatype?.value;
|
|
38
|
+
if (datatype &&
|
|
39
|
+
datatype !== 'http://www.w3.org/2001/XMLSchema#string' &&
|
|
40
|
+
datatype !== 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString') {
|
|
41
|
+
result = result.replace(pattern, `"${term.value}"^^<${datatype}>`);
|
|
42
|
+
}
|
|
43
|
+
else if (literal.language) {
|
|
44
|
+
result = result.replace(pattern, `"${term.value}"@${literal.language}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
result = result.replace(pattern, `"${term.value}"`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
13
53
|
export class TermsResponse {
|
|
14
54
|
result;
|
|
15
55
|
responseTimeMs;
|
|
@@ -92,10 +132,18 @@ export class QueryTermsService {
|
|
|
92
132
|
const logger = new LoggerPino({ logger: this.logger });
|
|
93
133
|
// Extract HTTP credentials if the distribution URL contains any.
|
|
94
134
|
const url = new URL(distribution.endpoint.toString());
|
|
95
|
-
|
|
96
|
-
|
|
135
|
+
// Workaround for https://github.com/comunica/comunica/issues/1655, so use
|
|
136
|
+
// string substitution instead of initialBindings for:
|
|
137
|
+
// - SERVICE clauses crash with initialBindings
|
|
138
|
+
// - VALUES crashes in some combinations
|
|
139
|
+
const useStringSubstitution = requiresStringSubstitution(query);
|
|
140
|
+
const finalQuery = useStringSubstitution
|
|
141
|
+
? substituteBindings(query, bindings)
|
|
142
|
+
: query;
|
|
143
|
+
this.logger.info(`Querying "${url}" with "${finalQuery}"...`);
|
|
144
|
+
const quadStream = await this.engine.queryQuads(finalQuery, {
|
|
97
145
|
log: logger,
|
|
98
|
-
httpAuth: url.username === '' ?
|
|
146
|
+
httpAuth: url.username === '' ? undefined : url.username + ':' + url.password,
|
|
99
147
|
httpTimeout: timeoutMs,
|
|
100
148
|
noCache: true,
|
|
101
149
|
sources: [
|
|
@@ -104,7 +152,10 @@ export class QueryTermsService {
|
|
|
104
152
|
value: url.origin + url.pathname,
|
|
105
153
|
},
|
|
106
154
|
],
|
|
107
|
-
initialBindings
|
|
155
|
+
// Only pass initialBindings when NOT using string substitution
|
|
156
|
+
...(useStringSubstitution
|
|
157
|
+
? {}
|
|
158
|
+
: { initialBindings: bindingsFactory.fromRecord(bindings) }),
|
|
108
159
|
});
|
|
109
160
|
return new Promise((resolve) => {
|
|
110
161
|
const termsTransformer = new TermsTransformer();
|
package/dist/test-utils.js
CHANGED
|
@@ -93,7 +93,7 @@ export const testCatalog = (port) => new Catalog([
|
|
|
93
93
|
], ['http://data.beeldengeluid.nl/gtaa/'], 'https://example.com/gtaa', ['nl'], [
|
|
94
94
|
new Organization('https://www.beeldengeluid.nl/', { nl: 'Nederlands Instituut voor Beeld en Geluid' }, { nl: 'Beeld en Geluid' }),
|
|
95
95
|
], [
|
|
96
|
-
new SparqlDistribution('https://data.beeldengeluid.nl/id/datadownload/0026', 'https://username:password@gtaa.apis.beeldengeluid.nl/sparql', 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }', 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'),
|
|
96
|
+
new SparqlDistribution('https://data.beeldengeluid.nl/id/datadownload/0026', 'https://username:password@gtaa.apis.beeldengeluid.nl/sparql', 'CONSTRUCT { ?s ?p ?o } WHERE { ?s skos:inScheme ?datasetUri ; ?p ?o }', 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }'),
|
|
97
97
|
]),
|
|
98
98
|
]);
|
|
99
99
|
export async function startDistributionSparqlEndpoint(port) {
|