diff --git a/README.md b/README.md index 82b591d..31073ce 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,24 @@ stages: - query: "CONSTRUCT { $this a } WHERE { $this a }" ``` +#### Stores + +To query large local files, you may need to load them into a SPARQL store first. Do so by starting a SPARQL store, +for example Oxigraph: + +```shell +docker run --rm -v $PWD/data:/data -p 7878:7878 oxigraph/oxigraph --location /data serve +``` + +Then configure the store in your pipeline: + +```yaml +# config.yml +stores: + - queryUrl: "http://localhost:7878/query" + storeUrl: "http://localhost:7878/store" +``` + #### Example configuration ```yaml diff --git a/jest.config.js b/jest.config.js index 0e1ecfd..6095f78 100644 --- a/jest.config.js +++ b/jest.config.js @@ -11,10 +11,10 @@ export default { coverageReporters: ['json-summary', 'text'], coverageThreshold: { global: { - lines: 68.16, - statements: 68.5, - branches: 64.36, - functions: 75, + lines: 71.15, + statements: 71.25, + branches: 66.66, + functions: 76.59, }, }, transform: { diff --git a/package-lock.json b/package-lock.json index b24e33f..dca2d5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "chalk": "^5.3.0", "commander": "^12.1.0", "glob": "^7.2.3", + "got": "^14.4.1", "inquirer": "^9.3.0", "js-yaml": "^4.1.0", "lodash.clonedeep": "^4.5.0", @@ -25,7 +26,9 @@ "ora": "^7.0.1", "parse-duration": "^1.1.0", "pretty-ms": "^8.0.0", - "sparqljs": "^3.7.1" + "rdf-dereference": "^2.2.0", + "sparqljs": "^3.7.1", + "testcontainers": "^10.10.0" }, "bin": { "ld-workbench": "build/main.js" @@ -662,6 +665,11 @@ "node": ">=6.9.0" } }, + "node_modules/@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==" + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -4733,8 +4741,7 @@ "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", - "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", - "dev": true + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==" }, "node_modules/@semantic-release/commit-analyzer": { "version": "12.0.0", @@ -5311,6 +5318,17 @@ "@swc/counter": "^0.1.3" } }, + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, "node_modules/@triply/triplydb": { "version": "8.0.6", "resolved": "https://registry.npmjs.org/@triply/triplydb/-/triplydb-8.0.6.tgz", @@ -5486,6 +5504,25 @@ "@types/node": "*" } }, + "node_modules/@types/docker-modem": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz", + "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==", + "dependencies": { + "@types/node": "*", + "@types/ssh2": "*" + } + }, + "node_modules/@types/dockerode": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.29.tgz", + "integrity": "sha512-5PRRq/yt5OT/Jf77ltIdz4EiR9+VLnPF+HpU4xGFwUqmV24Co2HKBNW3w+slqZ1CYchbcDeqJASHDYWzZCcMiQ==", + "dependencies": { + "@types/docker-modem": "*", + "@types/node": "*", + "@types/ssh2": "*" + } + }, "node_modules/@types/glob": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", @@ -5505,6 +5542,11 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + }, "node_modules/@types/http-link-header": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/http-link-header/-/http-link-header-1.0.7.tgz", @@ -5659,6 +5701,30 @@ "@rdfjs/types": ">=1.0.0" } }, + "node_modules/@types/ssh2": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.0.tgz", + "integrity": "sha512-YcT8jP5F8NzWeevWvcyrrLB3zcneVjzYY9ZDSMAMboI+2zR1qYWFhwsyOFVzT7Jorn67vqxC0FRiw8YyG9P1ww==", + "dependencies": { + "@types/node": "^18.11.18" + } + }, + "node_modules/@types/ssh2-streams": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@types/ssh2-streams/-/ssh2-streams-0.1.12.tgz", + "integrity": "sha512-Sy8tpEmCce4Tq0oSOYdfqaBpA3hDM8SoxoFh5vzFsu2oL+znzGz8oVWW7xb4K920yYMUY+PIG31qZnFMfPWNCg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ssh2/node_modules/@types/node": { + "version": "18.19.39", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.39.tgz", + "integrity": "sha512-nPwTRDKUctxw3di5b4TfT3I0sWDiWoPQCZjXhvdkINntwr8lcoVCKsTgnXeRubKIlfnV+eN/HYk6Jb40tbcEAQ==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -6035,6 +6101,83 @@ "node": ">= 8" } }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/archiver/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -6113,6 +6256,14 @@ "node": ">=0.10.0" } }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -6127,6 +6278,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==" + }, "node_modules/asynciterator": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.9.0.tgz", @@ -6168,6 +6324,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -6338,6 +6499,47 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", + "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", + "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", + "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "optional": true, + "dependencies": { + "streamx": "^2.18.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -6357,6 +6559,14 @@ } ] }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/before-after-hook": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-3.0.2.tgz", @@ -6490,11 +6700,28 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" }, + "node_modules/buildcheck": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", + "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/builtins": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz", @@ -6504,6 +6731,65 @@ "semver": "^7.0.0" } }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "engines": { + "node": ">=14.16" + } + }, + "node_modules/cacheable-request": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-12.0.1.tgz", + "integrity": "sha512-Yo9wGIQUaAfIbk+qY0X4cDQgCosecfBe3V9NSyeY4qPC2SAkbCS4Xj79VP8WOzitpJUZKc/wsRCYF5ariDIwkg==", + "dependencies": { + "@types/http-cache-semantics": "^4.0.4", + "get-stream": "^9.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.4", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.1", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/call-bind": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", @@ -6658,6 +6944,11 @@ "node": "*" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -7096,6 +7387,33 @@ "undici-types": "~5.26.4" } }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -7209,8 +7527,7 @@ "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cosmiconfig": { "version": "9.0.0", @@ -7255,6 +7572,56 @@ "typescript": ">=4" } }, + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -7534,6 +7901,31 @@ "node": ">=14.16" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -7604,6 +7996,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -7679,8 +8079,70 @@ "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", + "node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/docker-modem": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz", + "integrity": "sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.11.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/docker-modem/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/dockerode": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz", + "integrity": "sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "docker-modem": "^3.0.0", + "tar-fs": "~2.0.1" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/dockerode/node_modules/tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, @@ -8713,6 +9175,11 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -9000,6 +9467,14 @@ "node": ">= 6" } }, + "node_modules/form-data-encoder": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-4.0.2.tgz", + "integrity": "sha512-KQVhvhK8ZkWzxKxOr56CPulAhH3dobtuQ4+hNQ+HekH/Wp5gSOafqRAeTphQUJAIk0GBvHZgJ2ZGRWd5kphMuw==", + "engines": { + "node": ">= 18" + } + }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -9051,6 +9526,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -9182,11 +9662,21 @@ "node": ">=8.0.0" } }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "dev": true, "engines": { "node": ">=16" }, @@ -9415,6 +9905,53 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "14.4.1", + "resolved": "https://registry.npmjs.org/got/-/got-14.4.1.tgz", + "integrity": "sha512-IvDJbJBUeexX74xNQuMIVgCRRuNOm5wuK+OC3Dc2pnSoh1AOmgc7JVj7WC+cJ4u0aPcO9KZ2frTXcqK4W/5qTQ==", + "dependencies": { + "@sindresorhus/is": "^6.3.1", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^12.0.1", + "decompress-response": "^6.0.0", + "form-data-encoder": "^4.0.2", + "get-stream": "^8.0.1", + "http2-wrapper": "^2.2.1", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^4.0.1", + "responselike": "^3.0.0", + "type-fest": "^4.19.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/@sindresorhus/is": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-6.3.1.tgz", + "integrity": "sha512-FX4MfcifwJyFOI2lPoX7PQxCqx8BG1HCho7WdiXwpEQx1Ycij0JxkfYtGK7yqNScrZGSlt6RE6sw8QYoH7eKnQ==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/got/node_modules/type-fest": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.21.0.tgz", + "integrity": "sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -10151,6 +10688,11 @@ "entities": "^4.5.0" } }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + }, "node_modules/http-link-header": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.3.tgz", @@ -10177,6 +10719,29 @@ "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.3.0.tgz", "integrity": "sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==" }, + "node_modules/http2-wrapper": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", + "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", @@ -12528,8 +13093,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -12816,7 +13380,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -12896,6 +13459,44 @@ "url": "https://opencollective.com/node-fetch" } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -13042,12 +13643,27 @@ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==" + }, "node_modules/lodash.escaperegexp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==", "dev": true }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" + }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -13056,8 +13672,7 @@ "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" }, "node_modules/lodash.isstring": { "version": "4.0.1", @@ -13104,6 +13719,11 @@ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -13173,6 +13793,17 @@ "get-func-name": "^2.0.1" } }, + "node_modules/lowercase-keys": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", @@ -13440,6 +14071,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-response": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -13520,6 +14162,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -13557,6 +14204,12 @@ "node": ">=12.0" } }, + "node_modules/nan": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", + "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -13683,7 +14336,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -13692,7 +14344,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "dev": true, "engines": { "node": ">=14.16" }, @@ -16512,6 +17163,14 @@ "node": ">=0.10.0" } }, + "node_modules/p-cancelable": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-4.0.1.tgz", + "integrity": "sha512-wBowNApzd45EIKdO1LaU+LrMBwAcjfPaYtVzV3lmfM3gf8Z4CHZsiIqlM8TZZ8okYvh5A1cP6gTfCRQtwUpaUg==", + "engines": { + "node": ">=14.16" + } + }, "node_modules/p-each-series": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz", @@ -17053,8 +17712,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/promise-polyfill": { "version": "1.1.6", @@ -17086,6 +17744,32 @@ "node": ">=4.0.0" } }, + "node_modules/properties-reader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.3.0.tgz", + "integrity": "sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw==", + "dependencies": { + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/properties?sponsor=1" + } + }, + "node_modules/properties-reader/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -17175,6 +17859,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -17233,43 +17922,15 @@ "@rdfjs/types": "*" } }, - "node_modules/rdf-isomorphic": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rdf-isomorphic/-/rdf-isomorphic-1.3.1.tgz", - "integrity": "sha512-6uIhsXTVp2AtO6f41PdnRV5xZsa0zVZQDTBdn0br+DZuFf5M/YD+T6m8hKDUnALI6nFL/IujTMLgEs20MlNidQ==", - "dependencies": { - "@rdfjs/types": "*", - "hash.js": "^1.1.7", - "rdf-string": "^1.6.0", - "rdf-terms": "^1.7.0" - } - }, - "node_modules/rdf-literal": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/rdf-literal/-/rdf-literal-1.3.2.tgz", - "integrity": "sha512-79Stlu3sXy0kq9/decHFLf3xNPuY6sfhFPhd/diWErgaFr0Ekyg38Vh9bnVcqDYu48CFRi0t+hrFii49n92Hbw==", - "dependencies": { - "@rdfjs/types": "*", - "rdf-data-factory": "^1.1.0" - } - }, - "node_modules/rdf-object": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/rdf-object/-/rdf-object-1.14.0.tgz", - "integrity": "sha512-/KSUWr7onDtL7d81kOpcUzJ2vHYOYJc2KU9WzBZRYydBhK0Sksh5Hg4VCQNaxUEvYEgdrrTuq9SLpOOCmag0rQ==", - "dependencies": { - "@rdfjs/types": "*", - "jsonld-context-parser": "^2.0.2", - "rdf-data-factory": "^1.1.0", - "rdf-string": "^1.6.0", - "streamify-array": "^1.0.1" - } - }, - "node_modules/rdf-parse": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/rdf-parse/-/rdf-parse-2.3.3.tgz", - "integrity": "sha512-N5XEHm+ajFzwo/vVNzB4tDtvqMwBosbVJmZl5DlzplQM9ejlJBlN/43i0ImAb/NMtJJgQPC3jYnkCKGA7wdo/w==", + "node_modules/rdf-dereference": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/rdf-dereference/-/rdf-dereference-2.2.0.tgz", + "integrity": "sha512-6geM3CSUlXTK3n4OoKsL95M7XwKXoxiwK7cf4e/+Dj0X/ll77ihFN5j9VhLGXNYbMXDlm30kBg/VU6ymMv6o/Q==", "dependencies": { + "@comunica/actor-dereference-fallback": "^2.0.2", + "@comunica/actor-dereference-file": "^2.0.2", + "@comunica/actor-dereference-http": "^2.0.2", + "@comunica/actor-dereference-rdf-parse": "^2.6.0", "@comunica/actor-http-fetch": "^2.0.1", "@comunica/actor-http-proxy": "^2.0.1", "@comunica/actor-rdf-parse-html": "^2.0.1", @@ -17279,24 +17940,31 @@ "@comunica/actor-rdf-parse-jsonld": "^2.0.1", "@comunica/actor-rdf-parse-n3": "^2.0.1", "@comunica/actor-rdf-parse-rdfxml": "^2.0.1", - "@comunica/actor-rdf-parse-shaclc": "^2.6.2", + "@comunica/actor-rdf-parse-shaclc": "^2.6.0", "@comunica/actor-rdf-parse-xml-rdfa": "^2.0.1", + "@comunica/bus-dereference": "^2.0.2", + "@comunica/bus-dereference-rdf": "^2.0.2", "@comunica/bus-http": "^2.0.1", "@comunica/bus-init": "^2.0.1", "@comunica/bus-rdf-parse": "^2.0.1", "@comunica/bus-rdf-parse-html": "^2.0.1", "@comunica/config-query-sparql": "^2.0.1", + "@comunica/context-entries": "^2.8.1", "@comunica/core": "^2.0.1", "@comunica/mediator-combine-pipeline": "^2.0.1", "@comunica/mediator-combine-union": "^2.0.1", "@comunica/mediator-number": "^2.0.1", "@comunica/mediator-race": "^2.0.1", "@rdfjs/types": "*", - "readable-stream": "^4.3.0", + "process": "^0.11.10", + "rdf-string": "^1.6.0", "stream-to-string": "^1.2.0" + }, + "bin": { + "rdf-dereference": "bin/Runner.js" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-abstract-mediatyped": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-abstract-mediatyped": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-abstract-mediatyped/-/actor-abstract-mediatyped-2.10.0.tgz", "integrity": "sha512-0o6WBujsMnIVcwvRJv6Nj+kKPLZzqBS3On48rm01Rh9T1/My0E/buJMXwgcARKCfMonc2mJ9zxpPCh5ilGEU2A==", @@ -17305,7 +17973,7 @@ "@comunica/types": "^2.10.0" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-abstract-parse": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-abstract-parse": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-abstract-parse/-/actor-abstract-parse-2.10.0.tgz", "integrity": "sha512-0puCWF+y24EDOOAUUVVbC+tOf4UV+LzEbqi8T5v25jcVGCXyTqfra+bDywfrcv3adrVp18jLCJ46ycaH5xhy9Q==", @@ -17314,7 +17982,48 @@ "readable-stream": "^4.4.2" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-http-fetch": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-dereference-fallback": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-dereference-fallback/-/actor-dereference-fallback-2.10.0.tgz", + "integrity": "sha512-RSc/ScPdC7l13aZjz/6r4niWA8WDETbzuESQKKSWXi/HAlFOyOxdrDADdayVY2oyeZHIQibeNRtSi2ItzU7OPQ==", + "dependencies": { + "@comunica/bus-dereference": "^2.10.0", + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/actor-dereference-file": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-dereference-file/-/actor-dereference-file-2.10.0.tgz", + "integrity": "sha512-WXfAyHm0M3+YbYEtLtasT6YHsrzTAevmH27ex8r51qKNj2LK74llpw4mSeea3xyjQR30jVnKBIJSxuSbN64Now==", + "dependencies": { + "@comunica/bus-dereference": "^2.10.0", + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/actor-dereference-http": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@comunica/actor-dereference-http/-/actor-dereference-http-2.10.2.tgz", + "integrity": "sha512-gdDo83W1TAgD2jx0kVbzZKzzt++L4Y4fbyTOH3duy6vx1EMGGZlNCp6I1uguepKEjNX4N0zhAcZzdJcv8A3XMA==", + "dependencies": { + "@comunica/bus-dereference": "^2.10.0", + "@comunica/bus-http": "^2.10.2", + "@comunica/core": "^2.10.0", + "cross-fetch": "^4.0.0", + "relative-to-absolute-iri": "^1.0.7", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/actor-dereference-rdf-parse": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-dereference-rdf-parse/-/actor-dereference-rdf-parse-2.10.0.tgz", + "integrity": "sha512-ANWL6Bv+2WHUjVRS7hfkOfVBNJs8xYZ9KHlgBOQ94CKtQZB9uSMjdb1hLp/cQjiDmFIWLn0+GM5Xi0KFwBkVAw==", + "dependencies": { + "@comunica/bus-dereference": "^2.10.0", + "@comunica/bus-dereference-rdf": "^2.10.0", + "@comunica/bus-rdf-parse": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/actor-http-fetch": { "version": "2.10.2", "resolved": "https://registry.npmjs.org/@comunica/actor-http-fetch/-/actor-http-fetch-2.10.2.tgz", "integrity": "sha512-siHGx0TMVNb2gXvOroq0B3JE6uuS+4s+MsDkntqdBNVigwVYqLpNSKEaL5is8pputFfohJfDQY06lAHbfDNEcw==", @@ -17326,7 +18035,7 @@ "cross-fetch": "^4.0.0" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-http-proxy": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-http-proxy": { "version": "2.10.2", "resolved": "https://registry.npmjs.org/@comunica/actor-http-proxy/-/actor-http-proxy-2.10.2.tgz", "integrity": "sha512-3yUF8BCh4nwq8J6NRILEsyNrQNStkE9ggJ7hYwRfA1XcMgz1pANNaWJ2P2TEKH1jNinr23bL3JeuUZCm9Kz9dA==", @@ -17337,7 +18046,7 @@ "@comunica/types": "^2.10.0" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-html": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html/-/actor-rdf-parse-html-2.10.0.tgz", "integrity": "sha512-zgImXKpc+BN1i6lQiN1Qhlb1HbKdMIeJMOys6qbzRIijdK8GkGGChwhQp7Cso3lY1Nf4K7M3jPLZeQXeED2w7g==", @@ -17351,7 +18060,7 @@ "readable-stream": "^4.4.2" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-microdata": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-html-microdata": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-microdata/-/actor-rdf-parse-html-microdata-2.10.0.tgz", "integrity": "sha512-JLfiDauq4SmpI6TDS4HaHzI6iJe1j8lSk5FRRYK6YVEu8eO28jPmxQJiOiwbQiYqsjsV7kON/WIZSoUELoI4Ig==", @@ -17361,7 +18070,7 @@ "microdata-rdf-streaming-parser": "^2.0.1" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-rdfa": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-html-rdfa": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-rdfa/-/actor-rdf-parse-html-rdfa-2.10.0.tgz", "integrity": "sha512-9K3iaws9+FGl50oZi53hqyzhwjNKZ3mIr2zg/TAJZoapKvc14cthH17zKSSJrqI/NgBStRmZhBBkXcwfu1CANw==", @@ -17371,7 +18080,7 @@ "rdfa-streaming-parser": "^2.0.1" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-script": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-html-script": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-script/-/actor-rdf-parse-html-script-2.10.0.tgz", "integrity": "sha512-7XYqWchDquWnBLjG7rmmY+tdE81UZ8fPCU0Hn+vI39/MikNOpaiyr/ZYFqhogWFa9SkjmH0a7idVUzmjiwKRZQ==", @@ -17386,7 +18095,7 @@ "relative-to-absolute-iri": "^1.0.7" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-jsonld": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-jsonld": { "version": "2.10.2", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-jsonld/-/actor-rdf-parse-jsonld-2.10.2.tgz", "integrity": "sha512-K4fvD0zMU22KkQCqIFVT5Oy2FREEZ9CAo9u6kOcsMxEvg9aHGIM6hkaXR8I+1JCx1mDuEj3zQ8joR4tQh8fYCw==", @@ -17401,7 +18110,7 @@ "stream-to-string": "^1.2.0" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-n3": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-n3": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-n3/-/actor-rdf-parse-n3-2.10.0.tgz", "integrity": "sha512-o1MAbwJxW4Br2WCZdhFoRmAiOP4mfogeQqJ4nqlsOkoMtQ45EvLHsotb3Kqhuk5V+vsTxyK5v/a4zylGtcU7VQ==", @@ -17411,7 +18120,7 @@ "n3": "^1.17.0" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-rdfxml": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-rdfxml": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-rdfxml/-/actor-rdf-parse-rdfxml-2.10.0.tgz", "integrity": "sha512-HoJN52shXY3cvYtsS0cpin9KXpW3L7g1leebyCRSqnlnHdJv5D6G0Ep8vyt2xhquKNbOQ7LnP5VhiDiqz73XDg==", @@ -17421,7 +18130,365 @@ "rdfxml-streaming-parser": "^2.2.3" } }, - "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-shaclc": { + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-shaclc": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-shaclc/-/actor-rdf-parse-shaclc-2.10.0.tgz", + "integrity": "sha512-i6tmuZuS+RtDiSXpQc3s/PxtCqwIguo4ANmVB20PK4VWgQgBwoPG7LlNcJ0xmuH/3Bv6C2Agn18PLF6dZX+fKw==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/types": "^2.10.0", + "@rdfjs/types": "*", + "asynciterator": "^3.8.1", + "readable-stream": "^4.4.2", + "shaclc-parse": "^1.4.0", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/actor-rdf-parse-xml-rdfa": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-xml-rdfa/-/actor-rdf-parse-xml-rdfa-2.10.0.tgz", + "integrity": "sha512-68r/6B/fEyA1/OYleVuaPq47J+g4xJcJijpdL1wEj7CqjV+Xa+sDWRpNCyLcD/e1Y/g9UQmLz0ZnSpR00PFddA==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/types": "^2.10.0", + "rdfa-streaming-parser": "^2.0.1" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-dereference": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-dereference/-/bus-dereference-2.10.0.tgz", + "integrity": "sha512-nWyQXiH7zbiPTVttWVKJHykhV4IuahfhfUwPx3Op+cVsK489Su84dnGeSmPkxTAFFuxe6wU6ZEH4i7PDu48YvQ==", + "dependencies": { + "@comunica/actor-abstract-mediatyped": "^2.10.0", + "@comunica/actor-abstract-parse": "^2.10.0", + "@comunica/context-entries": "^2.10.0", + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0", + "readable-stream": "^4.4.2" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-dereference-rdf": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-dereference-rdf/-/bus-dereference-rdf-2.10.0.tgz", + "integrity": "sha512-WY/wPmFpO76wwJ2D5Aus43ZbYnBRLvQ0EOp4yywO0lBiq6F0JisjCVCM4EtWouOEAAfqEoIjHXGyC3gPWqm+SQ==", + "dependencies": { + "@comunica/bus-dereference": "^2.10.0", + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/core": "^2.10.0", + "@rdfjs/types": "*" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-http": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@comunica/bus-http/-/bus-http-2.10.2.tgz", + "integrity": "sha512-MAYRF6uEBAuJ9dCPW2Uyne7w3lNwXFXKfa14XuPG5DFTDpgo/Z2pWupPrBsA1eIWMNJ6WOG6QyEv4rllSIBqlg==", + "dependencies": { + "@comunica/core": "^2.10.0", + "@smessie/readable-web-to-node-stream": "^3.0.3", + "is-stream": "^2.0.1", + "readable-stream-node-to-web": "^1.0.1", + "web-streams-ponyfill": "^1.4.2" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-init": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-init/-/bus-init-2.10.0.tgz", + "integrity": "sha512-hJejHa8sLVhQLFlduCVnhOd5aW3FCEz8wmWjyeLI3kiHFaQibnGVMhUuuNRX5f8bnnPuTdEiHc1nnYHuSi+j8A==", + "dependencies": { + "@comunica/core": "^2.10.0", + "readable-stream": "^4.4.2" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-rdf-parse": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-rdf-parse/-/bus-rdf-parse-2.10.0.tgz", + "integrity": "sha512-EgCMZACfTG/+mayQpExWt0HoBT32BBVC1aS1lC43fXKBTxJ8kYrSrorVUuMACoh4dQVGTb+7j1j4K0hGNVzXGA==", + "dependencies": { + "@comunica/actor-abstract-mediatyped": "^2.10.0", + "@comunica/actor-abstract-parse": "^2.10.0", + "@comunica/core": "^2.10.0", + "@rdfjs/types": "*" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/bus-rdf-parse-html": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-rdf-parse-html/-/bus-rdf-parse-html-2.10.0.tgz", + "integrity": "sha512-RZliz4TtKP63QggoohGuIkGb6lq0BoYJ4aztKtGldWtPAVP/pdEvlDpiZWLB/j19g7S2aDLNY/lJtZ5efM1tHQ==", + "dependencies": { + "@comunica/core": "^2.10.0", + "@rdfjs/types": "*" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/config-query-sparql": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@comunica/config-query-sparql/-/config-query-sparql-2.7.0.tgz", + "integrity": "sha512-rMnFgT7cz9+0z7wV4OzIMY5qM9/Z0mTGrR8y2JokoHyyTcBGOSajFmy61XCSLMCsLLG8qDXsJ4ClCCky3TGfqA==" + }, + "node_modules/rdf-dereference/node_modules/@comunica/context-entries": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/context-entries/-/context-entries-2.10.0.tgz", + "integrity": "sha512-lmCYCcXxW8C6ecFH2whZCt31NT1ejb0P/sbytK7f4ctyA06Q8iYFEcYE4eWOXMdpfkwkcnz31x9XL77OGeSC2Q==", + "dependencies": { + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0", + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.2.2", + "sparqlalgebrajs": "^4.2.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/core": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/core/-/core-2.10.0.tgz", + "integrity": "sha512-onsGs2iKHUPRxxMOdx42vdxslk8q9FQZdRjQtHJ6SGiCpJwIL9ciBgPIOl2RL2YfzXHemr/0umeNOppRDcWhJA==", + "dependencies": { + "@comunica/types": "^2.10.0", + "immutable": "^4.1.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/mediator-combine-pipeline": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-combine-pipeline/-/mediator-combine-pipeline-2.10.0.tgz", + "integrity": "sha512-j7+/oUlbhKB4Rq6g9oNKU+e9cQL8U9z8tAUNhoXUSHajcr4huj0t1+riaOD109/DRWhV793ILhBDzgiZbHd7DA==", + "dependencies": { + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/mediator-combine-union": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-combine-union/-/mediator-combine-union-2.10.0.tgz", + "integrity": "sha512-QbP4zP1i6nMDZ8teC0RoTz5E8pOpxDhWPBr1ylb2jzPUjPpMgrnbHYTondlN0Oau3SMEehItojg/LYDtPOP/GQ==", + "dependencies": { + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/mediator-number": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-number/-/mediator-number-2.10.0.tgz", + "integrity": "sha512-0T8D1HGTu5Sd8iKb2dBjc6VRc/U4A15TAN6m561ra9pFlP+w31kby0ZYP6WWBHBobbUsX1LCvnbRQaAC4uWwVw==", + "dependencies": { + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/mediator-race": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-race/-/mediator-race-2.10.0.tgz", + "integrity": "sha512-JiEtOLMkPnbjSLabVpE4VqDbu2ZKKnkUdATGBeWX+o+MjPw6c0hhw01RG4WY2rQhDyNl++nLQe3EowQh8xW9TA==", + "dependencies": { + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/mediatortype-time": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/mediatortype-time/-/mediatortype-time-2.10.0.tgz", + "integrity": "sha512-nBz1exxrja1Tj8KSlSevG4Hw2u09tTh6gtNfVjI76i/e7muu4RUWVhi9b8PcwBNAfuUqRl+5OgOSa2X4W+6QlA==", + "dependencies": { + "@comunica/core": "^2.10.0" + } + }, + "node_modules/rdf-dereference/node_modules/@comunica/types": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/types/-/types-2.10.0.tgz", + "integrity": "sha512-1UjPGbZcYrapBjMGUZedrIGcn9rOLpEOlJo1ZkWddFUGTwndVg9d4BZnQw+UnQzXMcLJcdKt94Zns8iEmBqARw==", + "dependencies": { + "@rdfjs/types": "*", + "@types/yargs": "^17.0.24", + "asynciterator": "^3.8.1", + "sparqlalgebrajs": "^4.2.0" + } + }, + "node_modules/rdf-isomorphic": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rdf-isomorphic/-/rdf-isomorphic-1.3.1.tgz", + "integrity": "sha512-6uIhsXTVp2AtO6f41PdnRV5xZsa0zVZQDTBdn0br+DZuFf5M/YD+T6m8hKDUnALI6nFL/IujTMLgEs20MlNidQ==", + "dependencies": { + "@rdfjs/types": "*", + "hash.js": "^1.1.7", + "rdf-string": "^1.6.0", + "rdf-terms": "^1.7.0" + } + }, + "node_modules/rdf-literal": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rdf-literal/-/rdf-literal-1.3.2.tgz", + "integrity": "sha512-79Stlu3sXy0kq9/decHFLf3xNPuY6sfhFPhd/diWErgaFr0Ekyg38Vh9bnVcqDYu48CFRi0t+hrFii49n92Hbw==", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/rdf-object": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/rdf-object/-/rdf-object-1.14.0.tgz", + "integrity": "sha512-/KSUWr7onDtL7d81kOpcUzJ2vHYOYJc2KU9WzBZRYydBhK0Sksh5Hg4VCQNaxUEvYEgdrrTuq9SLpOOCmag0rQ==", + "dependencies": { + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.0.2", + "rdf-data-factory": "^1.1.0", + "rdf-string": "^1.6.0", + "streamify-array": "^1.0.1" + } + }, + "node_modules/rdf-parse": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/rdf-parse/-/rdf-parse-2.3.3.tgz", + "integrity": "sha512-N5XEHm+ajFzwo/vVNzB4tDtvqMwBosbVJmZl5DlzplQM9ejlJBlN/43i0ImAb/NMtJJgQPC3jYnkCKGA7wdo/w==", + "dependencies": { + "@comunica/actor-http-fetch": "^2.0.1", + "@comunica/actor-http-proxy": "^2.0.1", + "@comunica/actor-rdf-parse-html": "^2.0.1", + "@comunica/actor-rdf-parse-html-microdata": "^2.0.1", + "@comunica/actor-rdf-parse-html-rdfa": "^2.0.1", + "@comunica/actor-rdf-parse-html-script": "^2.0.1", + "@comunica/actor-rdf-parse-jsonld": "^2.0.1", + "@comunica/actor-rdf-parse-n3": "^2.0.1", + "@comunica/actor-rdf-parse-rdfxml": "^2.0.1", + "@comunica/actor-rdf-parse-shaclc": "^2.6.2", + "@comunica/actor-rdf-parse-xml-rdfa": "^2.0.1", + "@comunica/bus-http": "^2.0.1", + "@comunica/bus-init": "^2.0.1", + "@comunica/bus-rdf-parse": "^2.0.1", + "@comunica/bus-rdf-parse-html": "^2.0.1", + "@comunica/config-query-sparql": "^2.0.1", + "@comunica/core": "^2.0.1", + "@comunica/mediator-combine-pipeline": "^2.0.1", + "@comunica/mediator-combine-union": "^2.0.1", + "@comunica/mediator-number": "^2.0.1", + "@comunica/mediator-race": "^2.0.1", + "@rdfjs/types": "*", + "readable-stream": "^4.3.0", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-abstract-mediatyped": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-abstract-mediatyped/-/actor-abstract-mediatyped-2.10.0.tgz", + "integrity": "sha512-0o6WBujsMnIVcwvRJv6Nj+kKPLZzqBS3On48rm01Rh9T1/My0E/buJMXwgcARKCfMonc2mJ9zxpPCh5ilGEU2A==", + "dependencies": { + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-abstract-parse": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-abstract-parse/-/actor-abstract-parse-2.10.0.tgz", + "integrity": "sha512-0puCWF+y24EDOOAUUVVbC+tOf4UV+LzEbqi8T5v25jcVGCXyTqfra+bDywfrcv3adrVp18jLCJ46ycaH5xhy9Q==", + "dependencies": { + "@comunica/core": "^2.10.0", + "readable-stream": "^4.4.2" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-http-fetch": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-fetch/-/actor-http-fetch-2.10.2.tgz", + "integrity": "sha512-siHGx0TMVNb2gXvOroq0B3JE6uuS+4s+MsDkntqdBNVigwVYqLpNSKEaL5is8pputFfohJfDQY06lAHbfDNEcw==", + "dependencies": { + "@comunica/bus-http": "^2.10.2", + "@comunica/context-entries": "^2.10.0", + "@comunica/mediatortype-time": "^2.10.0", + "abort-controller": "^3.0.0", + "cross-fetch": "^4.0.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-http-proxy": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-proxy/-/actor-http-proxy-2.10.2.tgz", + "integrity": "sha512-3yUF8BCh4nwq8J6NRILEsyNrQNStkE9ggJ7hYwRfA1XcMgz1pANNaWJ2P2TEKH1jNinr23bL3JeuUZCm9Kz9dA==", + "dependencies": { + "@comunica/bus-http": "^2.10.2", + "@comunica/context-entries": "^2.10.0", + "@comunica/mediatortype-time": "^2.10.0", + "@comunica/types": "^2.10.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html/-/actor-rdf-parse-html-2.10.0.tgz", + "integrity": "sha512-zgImXKpc+BN1i6lQiN1Qhlb1HbKdMIeJMOys6qbzRIijdK8GkGGChwhQp7Cso3lY1Nf4K7M3jPLZeQXeED2w7g==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/bus-rdf-parse-html": "^2.10.0", + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0", + "@rdfjs/types": "*", + "htmlparser2": "^9.0.0", + "readable-stream": "^4.4.2" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-microdata": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-microdata/-/actor-rdf-parse-html-microdata-2.10.0.tgz", + "integrity": "sha512-JLfiDauq4SmpI6TDS4HaHzI6iJe1j8lSk5FRRYK6YVEu8eO28jPmxQJiOiwbQiYqsjsV7kON/WIZSoUELoI4Ig==", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^2.10.0", + "@comunica/core": "^2.10.0", + "microdata-rdf-streaming-parser": "^2.0.1" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-rdfa": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-rdfa/-/actor-rdf-parse-html-rdfa-2.10.0.tgz", + "integrity": "sha512-9K3iaws9+FGl50oZi53hqyzhwjNKZ3mIr2zg/TAJZoapKvc14cthH17zKSSJrqI/NgBStRmZhBBkXcwfu1CANw==", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^2.10.0", + "@comunica/core": "^2.10.0", + "rdfa-streaming-parser": "^2.0.1" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-html-script": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-script/-/actor-rdf-parse-html-script-2.10.0.tgz", + "integrity": "sha512-7XYqWchDquWnBLjG7rmmY+tdE81UZ8fPCU0Hn+vI39/MikNOpaiyr/ZYFqhogWFa9SkjmH0a7idVUzmjiwKRZQ==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/bus-rdf-parse-html": "^2.10.0", + "@comunica/context-entries": "^2.10.0", + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0", + "@rdfjs/types": "*", + "readable-stream": "^4.4.2", + "relative-to-absolute-iri": "^1.0.7" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-jsonld": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-jsonld/-/actor-rdf-parse-jsonld-2.10.2.tgz", + "integrity": "sha512-K4fvD0zMU22KkQCqIFVT5Oy2FREEZ9CAo9u6kOcsMxEvg9aHGIM6hkaXR8I+1JCx1mDuEj3zQ8joR4tQh8fYCw==", + "dependencies": { + "@comunica/bus-http": "^2.10.2", + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/context-entries": "^2.10.0", + "@comunica/core": "^2.10.0", + "@comunica/types": "^2.10.0", + "jsonld-context-parser": "^2.2.2", + "jsonld-streaming-parser": "^3.0.1", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-n3": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-n3/-/actor-rdf-parse-n3-2.10.0.tgz", + "integrity": "sha512-o1MAbwJxW4Br2WCZdhFoRmAiOP4mfogeQqJ4nqlsOkoMtQ45EvLHsotb3Kqhuk5V+vsTxyK5v/a4zylGtcU7VQ==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/types": "^2.10.0", + "n3": "^1.17.0" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-rdfxml": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-rdfxml/-/actor-rdf-parse-rdfxml-2.10.0.tgz", + "integrity": "sha512-HoJN52shXY3cvYtsS0cpin9KXpW3L7g1leebyCRSqnlnHdJv5D6G0Ep8vyt2xhquKNbOQ7LnP5VhiDiqz73XDg==", + "dependencies": { + "@comunica/bus-rdf-parse": "^2.10.0", + "@comunica/types": "^2.10.0", + "rdfxml-streaming-parser": "^2.2.3" + } + }, + "node_modules/rdf-parse/node_modules/@comunica/actor-rdf-parse-shaclc": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-shaclc/-/actor-rdf-parse-shaclc-2.10.0.tgz", "integrity": "sha512-i6tmuZuS+RtDiSXpQc3s/PxtCqwIguo4ANmVB20PK4VWgQgBwoPG7LlNcJ0xmuH/3Bv6C2Agn18PLF6dZX+fKw==", @@ -17836,6 +18903,33 @@ "resolved": "https://registry.npmjs.org/readable-stream-node-to-web/-/readable-stream-node-to-web-1.0.1.tgz", "integrity": "sha512-OGzi2VKLa8H259kAx7BIwuRrXHGcxeHj4RdASSgEGBP9Q2wowdPvBc65upF4Q9O05qWgKqBw1+9PiLTtObl7uQ==" }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -17943,6 +19037,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -17973,6 +19072,20 @@ "node": ">=10" } }, + "node_modules/responselike": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", @@ -18761,6 +19874,11 @@ "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", "dev": true }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==" + }, "node_modules/split-on-first": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", @@ -18786,6 +19904,41 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" }, + "node_modules/ssh-remote-port-forward": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz", + "integrity": "sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==", + "dependencies": { + "@types/ssh2": "^0.5.48", + "ssh2": "^1.4.0" + } + }, + "node_modules/ssh-remote-port-forward/node_modules/@types/ssh2": { + "version": "0.5.52", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.52.tgz", + "integrity": "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==", + "dependencies": { + "@types/node": "*", + "@types/ssh2-streams": "*" + } + }, + "node_modules/ssh2": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.15.0.tgz", + "integrity": "sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw==", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.9", + "nan": "^2.18.0" + } + }, "node_modules/stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", @@ -18892,6 +20045,19 @@ "resolved": "https://registry.npmjs.org/streamify-string/-/streamify-string-1.0.1.tgz", "integrity": "sha512-RXvBglotrvSIuQQ7oC55pdV40wZ/17gTb68ipMC4LA0SqMN4Sqfsf31Dpei7qXpYqZQ8ueVnPglUvtep3tlhqw==" }, + "node_modules/streamx": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", + "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -19146,6 +20312,90 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-fs/node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/temp-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", @@ -19211,6 +20461,67 @@ "node": ">=8" } }, + "node_modules/testcontainers": { + "version": "10.10.1", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.10.1.tgz", + "integrity": "sha512-bw86BLq2/ljJ/gLg3PBsyhYOoDBkyo87/MnpWLavYTAyWR7feGFnAA87qRLq2SSCOSFLHsgCA8+u7Eg+opSmTQ==", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.29", + "archiver": "^5.3.2", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^3.3.5", + "get-port": "^5.1.1", + "node-fetch": "^2.7.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.6", + "tmp": "^0.2.3" + } + }, + "node_modules/testcontainers/node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/testcontainers/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/testcontainers/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "node_modules/testcontainers/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/text-decoder": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", + "integrity": "sha512-TmLJNj6UgX8xcUZo4UDStGQtDiTzF7BzWlzn9g7UWrjkpHr5uJTK1ld16wZ3LXb2vb6jH8qU89dW5whuMdXYdw==", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-extensions": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", @@ -19426,6 +20737,11 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, "node_modules/type": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", @@ -20150,6 +21466,52 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } } } } diff --git a/package.json b/package.json index 8de4a8c..5a29e51 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,7 @@ "chalk": "^5.3.0", "commander": "^12.1.0", "glob": "^7.2.3", + "got": "^14.4.1", "inquirer": "^9.3.0", "js-yaml": "^4.1.0", "lodash.clonedeep": "^4.5.0", @@ -99,6 +100,8 @@ "ora": "^7.0.1", "parse-duration": "^1.1.0", "pretty-ms": "^8.0.0", - "sparqljs": "^3.7.1" + "rdf-dereference": "^2.2.0", + "sparqljs": "^3.7.1", + "testcontainers": "^10.10.0" } } diff --git a/src/configuration.d.ts b/src/configuration.d.ts index 5499923..f2afe19 100644 --- a/src/configuration.d.ts +++ b/src/configuration.d.ts @@ -46,6 +46,10 @@ export interface Configuration { * SPARQL endpoint for the iterator. If it starts with `file://`, a local RDF file is queried. If omitted the result of the previous stage is used. */ endpoint?: string; + /** + * Optional name of the store this endpoint should be imported into before querying. If omitted, the endpoint is queried directly. + */ + importTo?: string; /** * Number of `$this` bindings retrieved per query. Defaults to the LIMIT value of your iterator query or 10 if no LIMIT is present. */ @@ -107,6 +111,10 @@ export interface Configuration { * SPARQL endpoint for the iterator. If it starts with `file://`, a local RDF file is queried. If omitted the result of the previous stage is used. */ endpoint?: string; + /** + * Optional name of the store this endpoint should be imported into before querying. If omitted, the endpoint is queried directly. + */ + importTo?: string; /** * Number of `$this` bindings retrieved per query. Defaults to the LIMIT value of your iterator query or 10 if no LIMIT is present. */ @@ -155,4 +163,21 @@ export interface Configuration { destination?: string; }[] ]; + /** + * A list of SPARQL 1.1 Graph Stores that can be used in the pipeline. + */ + stores?: { + /** + * The store’s query URL. + */ + queryUrl: string; + /** + * The store’s Graph Store HTTP Protocol URL. + */ + storeUrl?: string; + /** + * The store’s SPARQL Update URL. + */ + updateUrl?: string; + }[]; } diff --git a/src/generator.ts b/src/generator.ts index 9680488..6be7457 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -45,10 +45,13 @@ export default class Generator extends EventEmitter { ) ); - this.endpoint = - stage.configuration.generator[this.index].endpoint === undefined - ? stage.iterator.endpoint - : getEndpoint(stage, 'generator', this.index); + if (stage.configuration.generator[this.index].endpoint === undefined) { + // No endpoint configured, so use the iterator’s endpoint. + this.endpoint = stage.iterator.endpoint; + this.query = this.query.withDefaultGraph(stage.importer?.graph); + } else { + this.endpoint = getEndpoint(stage, 'generator', this.index); + } this.engine = getEngine(this.endpoint); diff --git a/src/import.ts b/src/import.ts new file mode 100644 index 0000000..f9e0305 --- /dev/null +++ b/src/import.ts @@ -0,0 +1,126 @@ +import File from './file.js'; +import * as querystring from 'node:querystring'; +import path from 'path'; +import N3, {DataFactory} from 'n3'; +import rdfDereferencer from 'rdf-dereference'; +import {pipeline} from 'node:stream/promises'; +import got, {TimeoutError} from 'got'; +import {PassThrough} from 'node:stream'; +import {QueryEngine} from '@comunica/query-sparql'; +import pRetry from 'p-retry'; +import EventEmitter from 'node:events'; +import type {NamedNode} from '@rdfjs/types'; +import namedNode = DataFactory.namedNode; + +interface Events { + imported: [numOfTriples: number]; + end: [numOfTriples: number]; +} + +export class Importer extends EventEmitter { + public readonly graph: NamedNode; + constructor( + private readonly store: GraphStore, + public readonly file: File, + private readonly queryEngine: QueryEngine = new QueryEngine() + ) { + super(); + this.graph = namedNode( + 'import:' + querystring.escape(path.basename(file.toString())) + ); + } + + public async run() { + if (undefined !== this.store.options.storeUrl) { + await this.importWithGraphStoreProtocol(this.store.options.storeUrl); + await this.dataLoaded(); + } else { + throw new Error('Not supported'); + } + } + + /** + * Wait for data to be available in the SPARQL store + */ + private async dataLoaded() { + await pRetry( + async () => { + const result = await this.queryEngine.queryBindings( + `SELECT * FROM <${this.graph.value}> WHERE { ?s ?p ?o } LIMIT 1`, + { + sources: [ + { + type: 'sparql', + value: this.store.options.queryUrl.toString(), + }, + ], + } + ); + const results = await result.toArray(); + if (results.length === 0) { + throw new Error('No data loaded'); + } + }, + {retries: 3} + ); + } + + public async importWithGraphStoreProtocol(url: URL) { + const graphUrl = new URL(url.toString()); + graphUrl.searchParams.set('graph', this.graph.value); + + const {data} = await rdfDereferencer.default.dereference( + this.file.toString(), + {localFiles: true} + ); + + let numOfTriples = 0; + data.on('data', () => { + numOfTriples++; + if (numOfTriples % 1000 === 0) { + this.emit('imported', numOfTriples); + } + }); + + const writer = new N3.StreamWriter({format: 'N-Triples'}); + const request = got.stream.put(graphUrl.toString(), { + headers: { + 'Content-Type': 'application/n-triples', + }, + maxRedirects: 0, + timeout: { + response: 1000, + }, + }); + + try { + await pipeline( + data, + writer, + request, + new PassThrough() // Catch response errors. + ); + } catch (e) { + if (!(e instanceof TimeoutError)) { + // Ignore TimeoutErrors because some graph stores, such as Oxigraph, don’t correctly respond to the streaming request. + throw e; + } + } + + this.emit('end', numOfTriples); + } + + public get url() { + return this.store.options.queryUrl; + } +} + +export class GraphStore { + constructor( + public readonly options: {queryUrl: URL; storeUrl?: URL; updateUrl?: URL} + ) { + if (undefined === options.storeUrl && undefined === options.updateUrl) { + throw new Error('Store must have at least one of storeUrl or updateUrl'); + } + } +} diff --git a/src/iterator.ts b/src/iterator.ts index 1bf885e..b454144 100644 --- a/src/iterator.ts +++ b/src/iterator.ts @@ -1,14 +1,10 @@ import EventEmitter from 'node:events'; import sparqljs, {type SelectQuery, type VariableTerm} from 'sparqljs'; -import type Stage from './stage.js'; import type {NamedNode} from '@rdfjs/types'; -import getSPARQLQuery from './utils/getSPARQLQuery.js'; import {type Bindings} from '@comunica/types'; -import getEndpoint from './utils/getEndpoint.js'; import type {Endpoint, QueryEngine, QuerySource} from './types.js'; import getEngine from './utils/getEngine.js'; import getEngineSource from './utils/getEngineSource.js'; -import parse from 'parse-duration'; import {BaseQuery} from './sparql.js'; const DEFAULT_LIMIT = 10; @@ -20,30 +16,18 @@ interface Events { } export default class Iterator extends EventEmitter { - private readonly query: Query; - public readonly endpoint: Endpoint; private readonly engine: QueryEngine; - private readonly delay: number = 0; private source?: QuerySource; private offset = 0; public totalResults = 0; - constructor(stage: Stage) { + constructor( + public readonly query: Query, + public readonly endpoint: Endpoint, + private readonly delay: number = 0 + ) { super(); - this.query = Query.from( - getSPARQLQuery(stage.configuration.iterator.query, 'select'), - stage.configuration.iterator.batchSize - ); - this.endpoint = getEndpoint(stage); this.engine = getEngine(this.endpoint); - if (stage.configuration.iterator.delay !== undefined) { - const delay = parse(stage.configuration.iterator.delay); - if (delay === undefined) - throw new Error( - `Error in stage \`${stage.configuration.name}\`: incorrect delay format was provided.` - ); - this.delay = delay; - } } public async run(): Promise { diff --git a/src/main.ts b/src/main.ts index 2b68990..14d1c43 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,7 +12,7 @@ console.info( chalk.bold(`Welcome to LD Workbench version ${chalk.cyan(version())}`) ); -async function main(): Promise { +(async () => { const pipelines = loadPipelines(cli.config ?? './pipelines/'); const names = [...pipelines.keys()]; let configuration: Configuration | undefined; @@ -22,7 +22,6 @@ async function main(): Promise { if (configuration === undefined) { error( `No pipeline named “${cli.pipeline}” was found.`, - 2, `Valid pipeline names are: ${names.map(name => `"${name}"`).join(', ')}` ); } @@ -62,14 +61,6 @@ async function main(): Promise { }); await pipeline.run(); } catch (e) { - error( - `Error in pipeline ${chalk.italic(configuration.name)}`, - 5, - e as Error - ); + error(`Error in pipeline ${chalk.italic(configuration.name)}`, e as Error); } -} - -main().catch(e => { - error(e as Error); -}); +})(); diff --git a/src/pipeline.ts b/src/pipeline.ts index 5bb4047..e99110b 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -12,6 +12,7 @@ import {memoryConsumption} from './utils/memory.js'; import {Progress} from './progress.js'; import {millify} from 'millify'; import formatDuration from './utils/formatDuration.js'; +import {GraphStore} from './import.js'; interface PipelineOptions { startFromStageName?: string; silent?: boolean; @@ -23,10 +24,11 @@ class Pipeline { private stageNames: string[] = []; private startTime = performance.now(); private readonly destination: File | TriplyDB; + public readonly stores: GraphStore[] = []; private readonly opts?: PipelineOptions; public constructor( - private readonly $configuration: Configuration, + private readonly configuration: Configuration, pipelineOptions?: PipelineOptions ) { // create data folder: @@ -34,7 +36,7 @@ class Pipeline { this.dataDir = path.join( 'pipelines', 'data', - kebabcase(this.$configuration.name) + kebabcase(this.configuration.name) ); fs.mkdirSync(this.dataDir, {recursive: true}); const destinationFile = @@ -61,6 +63,20 @@ class Pipeline { this.destination = isTriplyDBPathString(destinationFile) ? new TriplyDB(destinationFile).validate() : new File(destinationFile, true).validate(); + + this.stores = (configuration.stores ?? []).map( + storeConfig => + new GraphStore({ + queryUrl: new URL(storeConfig.queryUrl), + updateUrl: storeConfig.updateUrl + ? new URL(storeConfig.updateUrl) + : undefined, + storeUrl: storeConfig.storeUrl + ? new URL(storeConfig.storeUrl) + : undefined, + }) + ); + this.validate(); } @@ -86,33 +102,37 @@ class Pipeline { } private validate(): void { - if (this.$configuration.stages.length === 0) { + if (this.configuration.stages.length === 0) { throw new Error('Your pipeline contains no stages.'); } - if (this.$configuration.stages[0].iterator.endpoint === undefined) { + if (this.configuration.stages[0].iterator.endpoint === undefined) { throw new Error( 'The first stage of your pipeline must have an endpoint defined for the Iterator.' ); } - for (const stageConfiguration of this.$configuration.stages) { + for (const stageConfiguration of this.configuration.stages) { if (this.stages.has(stageConfiguration.name)) { throw new Error( `Detected a duplicate name for stage \`${stageConfiguration.name}\` in your pipeline: each stage must have a unique name.` ); } - this.stages.set( - stageConfiguration.name, - new Stage(this, stageConfiguration) - ); + try { + this.stages.set( + stageConfiguration.name, + new Stage(this, stageConfiguration) + ); + } catch (e) { + throw new Error( + `Error in the iterator of stage \`${stageConfiguration.name}\`: ${ + (e as Error).message + }` + ); + } } } - public get configuration(): Configuration { - return this.$configuration; - } - public async run(): Promise { const progress = new Progress({silent: this.opts?.silent === true}) .line(chalk.cyan(`▶ Starting pipeline “${chalk.bold(this.name)}”`)) @@ -188,7 +208,6 @@ class Pipeline { }); stage.on('error', e => { reject(e); - this.error(e); }); stage.on('end', (iris, statements) => { progress.succeed( @@ -202,6 +221,7 @@ class Pipeline { ); resolve(); }); + this.monitorImport(stage, progress); try { stage.run(); } catch (e) { @@ -228,6 +248,31 @@ class Pipeline { ); } + private monitorImport(stage: Stage, progress: Progress) { + let importStartTime: number; + + stage.on('importStart', () => { + progress.start('Importing data to SPARQL store'); + importStartTime = performance.now(); + }); + stage.on('imported', numOfTriples => { + progress.text( + `Importing data to SPARQL store\n\n Statements: ${millify( + numOfTriples + )}\n Duration: ${formatDuration(importStartTime, performance.now())} ` + ); + }); + stage.on('importSuccess', numOfTriples => { + progress.succeed( + `Imported ${millify( + numOfTriples + )} statements to SPARQL store (took ${prettyMilliseconds( + performance.now() - importStartTime + )})` + ); + }); + } + private async writeResult(): Promise { const progress = new Progress({silent: this.opts?.silent === true}).start( 'Writing results to destination' @@ -240,11 +285,11 @@ class Pipeline { } get name(): string { - return this.$configuration.name; + return this.configuration.name; } get description(): string | undefined { - return this.$configuration.description; + return this.configuration.description; } private increaseProgress( diff --git a/src/sparql.ts b/src/sparql.ts index 4aff382..e3b193e 100644 --- a/src/sparql.ts +++ b/src/sparql.ts @@ -1,12 +1,20 @@ -import sparqljs, {type SparqlQuery} from 'sparqljs'; +import sparqljs, {Query} from 'sparqljs'; +import {NamedNode} from '@rdfjs/types'; const {Generator} = sparqljs; const generator = new Generator(); export abstract class BaseQuery { - protected constructor(protected readonly query: SparqlQuery) {} + protected constructor(protected readonly query: Query) {} protected abstract validate(): void; public toString = () => generator.stringify(this.query); + + public withDefaultGraph(graph?: NamedNode): this { + if (undefined !== graph) { + this.query.from = {default: [graph], named: []}; + } + return this; + } } diff --git a/src/stage.ts b/src/stage.ts index bccb399..60f347f 100644 --- a/src/stage.ts +++ b/src/stage.ts @@ -1,7 +1,7 @@ import EventEmitter from 'node:events'; import File from './file.js'; import {Configuration} from './configuration.js'; -import Iterator from './iterator.js'; +import Iterator, {Query} from './iterator.js'; import Generator from './generator.js'; import kebabcase from 'lodash.kebabcase'; import type Pipeline from './pipeline.js'; @@ -10,8 +10,15 @@ import {Writer} from 'n3'; import type {NamedNode} from '@rdfjs/types'; import type {WriteStream} from 'node:fs'; import {isPreviousStage} from './utils/guards.js'; +import getSPARQLQuery from './utils/getSPARQLQuery.js'; +import parse from 'parse-duration'; +import getEndpoint from './utils/getEndpoint.js'; +import {Importer} from './import.js'; interface Events { + importStart: []; + imported: [numOfTriples: number]; + importSuccess: [numOfTriples: number]; generatorResult: [count: number]; end: [iteratorCount: number, statements: number]; iteratorResult: [$this: NamedNode, quadsGenerated: number]; @@ -19,9 +26,10 @@ interface Events { } export default class Stage extends EventEmitter { - public destination: () => WriteStream; - public iterator: Iterator; - public generators: Generator[] = []; + public readonly destination: () => WriteStream; + public readonly iterator: Iterator; + public readonly generators: Generator[] = []; + public readonly importer?: Importer; private iteratorEnded = false; public constructor( @@ -29,23 +37,35 @@ export default class Stage extends EventEmitter { public readonly configuration: Configuration['stages'][0] ) { super(); - try { - this.iterator = new Iterator(this); - } catch (e) { - throw new Error( - `Error in the iterator of stage \`${configuration.name}\`: ${ - (e as Error).message - }` + + const endpoint = getEndpoint(this); + if ( + undefined !== configuration.iterator['importTo'] && + endpoint instanceof File + ) { + const storeUrl = configuration.iterator['importTo']!; + const store = pipeline.stores.find( + store => store.options.queryUrl.toString() === storeUrl ); + if (store === undefined) { + throw new Error(`No store configured with queryUrl ${storeUrl}`); + } + this.importer = new Importer(store, endpoint); } + this.iterator = new Iterator( + Query.from( + getSPARQLQuery(configuration.iterator.query, 'select'), + configuration.iterator.batchSize + ).withDefaultGraph(this.importer?.graph), + this.importer?.url ?? endpoint, + this.parseDelay(configuration.iterator.delay) + ); + // Handle both single generator and array of generators for (let index = 0; index < this.configuration.generator.length; index++) { - const generatorConfig = this.configuration.generator[index]; try { - this.generators.push( - new Generator({...this, generators: [generatorConfig]}, index) - ); + this.generators.push(new Generator(this, index)); } catch (e) { throw new Error( `Error in the generator of stage \`${configuration.name}\`: ${ @@ -74,6 +94,21 @@ export default class Stage extends EventEmitter { format: 'N-Triples', }); + if (this.importer !== undefined) { + this.importer.on('imported', numOfTriples => + this.emit('imported', numOfTriples) + ); + this.importer.on('end', numOfTriples => + this.emit('importSuccess', numOfTriples) + ); + this.emit('importStart'); + try { + await this.importer.run(); + } catch (e) { + this.emit('error', e as Error); + } + } + const generatorProcessedCounts = new Map(); let quadsGenerated = 0; @@ -121,7 +156,22 @@ export default class Stage extends EventEmitter { }); // Start the iterator - this.iterator.run(); + await this.iterator.run(); + } + + private parseDelay(delay?: string) { + if (delay === undefined) { + return undefined; + } + + const parsed = parse(delay); + if (parsed === undefined) { + throw new Error( + `Error in stage “${this.configuration.name}”: incorrect delay format was provided.` + ); + } + + return parsed; } } diff --git a/src/utils/error.ts b/src/utils/error.ts index 5294139..9378bed 100644 --- a/src/utils/error.ts +++ b/src/utils/error.ts @@ -2,16 +2,10 @@ import chalk from 'chalk'; export const error = ( message: string | Error, - exitCode?: number, ...info: Array ): void => { console.error( chalk.red(message instanceof Error ? message.message : message) ); - if (info.length > 0) { - for (const i of info) { - console.info(i instanceof Error ? i.message : i); - } - } - throw message; + info.forEach(i => console.info(i)); }; diff --git a/src/utils/formatDuration.ts b/src/utils/formatDuration.ts index 788a38a..44760d0 100644 --- a/src/utils/formatDuration.ts +++ b/src/utils/formatDuration.ts @@ -8,9 +8,7 @@ export default function formatDuration( const minutes = Math.floor((durationInMilliseconds % 3600000) / 60000); const seconds = Math.floor((durationInMilliseconds % 60000) / 1000); - const formattedDuration = `${hours.toString().padStart(2, '0')}:${minutes + return `${hours.toString().padStart(2, '0')}:${minutes .toString() .padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; - - return formattedDuration; } diff --git a/static/ld-workbench.schema.json b/static/ld-workbench.schema.json index f1a0d1e..ad96539 100644 --- a/static/ld-workbench.schema.json +++ b/static/ld-workbench.schema.json @@ -1,7 +1,7 @@ { "$id": "https://raw.githubusercontent.com/netwerk-digitaal-erfgoed/ld-workbench/main/static/ld-workbench.schema.json", "$schema": "http://json-schema.org/draft-07/schema#", - "title": "LDWorkbenchConfiguration", + "title": "Configuration", "description": "JSON Schema for LDWorkbench.\nIt helps with the writing of the configuration needed to run LDWorkbench pipelines.", "type": "object", "additionalProperties": false, @@ -47,6 +47,10 @@ "type": "string", "description": "SPARQL endpoint for the iterator. If it starts with `file://`, a local RDF file is queried. If omitted the result of the previous stage is used." }, + "importTo": { + "type": "string", + "description": "Optional name of the store this endpoint should be imported into before querying. If omitted, the endpoint is queried directly." + }, "batchSize": { "type": "number", "minimum": 1, @@ -90,6 +94,29 @@ }, "required": ["name", "iterator", "generator"] } + }, + "stores": { + "type": "array", + "description": "A list of SPARQL 1.1 Graph Stores that can be used in the pipeline.", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "queryUrl": { + "type": "string", + "description": "The store’s query URL." + }, + "storeUrl": { + "type": "string", + "description": "The store’s Graph Store HTTP Protocol URL." + }, + "updateUrl": { + "type": "string", + "description": "The store’s SPARQL Update URL." + } + }, + "required": ["queryUrl"] + } } }, "required": ["name", "stages"] diff --git a/test/fixtures/import/config.yml b/test/fixtures/import/config.yml new file mode 100644 index 0000000..3236332 --- /dev/null +++ b/test/fixtures/import/config.yml @@ -0,0 +1,20 @@ +name: Import +description: Pipeline that imports a data dump file + +stores: + # Oxigraph + - queryUrl: "http://localhost:7878/query" + storeUrl: "http://localhost:7878/store?no_transaction&lenient" + + # Fuseki + - queryUrl: "http://localhost:3030/persistent" + storeUrl: "http://localhost:3030/persistent" + +stages: + - name: "Stage" + iterator: + query: "SELECT $this WHERE { $this a }" + endpoint: file://../../../static/tests/iris.nt + importTo: http://localhost:7878/query + generator: + - query: "CONSTRUCT WHERE { $this a }" diff --git a/test/import.test.ts b/test/import.test.ts new file mode 100644 index 0000000..7b083c5 --- /dev/null +++ b/test/import.test.ts @@ -0,0 +1,44 @@ +import {GenericContainer, StartedTestContainer, Wait} from 'testcontainers'; +import loadPipelines from '../src/utils/loadPipelines.js'; +import Pipeline from '../src/pipeline.js'; +import fs from 'fs'; + +describe('Import', () => { + let sparqlStore: StartedTestContainer; + + beforeAll(async () => { + sparqlStore = await new GenericContainer('oxigraph/oxigraph:0.4.0-alpha.7') + .withExposedPorts(7878) + .withWaitStrategy(Wait.forLogMessage('Listening')) // Waiting for the port does not work. + .start(); + }, 30_000); + + it('imports an RDF file to a SPARQL store', async () => { + const [[, configuration]] = loadPipelines( + './test/fixtures/import/config.yml' + ).entries(); + + // Replace port. + configuration.stores![0].queryUrl = `http://localhost:${sparqlStore.getMappedPort( + 7878 + )}/query`; + configuration.stores![0].storeUrl = `http://localhost:${sparqlStore.getMappedPort( + 7878 + )}/store?no_transaction&lenient`; + configuration.stages![0].iterator.importTo = + configuration.stores![0].queryUrl; + const pipeline = new Pipeline(configuration, {silent: true}); + + await pipeline.run(); + + const file = fs.readFileSync('pipelines/data/import/statements.nt', { + encoding: 'utf-8', + }); + const numOfTriples = file.split('\n').length - 1; + expect(numOfTriples).toEqual(153); + }, 15_000); + + afterAll(async () => { + // await sparqlStore.stop(); + }); +});