diff --git a/.gitignore b/.gitignore index fc42ab9..f53f58b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ coverage node_modules v8.log package-lock.json +node_modules/ diff --git a/package.json b/package.json index 86c59ce..298257e 100644 --- a/package.json +++ b/package.json @@ -33,19 +33,21 @@ "lib/**/*.js" ], "dependencies": { - "@digitalbazaar/http-client": "^3.2.0", + "@digitalbazaar/http-client": "^4.3.0", "@xmldom/xmldom": "^0.8.2", "content-type": "^1.0.4", "get-stdin": "^9.0.0", - "jsonld": "^8.1.0", + "jsonld": "^9.0.0", "rdfa": "^0.0.10" }, "devDependencies": { "@digitalbazaar/eslint-config": "^8.0.1", - "eslint": "^9.39.4" + "eslint": "^9.39.4", + "mocha": "^11.7.5", + "chai": "^6.2.2" }, "engines": { - "node": ">=14.13.1" + "node": "^20.19.0 || ^22.13.0 || >=24.0.0" }, "keywords": [ "JSON", @@ -57,6 +59,7 @@ "jsonld" ], "scripts": { - "lint": "eslint ." + "lint": "eslint .", + "test": "mocha \"test/**/*.test.js\"" } } diff --git a/test/data/sample.jsonld b/test/data/sample.jsonld new file mode 100644 index 0000000..d7c6c25 --- /dev/null +++ b/test/data/sample.jsonld @@ -0,0 +1,9 @@ +{ + "@context": "https://www.w3.org/ns/credentials/v2", + "id": "urn:uuid:2a1d4ddb-bbda-43cb-8886-fda9855bcf5d", + "type": ["VerifiableCredential"], + "credentialSubject": { + "id": "did:example:123", + "name": "Example" + } +} diff --git a/test/jsonld-request.test.js b/test/jsonld-request.test.js new file mode 100644 index 0000000..23e7de4 --- /dev/null +++ b/test/jsonld-request.test.js @@ -0,0 +1,76 @@ +import * as chai from 'chai'; +import {promises as fs} from 'node:fs'; +import http from 'node:http'; +import {jsonldRequest} from '../lib/index.js'; +import path from 'node:path'; +import {spawn} from 'node:child_process'; + +const should = chai.should(); + +describe('jsonldRequest', function() { + let fixturePath; + let fixtureData; + + before(async () => { + fixturePath = path.join(import.meta.dirname, 'data', 'sample.jsonld'); + fixtureData = await fs.readFile(fixturePath, 'utf8'); + }); + + it('loads a local file (file://) and parses JSON-LD', async () => { + const fileUrl = `file://${fixturePath}`; + const {data} = await jsonldRequest(fileUrl, {allow: ['file']}); + data.should.deep.equal(JSON.parse(fixtureData)); + }); + + it('loads JSON-LD over HTTP and parses it', async () => { + // start local HTTP server to serve the fixture + const server = http.createServer((req, res) => { + const headers = { + 'Content-Type': 'application/ld+json; charset=utf-8' + }; + res.writeHead(200, headers); + res.end(fixtureData); + }); + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); + const addr = server.address(); + const url = `http://127.0.0.1:${addr.port}/fixture.json`; + try { + const {data} = await jsonldRequest(url, {allow: ['http', 'https']}); + should.exist(data); + data.should.be.an('object'); + data.should.have.property('@context'); + } finally { + server.close(); + } + }); + + it('reads JSON-LD from stdin (child process runner)', async () => { + const runner = path.join(import.meta.dirname, 'runner-stdin.js'); + const child = spawn( + process.execPath, + [runner, '-'] + ); + + let stdout = ''; + let stderr = ''; + child.stdout.on('data', d => { + stdout += d.toString(); + }); + child.stderr.on('data', d => { + stderr += d.toString(); + }); + + // write fixture to child's stdin + child.stdin.write(fixtureData); + child.stdin.end(); + + const exitCode = await new Promise(resolve => child.on('close', resolve)); + if(exitCode !== 0) { + throw new Error(`Runner exited with ${exitCode}: ${stderr}`); + } + const parsed = JSON.parse(stdout); + should.exist(parsed); + parsed.should.be.an('object'); + parsed.should.have.property('@context'); + }); +}); diff --git a/test/runner-stdin.js b/test/runner-stdin.js new file mode 100644 index 0000000..cb4a886 --- /dev/null +++ b/test/runner-stdin.js @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import {jsonldRequest} from '../lib/index.js'; + +const loc = process.argv[2] || '-'; +const options = {allow: ['stdin']}; + +jsonldRequest(loc, options).then(({data}) => { + // print only the data as JSON to stdout + console.log(JSON.stringify(data)); +}).catch(err => { + // print error to stderr + console.error(err && err.stack ? err.stack : String(err)); + process.exit(1); +});