@netwerk-digitaal-erfgoed/network-of-terms-query 6.2.11 → 6.2.13
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 +14 -0
- package/dist/query.d.ts +24 -0
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +18 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/query.ts +47 -0
- package/test/query.test.ts +37 -1
- package/vite.config.ts +5 -5
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netwerk-digitaal-erfgoed/network-of-terms-query",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.13",
|
|
4
4
|
"description": "Engine for querying sources in the Network of Terms",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"homepage": "https://github.com/netwerk-digitaal-erfgoed/network-of-terms#readme",
|
package/src/query.ts
CHANGED
|
@@ -91,6 +91,53 @@ export class TimeoutError extends Error {
|
|
|
91
91
|
|
|
92
92
|
export class ServerError extends Error {}
|
|
93
93
|
|
|
94
|
+
export interface BuildSearchQueryOptions {
|
|
95
|
+
/** The SPARQL query template with placeholders. */
|
|
96
|
+
template: string;
|
|
97
|
+
/** The search term to bind. */
|
|
98
|
+
searchTerm: string;
|
|
99
|
+
/** Query mode for search term processing. */
|
|
100
|
+
queryMode: QueryMode;
|
|
101
|
+
/** Dataset IRI to bind to ?datasetUri. */
|
|
102
|
+
datasetIri: string;
|
|
103
|
+
/** Limit for results. */
|
|
104
|
+
limit: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface BuildSearchQueryResult {
|
|
108
|
+
/** The query with #LIMIT# replaced. */
|
|
109
|
+
query: string;
|
|
110
|
+
/** Bindings for SPARQL variables (?query, ?virtuosoQuery, ?datasetUri, ?limit). */
|
|
111
|
+
bindings: Record<string, RDF.Term>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Build a SPARQL query and bindings from a template.
|
|
116
|
+
* Returns the query with #LIMIT# replaced and a set of bindings for variables.
|
|
117
|
+
* The bindings can be used with Comunica's initialBindings or serialized into the query.
|
|
118
|
+
*/
|
|
119
|
+
export function buildSearchQuery(
|
|
120
|
+
options: BuildSearchQueryOptions,
|
|
121
|
+
): BuildSearchQueryResult {
|
|
122
|
+
const variants = queryVariants(options.searchTerm, options.queryMode);
|
|
123
|
+
|
|
124
|
+
// Replace #LIMIT# placeholder
|
|
125
|
+
const query = options.template.replace('#LIMIT#', `LIMIT ${options.limit}`);
|
|
126
|
+
|
|
127
|
+
// Build bindings record
|
|
128
|
+
const bindings: Record<string, RDF.Term> = {};
|
|
129
|
+
for (const [varName, value] of variants) {
|
|
130
|
+
bindings[varName] = dataFactory.literal(value);
|
|
131
|
+
}
|
|
132
|
+
bindings['datasetUri'] = dataFactory.namedNode(options.datasetIri);
|
|
133
|
+
bindings['limit'] = dataFactory.literal(
|
|
134
|
+
options.limit.toString(),
|
|
135
|
+
dataFactory.namedNode('http://www.w3.org/2001/XMLSchema#integer'),
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
return { query, bindings };
|
|
139
|
+
}
|
|
140
|
+
|
|
94
141
|
export class QueryTermsService {
|
|
95
142
|
private readonly logger: Pino.Logger;
|
|
96
143
|
private readonly engine: QueryEngine;
|
package/test/query.test.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { testCatalog } from '../src/test-utils.js';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
buildSearchQuery,
|
|
4
|
+
QueryMode,
|
|
5
|
+
QueryTermsService,
|
|
6
|
+
} from '../src/index.js';
|
|
3
7
|
import { QueryEngine } from '@comunica/query-sparql';
|
|
4
8
|
import { ArrayIterator } from 'asynciterator';
|
|
5
9
|
import type { Term } from '@rdfjs/types';
|
|
@@ -66,3 +70,35 @@ const query = async (iri: string) => {
|
|
|
66
70
|
initialBindings: Map<string, Term>;
|
|
67
71
|
};
|
|
68
72
|
};
|
|
73
|
+
|
|
74
|
+
describe('buildSearchQuery', () => {
|
|
75
|
+
it('returns query and bindings', () => {
|
|
76
|
+
const result = buildSearchQuery({
|
|
77
|
+
template: 'SELECT * WHERE { ?s ?p ?o } #LIMIT#',
|
|
78
|
+
searchTerm: 'test',
|
|
79
|
+
queryMode: QueryMode.OPTIMIZED,
|
|
80
|
+
datasetIri: 'https://example.org/dataset',
|
|
81
|
+
limit: 10,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
expect(result.query).toBe('SELECT * WHERE { ?s ?p ?o } LIMIT 10');
|
|
85
|
+
expect(result.bindings['datasetUri'].value).toBe(
|
|
86
|
+
'https://example.org/dataset',
|
|
87
|
+
);
|
|
88
|
+
expect(result.bindings['limit'].value).toBe('10');
|
|
89
|
+
expect(result.bindings['query'].value).toBe('test');
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('creates Virtuoso-specific query variant', () => {
|
|
93
|
+
const result = buildSearchQuery({
|
|
94
|
+
template: 'SELECT * WHERE { ?s ?p ?o }',
|
|
95
|
+
searchTerm: 'van gogh',
|
|
96
|
+
queryMode: QueryMode.OPTIMIZED,
|
|
97
|
+
datasetIri: 'https://example.org/dataset',
|
|
98
|
+
limit: 100,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Virtuoso format: 'word1' AND 'word2' for multi-word queries
|
|
102
|
+
expect(result.bindings['virtuosoQuery'].value).toBe("'van' AND 'gogh'");
|
|
103
|
+
});
|
|
104
|
+
});
|
package/vite.config.ts
CHANGED
|
@@ -16,11 +16,11 @@ export default defineConfig(() => ({
|
|
|
16
16
|
provider: 'v8' as const,
|
|
17
17
|
thresholds: {
|
|
18
18
|
autoUpdate: true,
|
|
19
|
-
lines:
|
|
20
|
-
functions:
|
|
21
|
-
branches: 91.
|
|
22
|
-
statements:
|
|
19
|
+
lines: 57.57,
|
|
20
|
+
functions: 41.02,
|
|
21
|
+
branches: 91.52,
|
|
22
|
+
statements: 57.57,
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
|
-
}));
|
|
26
|
+
}));
|