glam/packages/api-client/src/clients/sparql.ts
2025-12-21 00:01:54 +01:00

80 lines
1.9 KiB
TypeScript

/**
* @glam/api-client - SPARQL client for Oxigraph
*/
import { getApiConfig } from '../config';
import { SparqlResults } from '../types';
export class SparqlClient {
private endpoint: string;
constructor(endpoint?: string) {
this.endpoint = endpoint || getApiConfig().sparqlEndpoint;
}
/**
* Execute a SPARQL SELECT query
*/
async query(sparql: string): Promise<SparqlResults> {
const response = await fetch(`${this.endpoint}/query`, {
method: 'POST',
headers: {
'Content-Type': 'application/sparql-query',
'Accept': 'application/sparql-results+json',
},
body: sparql,
});
if (!response.ok) {
throw new Error(`SPARQL query failed: ${response.statusText}`);
}
return response.json();
}
/**
* Execute a SPARQL UPDATE query
*/
async update(sparql: string): Promise<void> {
const response = await fetch(`${this.endpoint}/update`, {
method: 'POST',
headers: {
'Content-Type': 'application/sparql-update',
},
body: sparql,
});
if (!response.ok) {
throw new Error(`SPARQL update failed: ${response.statusText}`);
}
}
/**
* Execute a SPARQL CONSTRUCT query and return RDF
*/
async construct(sparql: string, format: 'turtle' | 'ntriples' | 'jsonld' = 'turtle'): Promise<string> {
const acceptMap = {
turtle: 'text/turtle',
ntriples: 'application/n-triples',
jsonld: 'application/ld+json',
};
const response = await fetch(`${this.endpoint}/query`, {
method: 'POST',
headers: {
'Content-Type': 'application/sparql-query',
'Accept': acceptMap[format],
},
body: sparql,
});
if (!response.ok) {
throw new Error(`SPARQL construct failed: ${response.statusText}`);
}
return response.text();
}
}
// Default singleton instance
export const sparqlClient = new SparqlClient();