@lde/sparql-qlever 0.14.2 → 0.14.4
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/dist/importer.d.ts.map +1 -1
- package/dist/importer.js +53 -16
- package/dist/preprocess.d.ts +33 -0
- package/dist/preprocess.d.ts.map +1 -0
- package/dist/preprocess.js +158 -0
- package/package.json +17 -10
package/dist/importer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,IAAI,iBAAiB,EAC7B,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,
|
|
1
|
+
{"version":3,"file":"importer.d.ts","sourceRoot":"","sources":["../src/importer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,IAAI,iBAAiB,EAC7B,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAyB,YAAY,EAAE,MAAM,cAAc,CAAC;AAMnE,MAAM,WAAW,kBAAkB;IACjC,oBAAoB;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,yBAAyB;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yJAAyJ;IACzJ,+BAA+B,CAAC,EAAE,OAAO,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAWD,qBAAa,QAAS,YAAW,iBAAiB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,OAAO,EAAE,qBAAqB;IAa7B,MAAM,CACjB,aAAa,EAAE,YAAY,EAAE,GAC5B,OAAO,CAAC,YAAY,GAAG,gBAAgB,GAAG,YAAY,CAAC;YAqC5C,QAAQ;IA6DtB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,aAAa;IAIrB;;OAEG;YACW,eAAe;IA0B7B,yDAAyD;YAC3C,eAAe;YAaf,cAAc;YAKd,KAAK;CA4CpB"}
|
package/dist/importer.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ImportFailed, ImportSuccessful, NotSupported, } from '@lde/sparql-importer';
|
|
2
|
+
import { compressionMediaTypes } from '@lde/dataset';
|
|
2
3
|
import { LastModifiedDownloader } from '@lde/distribution-downloader';
|
|
3
4
|
import { basename, dirname, join } from 'path';
|
|
4
5
|
import { readFile, stat, writeFile } from 'node:fs/promises';
|
|
6
|
+
import { needsPreprocessing, preprocess } from './preprocess.js';
|
|
5
7
|
export class Importer {
|
|
6
8
|
options;
|
|
7
9
|
constructor(options) {
|
|
@@ -17,8 +19,11 @@ export class Importer {
|
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
async import(distributions) {
|
|
20
|
-
const downloadDistributions = distributions
|
|
21
|
-
|
|
22
|
+
const downloadDistributions = distributions
|
|
23
|
+
.filter((distribution) => distribution.mimeType !== undefined &&
|
|
24
|
+
acceptedMediaTypes.includes(distribution.mimeType))
|
|
25
|
+
.sort((a, b) => acceptedMediaTypes.indexOf(a.mimeType) -
|
|
26
|
+
acceptedMediaTypes.indexOf(b.mimeType));
|
|
22
27
|
if (downloadDistributions.length === 0) {
|
|
23
28
|
return new NotSupported();
|
|
24
29
|
}
|
|
@@ -52,15 +57,29 @@ export class Importer {
|
|
|
52
57
|
}
|
|
53
58
|
return new ImportSuccessful(distribution, undefined, tripleCount);
|
|
54
59
|
}
|
|
55
|
-
|
|
60
|
+
let indexFile = localFile;
|
|
61
|
+
let format;
|
|
62
|
+
const warnings = [];
|
|
63
|
+
if (needsPreprocessing(distribution)) {
|
|
64
|
+
const result = await preprocess(localFile, distribution);
|
|
65
|
+
indexFile = result.path;
|
|
66
|
+
format = result.format;
|
|
67
|
+
warnings.push(...result.warnings);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const resolved = fileFormatFor(distribution.mimeType, basename(localFile), headers.get('Content-Type') ?? undefined);
|
|
71
|
+
format = resolved.format;
|
|
72
|
+
if (resolved.warning)
|
|
73
|
+
warnings.push(resolved.warning);
|
|
74
|
+
}
|
|
56
75
|
let logs;
|
|
57
76
|
try {
|
|
58
|
-
logs = await this.index(
|
|
77
|
+
logs = await this.index(indexFile, format);
|
|
59
78
|
}
|
|
60
79
|
catch (error) {
|
|
61
80
|
if (format === 'ttl' &&
|
|
62
81
|
error.message?.includes('multiline string literal')) {
|
|
63
|
-
logs = await this.index(
|
|
82
|
+
logs = await this.index(indexFile, format, false);
|
|
64
83
|
}
|
|
65
84
|
else {
|
|
66
85
|
throw error;
|
|
@@ -71,7 +90,6 @@ export class Importer {
|
|
|
71
90
|
return new ImportFailed(distribution, 'Indexed 0 triples from distribution');
|
|
72
91
|
}
|
|
73
92
|
await this.writeCacheInfo(localFile);
|
|
74
|
-
const warnings = warning ? [warning] : [];
|
|
75
93
|
return new ImportSuccessful(distribution, undefined, tripleCount, warnings);
|
|
76
94
|
}
|
|
77
95
|
parseTripleCount(logs) {
|
|
@@ -148,15 +166,39 @@ export class Importer {
|
|
|
148
166
|
.filter(Boolean)
|
|
149
167
|
.join(' ');
|
|
150
168
|
const metadataFile = `${this.options.indexName}.meta-data.json`;
|
|
151
|
-
const
|
|
169
|
+
const localName = basename(file);
|
|
170
|
+
const decompressCommand = localName.toLowerCase().endsWith('.zip')
|
|
171
|
+
? `unzip -p '${localName}'`
|
|
172
|
+
: `(gunzip -c '${localName}' 2>/dev/null || cat '${localName}')`;
|
|
173
|
+
const indexTask = await this.options.taskRunner.run(`${decompressCommand} | qlever-index ${flags} && cat ${metadataFile}`);
|
|
152
174
|
return await this.options.taskRunner.wait(indexTask);
|
|
153
175
|
}
|
|
154
176
|
}
|
|
155
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Native QLever index formats — `qlever-index -F <flag>` consumes these
|
|
179
|
+
* directly. JSON-LD is not here: it is preprocessed to N-Quads first (see
|
|
180
|
+
* {@link preprocess}).
|
|
181
|
+
*/
|
|
182
|
+
const nativeFormats = new Map([
|
|
156
183
|
['application/n-triples', 'nt'],
|
|
157
184
|
['application/n-quads', 'nq'],
|
|
158
185
|
['text/turtle', 'ttl'],
|
|
159
186
|
]);
|
|
187
|
+
/**
|
|
188
|
+
* Accepted distribution media types, in preference order: the first match is
|
|
189
|
+
* tried first. Native formats win over JSON-LD because they skip the Node-side
|
|
190
|
+
* preprocessor.
|
|
191
|
+
*
|
|
192
|
+
* `application/zip` is intentionally absent — the inner RDF format must be
|
|
193
|
+
* declared via `mediaType` with `application/zip` appearing only as the
|
|
194
|
+
* `compressFormat`, so we know what is inside.
|
|
195
|
+
*/
|
|
196
|
+
const acceptedMediaTypes = [
|
|
197
|
+
'application/n-quads',
|
|
198
|
+
'application/n-triples',
|
|
199
|
+
'text/turtle',
|
|
200
|
+
'application/ld+json',
|
|
201
|
+
];
|
|
160
202
|
const defaultQleverIndexOptions = {
|
|
161
203
|
'ascii-prefixes-only': true,
|
|
162
204
|
'num-triples-per-batch': 3_000_000,
|
|
@@ -169,11 +211,6 @@ const extensionFormats = new Map([
|
|
|
169
211
|
['.nq', 'nq'],
|
|
170
212
|
['.ttl', 'ttl'],
|
|
171
213
|
]);
|
|
172
|
-
const compressionTypes = new Set([
|
|
173
|
-
'application/gzip',
|
|
174
|
-
'application/x-gzip',
|
|
175
|
-
'application/octet-stream',
|
|
176
|
-
]);
|
|
177
214
|
/**
|
|
178
215
|
* Determine the QLever format flag for a distribution.
|
|
179
216
|
*
|
|
@@ -183,15 +220,15 @@ const compressionTypes = new Set([
|
|
|
183
220
|
* 3. Declared MIME type from the dataset registry (last resort)
|
|
184
221
|
*/
|
|
185
222
|
function fileFormatFor(declaredMimeType, filename, serverContentType) {
|
|
186
|
-
const declaredFormat =
|
|
223
|
+
const declaredFormat = nativeFormats.get(declaredMimeType);
|
|
187
224
|
if (declaredFormat === undefined) {
|
|
188
225
|
throw new Error(`Unsupported media type: ${declaredMimeType}`);
|
|
189
226
|
}
|
|
190
227
|
// Try server Content-Type first (strip parameters like "; charset=utf-8").
|
|
191
228
|
if (serverContentType) {
|
|
192
229
|
const actualType = serverContentType.split(';')[0].trim();
|
|
193
|
-
if (!
|
|
194
|
-
const serverFormat =
|
|
230
|
+
if (!compressionMediaTypes.has(actualType)) {
|
|
231
|
+
const serverFormat = nativeFormats.get(actualType);
|
|
195
232
|
if (serverFormat !== undefined && serverFormat !== declaredFormat) {
|
|
196
233
|
return {
|
|
197
234
|
format: serverFormat,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Distribution } from '@lde/dataset';
|
|
2
|
+
export interface PreprocessResult {
|
|
3
|
+
/** Path to the file ready for `qlever-index`. Always N-Quads. */
|
|
4
|
+
path: string;
|
|
5
|
+
format: 'nq';
|
|
6
|
+
warnings: string[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Whether a distribution needs Node-side preprocessing before `qlever-index`
|
|
10
|
+
* can read it.
|
|
11
|
+
*
|
|
12
|
+
* Only JSON-LD distributions return `true`: `qlever-index` cannot parse
|
|
13
|
+
* JSON-LD, so we stream it through a JSON-LD parser into N-Quads first.
|
|
14
|
+
*
|
|
15
|
+
* Native RDF formats (`nt`, `nq`, `ttl`) — including when wrapped in
|
|
16
|
+
* `application/gzip` or `application/zip` — go straight through the shell
|
|
17
|
+
* pipeline in `index()`, which uses `gunzip -c` or `unzip -p` as appropriate.
|
|
18
|
+
* Standalone `mediaType=application/zip` is rejected upstream: the inner
|
|
19
|
+
* format must be declared.
|
|
20
|
+
*/
|
|
21
|
+
export declare function needsPreprocessing(distribution: Distribution): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Convert a JSON-LD distribution to N-Quads alongside the source file.
|
|
24
|
+
*
|
|
25
|
+
* Streams the source through `rdf-parse` → `rdf-serialize` so memory use
|
|
26
|
+
* stays bounded regardless of input size. Handles gzip transparently
|
|
27
|
+
* (declared `compressFormat` or `.gz` filename) and zip containers (folds
|
|
28
|
+
* each JSON-LD entry into the output stream in order).
|
|
29
|
+
*
|
|
30
|
+
* Cached: if the output is newer than the input, it is reused as-is.
|
|
31
|
+
*/
|
|
32
|
+
export declare function preprocess(localFile: string, distribution: Distribution): Promise<PreprocessResult>;
|
|
33
|
+
//# sourceMappingURL=preprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preprocess.d.ts","sourceRoot":"","sources":["../src/preprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAmB5C,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAEtE;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,gBAAgB,CAAC,CAsB3B"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { rdfParser } from 'rdf-parse';
|
|
2
|
+
import { rdfSerializer } from 'rdf-serialize';
|
|
3
|
+
import { createGunzip } from 'node:zlib';
|
|
4
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
5
|
+
import { rm, stat } from 'node:fs/promises';
|
|
6
|
+
import { extname } from 'node:path';
|
|
7
|
+
import { finished } from 'node:stream/promises';
|
|
8
|
+
import { promisify } from 'node:util';
|
|
9
|
+
import yauzl from 'yauzl';
|
|
10
|
+
const JSONLD_MIME = 'application/ld+json';
|
|
11
|
+
const ZIP_MIME = 'application/zip';
|
|
12
|
+
const GZIP_MIME = 'application/gzip';
|
|
13
|
+
const GZIP_MIME_LEGACY = 'application/x-gzip';
|
|
14
|
+
const JSONLD_ZIP_EXTENSIONS = ['.jsonld', '.json'];
|
|
15
|
+
/**
|
|
16
|
+
* Whether a distribution needs Node-side preprocessing before `qlever-index`
|
|
17
|
+
* can read it.
|
|
18
|
+
*
|
|
19
|
+
* Only JSON-LD distributions return `true`: `qlever-index` cannot parse
|
|
20
|
+
* JSON-LD, so we stream it through a JSON-LD parser into N-Quads first.
|
|
21
|
+
*
|
|
22
|
+
* Native RDF formats (`nt`, `nq`, `ttl`) — including when wrapped in
|
|
23
|
+
* `application/gzip` or `application/zip` — go straight through the shell
|
|
24
|
+
* pipeline in `index()`, which uses `gunzip -c` or `unzip -p` as appropriate.
|
|
25
|
+
* Standalone `mediaType=application/zip` is rejected upstream: the inner
|
|
26
|
+
* format must be declared.
|
|
27
|
+
*/
|
|
28
|
+
export function needsPreprocessing(distribution) {
|
|
29
|
+
return distribution.mimeType === JSONLD_MIME;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Convert a JSON-LD distribution to N-Quads alongside the source file.
|
|
33
|
+
*
|
|
34
|
+
* Streams the source through `rdf-parse` → `rdf-serialize` so memory use
|
|
35
|
+
* stays bounded regardless of input size. Handles gzip transparently
|
|
36
|
+
* (declared `compressFormat` or `.gz` filename) and zip containers (folds
|
|
37
|
+
* each JSON-LD entry into the output stream in order).
|
|
38
|
+
*
|
|
39
|
+
* Cached: if the output is newer than the input, it is reused as-is.
|
|
40
|
+
*/
|
|
41
|
+
export async function preprocess(localFile, distribution) {
|
|
42
|
+
if (!needsPreprocessing(distribution)) {
|
|
43
|
+
throw new Error(`preprocess called for distribution that does not need preprocessing: mediaType=${distribution.mimeType}`);
|
|
44
|
+
}
|
|
45
|
+
const outputFile = `${localFile}.preprocessed.nq`;
|
|
46
|
+
if (await outputIsUpToDate(localFile, outputFile)) {
|
|
47
|
+
return { path: outputFile, format: 'nq', warnings: [] };
|
|
48
|
+
}
|
|
49
|
+
await rm(outputFile, { force: true });
|
|
50
|
+
const warnings = [];
|
|
51
|
+
if (distribution.compressMimeType === ZIP_MIME) {
|
|
52
|
+
await streamJsonldZip(localFile, outputFile, warnings);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
await streamJsonldFile(localFile, outputFile, distribution);
|
|
56
|
+
}
|
|
57
|
+
return { path: outputFile, format: 'nq', warnings };
|
|
58
|
+
}
|
|
59
|
+
async function outputIsUpToDate(inputFile, outputFile) {
|
|
60
|
+
try {
|
|
61
|
+
const [inputStat, outputStat] = await Promise.all([
|
|
62
|
+
stat(inputFile),
|
|
63
|
+
stat(outputFile),
|
|
64
|
+
]);
|
|
65
|
+
return outputStat.mtimeMs > inputStat.mtimeMs && outputStat.size > 0;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Pipe one JSON-LD source through parse → N-Quads serialize into an already
|
|
73
|
+
* open writable, without closing it. Back-pressure is handled by Node's
|
|
74
|
+
* built-in `.pipe()`; the caller manages `output`'s lifecycle.
|
|
75
|
+
*/
|
|
76
|
+
async function pipeJsonldToWritable(input, output) {
|
|
77
|
+
const quads = rdfParser.parse(input, { contentType: JSONLD_MIME });
|
|
78
|
+
const bytes = rdfSerializer.serialize(quads, {
|
|
79
|
+
contentType: 'application/n-quads',
|
|
80
|
+
});
|
|
81
|
+
bytes.pipe(output, { end: false });
|
|
82
|
+
await finished(bytes);
|
|
83
|
+
}
|
|
84
|
+
async function closeWritable(output) {
|
|
85
|
+
await new Promise((resolve, reject) => {
|
|
86
|
+
output.once('close', resolve);
|
|
87
|
+
output.once('error', reject);
|
|
88
|
+
output.end();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async function streamJsonldFile(localFile, outputFile, distribution) {
|
|
92
|
+
const isGzipped = distribution.compressMimeType === GZIP_MIME ||
|
|
93
|
+
distribution.compressMimeType === GZIP_MIME_LEGACY ||
|
|
94
|
+
localFile.toLowerCase().endsWith('.gz');
|
|
95
|
+
const source = createReadStream(localFile);
|
|
96
|
+
const input = isGzipped ? source.pipe(createGunzip()) : source;
|
|
97
|
+
const output = createWriteStream(outputFile);
|
|
98
|
+
try {
|
|
99
|
+
await pipeJsonldToWritable(input, output);
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await closeWritable(output);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const openZip = promisify(yauzl.open);
|
|
106
|
+
async function streamJsonldZip(zipFile, outputFile, warnings) {
|
|
107
|
+
const zip = await openZip(zipFile, { lazyEntries: true });
|
|
108
|
+
const output = createWriteStream(outputFile);
|
|
109
|
+
let entriesProcessed = 0;
|
|
110
|
+
try {
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
zip.on('error', reject);
|
|
113
|
+
zip.on('end', resolve);
|
|
114
|
+
zip.on('entry', (entry) => {
|
|
115
|
+
void (async () => {
|
|
116
|
+
try {
|
|
117
|
+
if (entry.fileName.endsWith('/')) {
|
|
118
|
+
zip.readEntry();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const extension = extname(entry.fileName).toLowerCase();
|
|
122
|
+
if (!JSONLD_ZIP_EXTENSIONS.includes(extension)) {
|
|
123
|
+
warnings.push(`Skipping zip entry ${entry.fileName}: extension ${extension || '(none)'} is not JSON-LD`);
|
|
124
|
+
zip.readEntry();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const stream = await openZipEntry(zip, entry);
|
|
128
|
+
await pipeJsonldToWritable(stream, output);
|
|
129
|
+
entriesProcessed++;
|
|
130
|
+
zip.readEntry();
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
reject(error);
|
|
134
|
+
}
|
|
135
|
+
})();
|
|
136
|
+
});
|
|
137
|
+
zip.readEntry();
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
zip.close();
|
|
142
|
+
await closeWritable(output);
|
|
143
|
+
}
|
|
144
|
+
if (entriesProcessed === 0) {
|
|
145
|
+
throw new Error(`Zip ${zipFile} contains no JSON-LD entries`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function openZipEntry(zip, entry) {
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
zip.openReadStream(entry, (error, stream) => {
|
|
151
|
+
if (error || stream === undefined) {
|
|
152
|
+
reject(error ?? new Error('Failed to open zip entry'));
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
resolve(stream);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lde/sparql-qlever",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.4",
|
|
4
4
|
"repository": {
|
|
5
5
|
"url": "git+https://github.com/ldelements/lde.git",
|
|
6
6
|
"directory": "packages/sparql-qlever"
|
|
@@ -24,14 +24,21 @@
|
|
|
24
24
|
"!**/*.tsbuildinfo"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@lde/dataset": "0.7.
|
|
28
|
-
"@lde/distribution-downloader": "0.6.
|
|
29
|
-
"@lde/sparql-importer": "0.6.
|
|
30
|
-
"@lde/sparql-server": "0.4.
|
|
31
|
-
"@lde/task-runner": "0.2.
|
|
32
|
-
"@lde/task-runner-docker": "0.2.
|
|
33
|
-
"@lde/task-runner-native": "0.2.
|
|
34
|
-
"@lde/wait-for-sparql": "0.2.
|
|
35
|
-
"
|
|
27
|
+
"@lde/dataset": "0.7.4",
|
|
28
|
+
"@lde/distribution-downloader": "0.6.2",
|
|
29
|
+
"@lde/sparql-importer": "0.6.2",
|
|
30
|
+
"@lde/sparql-server": "0.4.11",
|
|
31
|
+
"@lde/task-runner": "0.2.11",
|
|
32
|
+
"@lde/task-runner-docker": "0.2.13",
|
|
33
|
+
"@lde/task-runner-native": "0.2.14",
|
|
34
|
+
"@lde/wait-for-sparql": "0.2.12",
|
|
35
|
+
"rdf-parse": "^5.0.0",
|
|
36
|
+
"rdf-serialize": "^5.1.0",
|
|
37
|
+
"tslib": "^2.3.0",
|
|
38
|
+
"yauzl": "^3.2.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@rdfjs/types": "^2.0.0",
|
|
42
|
+
"@types/yauzl": "^2.10.3"
|
|
36
43
|
}
|
|
37
44
|
}
|