From baba8fe84e2b1df4089048bb6a86505ccbbc014a Mon Sep 17 00:00:00 2001 From: Laurens Rietveld Date: Fri, 26 Oct 2018 14:38:18 +0200 Subject: [PATCH] Added generics to allow users to deviate from the standard --- types/n3/index.d.ts | 124 +++++++++++++++++++---------------- types/n3/n3-tests.ts | 27 +++++++- types/n3/tslint.json | 5 +- types/rdf-js/index.d.ts | 60 +++++++++++++---- types/rdf-js/rdf-js-tests.ts | 16 +++-- types/rdf-js/tslint.json | 7 +- 6 files changed, 162 insertions(+), 77 deletions(-) diff --git a/types/n3/index.d.ts b/types/n3/index.d.ts index 768cdd7a7e..c303475912 100644 --- a/types/n3/index.d.ts +++ b/types/n3/index.d.ts @@ -3,7 +3,7 @@ // Definitions by: Fred Eisele // Ruben Taelman // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -// TypeScript Version: 2.1 +// TypeScript Version: 2.3 /// @@ -78,13 +78,23 @@ export type Quad_Predicate = NamedNode | Variable; export type Quad_Object = NamedNode | Literal | BlankNode | Variable; export type Quad_Graph = DefaultGraph | NamedNode | BlankNode | Variable; -export class Quad implements RDF.Quad { - constructor(subject: Quad_Subject, predicate: Quad_Predicate, object: Quad_Object, graph?: Quad_Graph); +export class BaseQuad implements RDF.BaseQuad { + constructor(subject: Term, predicate: Term, object: Term, graph?: Term); + subject: Term; + predicate: Term; + object: Term; + graph: Term; + equals(other: RDF.BaseQuad): boolean; + toJSON(): string; +} + +export class Quad extends BaseQuad implements RDF.Quad { + constructor(subject: Term, predicate: Term, object: Term, graph?: Term); subject: Quad_Subject; predicate: Quad_Predicate; object: Quad_Object; graph: Quad_Graph; - equals(other: RDF.Quad): boolean; + equals(other: RDF.BaseQuad): boolean; toJSON(): string; } @@ -96,26 +106,28 @@ export namespace DataFactory { function literal(value: string | number, languageOrDatatype?: string | RDF.NamedNode): Literal; function variable(value: string): Variable; function defaultGraph(): DefaultGraph; - function quad(subject: Quad_Subject, predicate: Quad_Predicate, object: Quad_Object, graph?: Quad_Graph): Quad; - function triple(subject: Quad_Subject, predicate: Quad_Predicate, object: Quad_Object): Quad; + function quad(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object, graph?: Quad_Graph): Quad; + function quad(subject: Q_In['subject'], predicate: Q_In['predicate'], object: Q_In['object'], graph?: Q_In['graph']): Q_Out; + function triple(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object): Quad; + function triple(subject: Q_In['subject'], predicate: Q_In['predicate'], object: Q_In['object']): Q_Out; } export type ErrorCallback = (err: Error, result: any) => void; -export type QuadCallback = (result: Quad) => void; -export type QuadPredicate = (result: Quad) => boolean; +export type QuadCallback = (result: Q) => void; +export type QuadPredicate = (result: Q) => boolean; export type OTerm = RDF.Term | string | null; export type Logger = (message?: any, ...optionalParams: any[]) => void; -export interface BlankTriple { - predicate: RDF.Quad_Predicate; - object: RDF.Quad_Object; +export interface BlankTriple { + predicate: Q['predicate']; + object: Q['object']; } export interface ParserConstructor { - new (options?: ParserOptions): N3Parser; - (options?: ParserOptions): N3Parser; + new (options?: ParserOptions): N3Parser; + (options?: ParserOptions): N3Parser; } export const Parser: ParserConstructor; @@ -126,19 +138,19 @@ export interface ParserOptions { baseIRI?: string; } -export type ParseCallback = (error: Error, quad: Quad, prefixes: Prefixes) => void; +export type ParseCallback = (error: Error, quad: Q, prefixes: Prefixes) => void; -export interface N3Parser { - parse(input: string, callback: ParseCallback): void; +export interface N3Parser { + parse(input: string, callback: ParseCallback): void; } export interface StreamParserConstructor { - new (options?: ParserOptions): N3StreamParser; - (options?: ParserOptions): N3StreamParser; + new (options?: ParserOptions): N3StreamParser; + (options?: ParserOptions): N3StreamParser; } export const StreamParser: StreamParserConstructor; -export interface N3StreamParser extends RDF.Stream, NodeJS.WritableStream, RDF.Sink { +export interface N3StreamParser extends RDF.Stream, NodeJS.WritableStream, RDF.Sink { // Below are the NodeJS.ReadableStream methods, // we can not extend the interface directly, // as `read` clashes with RDF.Sink. @@ -148,10 +160,10 @@ export interface N3StreamParser extends RDF.Stream, NodeJS.WritableStream, RDF.S pause(): this; resume(): this; isPaused(): boolean; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: NodeJS.WritableStream | RDF.Stream): void; + pipe>(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: NodeJS.WritableStream | RDF.Stream): void; unshift(chunk: string | Buffer): void; - wrap(oldStream: NodeJS.ReadableStream | RDF.Stream): NodeJS.ReadableStream; + wrap(oldStream: NodeJS.ReadableStream | RDF.Stream): NodeJS.ReadableStream; } export interface WriterOptions { @@ -161,66 +173,66 @@ export interface WriterOptions { } export interface WriterConstructor { - new (options?: WriterOptions): N3Writer; - new (fd: any, options?: WriterOptions): N3Writer; - (options?: WriterOptions): N3Writer; - (fd: any, options?: WriterOptions): N3Writer; + new (options?: WriterOptions): N3Writer; + new (fd: any, options?: WriterOptions): N3Writer; + (options?: WriterOptions): N3Writer; + (fd: any, options?: WriterOptions): N3Writer; } export const Writer: WriterConstructor; -export interface N3Writer { - quadToString(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object, graph?: RDF.Quad_Graph): string; +export interface N3Writer { + quadToString(subject: Q['subject'], predicate: Q['predicate'], object: Q['object'], graph?: Q['graph']): string; quadsToString(quads: RDF.Quad[]): string; - addQuad(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object | RDF.Quad_Object[], graph?: RDF.Quad_Graph, done?: () => void): void; + addQuad(subject: Q['subject'], predicate: Q['predicate'], object: Q['object'] | Array, graph?: Q['graph'], done?: () => void): void; addQuad(quad: RDF.Quad): void; addQuads(quads: RDF.Quad[]): void; addPrefix(prefix: string, iri: string, done?: () => void): void; addPrefixes(prefixes: Prefixes, done?: () => void): void; end(err?: ErrorCallback, result?: string): void; - blank(predicate: RDF.Quad_Predicate, object: RDF.Quad_Object): BlankNode; + blank(predicate: Q['predicate'], object: Q['object']): BlankNode; blank(triple: BlankTriple | RDF.Quad | BlankTriple[] | RDF.Quad[]): BlankNode; - list(triple: RDF.Quad_Object[]): Quad_Object[]; + list(triple: Array): Quad_Object[]; } export interface StreamWriterConstructor { - new (options?: WriterOptions): N3StreamWriter; - new (fd: any, options?: WriterOptions): N3StreamWriter; - (options?: WriterOptions): N3StreamWriter; - (fd: any, options?: WriterOptions): N3StreamWriter; + new (options?: WriterOptions): N3StreamWriter; + new (fd: any, options?: WriterOptions): N3StreamWriter; + (options?: WriterOptions): N3StreamWriter; + (fd: any, options?: WriterOptions): N3StreamWriter; } export const StreamWriter: StreamWriterConstructor; -export interface N3StreamWriter extends NodeJS.ReadWriteStream, RDF.Source {} +export interface N3StreamWriter extends NodeJS.ReadWriteStream, RDF.Source {} -export interface N3Store extends RDF.Sink { +export interface N3Store extends RDF.Sink { readonly size: number; - addQuad(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object | RDF.Quad_Object[], graph?: RDF.Quad_Graph, done?: () => void): void; - addQuad(quad: RDF.Quad): void; - addQuads(quads: RDF.Quad[]): void; - removeQuad(subject: RDF.Quad_Subject, predicate: RDF.Quad_Predicate, object: RDF.Quad_Object | RDF.Quad_Object[], graph?: RDF.Quad_Graph, done?: () => void): void; - removeQuad(quad: RDF.Quad): void; - removeQuads(quads: RDF.Quad[]): void; + addQuad(subject: Q_RDF['subject'], predicate: Q_RDF['predicate'], object: Q_RDF['object'] | Array, graph?: Q_RDF['graph'], done?: () => void): void; + addQuad(quad: Q_RDF): void; + addQuads(quads: Q_RDF[]): void; + removeQuad(subject: Q_RDF['subject'], predicate: Q_RDF['predicate'], object: Q_RDF['object'] | Array, graph?: Q_RDF['graph'], done?: () => void): void; + removeQuad(quad: Q_RDF): void; + removeQuads(quads: Q_RDF[]): void; getQuads(subject: OTerm, predicate: OTerm, object: OTerm | OTerm[], graph: OTerm): Quad[]; countQuads(subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): number; - forEach(callback: QuadCallback, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): void; - every(callback: QuadPredicate, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): boolean; - some(callback: QuadPredicate, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): boolean; - getSubjects(predicate: OTerm, object: OTerm, graph: OTerm): Quad_Subject[]; - forSubjects(callback: QuadCallback, predicate: OTerm, object: OTerm, graph: OTerm): void; - getPredicates(subject: OTerm, object: OTerm, graph: OTerm): Quad_Predicate[]; - forPredicates(callback: QuadCallback, subject: OTerm, object: OTerm, graph: OTerm): void; - getObjects(subject: OTerm, predicate: OTerm, graph: OTerm): Quad_Object[]; - forObjects(callback: QuadCallback, subject: OTerm, predicate: OTerm, graph: OTerm): void; - getGraphs(subject: OTerm, predicate: OTerm, object: OTerm): Quad_Graph[]; - forGraphs(callback: QuadCallback, subject: OTerm, predicate: OTerm, object: OTerm): void; + forEach(callback: QuadCallback, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): void; + every(callback: QuadPredicate, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): boolean; + some(callback: QuadPredicate, subject: OTerm, predicate: OTerm, object: OTerm, graph: OTerm): boolean; + getSubjects(predicate: OTerm, object: OTerm, graph: OTerm): Array; + forSubjects(callback: QuadCallback, predicate: OTerm, object: OTerm, graph: OTerm): void; + getPredicates(subject: OTerm, object: OTerm, graph: OTerm): Array; + forPredicates(callback: QuadCallback, subject: OTerm, object: OTerm, graph: OTerm): void; + getObjects(subject: OTerm, predicate: OTerm, graph: OTerm): Array; + forObjects(callback: QuadCallback, subject: OTerm, predicate: OTerm, graph: OTerm): void; + getGraphs(subject: OTerm, predicate: OTerm, object: OTerm): Array; + forGraphs(callback: QuadCallback, subject: OTerm, predicate: OTerm, object: OTerm): void; createBlankNode(suggestedName?: string): BlankNode; // match, removeMatches and deleteGraph are missing for full RDF.Store adherence remove(stream: stream.Stream): EventEmitter; } export interface StoreConstructor { - new (triples?: Quad[], options?: StoreOptions): N3Store; - (triples?: Quad[], options?: StoreOptions): N3Store; + new (triples?: Q_RDF[], options?: StoreOptions): N3Store; + (triples?: Q_RDF[], options?: StoreOptions): N3Store; } export const Store: StoreConstructor; diff --git a/types/n3/n3-tests.ts b/types/n3/n3-tests.ts index ee312b6388..7fd3240b64 100644 --- a/types/n3/n3-tests.ts +++ b/types/n3/n3-tests.ts @@ -76,7 +76,13 @@ function test_doc_rdf_to_triples_2() { } function test_doc_rdf_stream_to_triples_1() { - const parser: N3.N3Parser = new N3.Parser({factory: N3.DataFactory}); + interface QuadBnode extends N3.BaseQuad { + subject: N3.BlankNode; + predicate: N3.BlankNode; + object: N3.BlankNode; + graph: N3.BlankNode; + } + const parser: N3.N3Parser = new N3.Parser({factory: N3.DataFactory}); parser.parse('abc', console.log); const streamParser: N3.N3StreamParser = N3.StreamParser(); @@ -177,7 +183,26 @@ function test_doc_storing() { const bnode2: RDF.BlankNode = store.createBlankNode('abc'); const mickey: RDF.Quad = store.getQuads(N3.DataFactory.namedNode('http://ex.org/Mickey'), null, null, null)[0]; + if (mickey.object.termType === "Literal") { + console.log(mickey.object.datatype); + } console.log(mickey.subject, mickey.predicate, mickey.object, '.'); + + interface N3QuadGeneralized extends N3.BaseQuad { + subject: N3.Quad_Subject | N3.BlankNode | N3.Literal; + predicate: N3.Quad_Predicate | N3.BlankNode | N3.Literal; + object: N3.Quad_Object | N3.BlankNode | N3.Literal; + graph: N3.Quad_Graph | N3.BlankNode | N3.Literal; + } + interface RDFQuadGeneralized extends RDF.BaseQuad { + subject: RDF.Quad_Subject | RDF.BlankNode | RDF.Literal; + predicate: RDF.Quad_Predicate | RDF.BlankNode | RDF.Literal; + object: RDF.Quad_Object | RDF.BlankNode | RDF.Literal; + graph: RDF.Quad_Graph | RDF.BlankNode | RDF.Literal; + } + const storeGeneralized = new N3.Store(); + // storeGeneralized. + storeGeneralized.addQuad(N3.DataFactory.namedNode('http://ex.org/Pluto'), N3.DataFactory.blankNode(), N3.DataFactory.namedNode('http://ex.org/Dog')); } function test_doc_utility() { diff --git a/types/n3/tslint.json b/types/n3/tslint.json index d88586e5bd..e27ad90359 100644 --- a/types/n3/tslint.json +++ b/types/n3/tslint.json @@ -1,3 +1,6 @@ { - "extends": "dtslint/dt.json" + "extends": "dtslint/dt.json", + "rules": { + "no-unnecessary-generics": false + } } diff --git a/types/rdf-js/index.d.ts b/types/rdf-js/index.d.ts index db1e3c7127..01afd89108 100644 --- a/types/rdf-js/index.d.ts +++ b/types/rdf-js/index.d.ts @@ -2,6 +2,7 @@ // Project: https://github.com/rdfjs/representation-task-force // Definitions by: Ruben Taelman // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 /// @@ -169,10 +170,42 @@ export type Quad_Object = NamedNode | Literal | BlankNode | Variable; */ export type Quad_Graph = DefaultGraph | NamedNode | BlankNode | Variable; +/** + * An RDF quad, taking any Term in its positions, containing the subject, predicate, object and graph terms. + */ +export interface BaseQuad { + /** + * The subject. + * @see Quad_Subject + */ + subject: Term; + /** + * The predicate. + * @see Quad_Predicate + */ + predicate: Term; + /** + * The object. + * @see Quad_Object + */ + object: Term; + /** + * The named graph. + * @see Quad_Graph + */ + graph: Term; + + /** + * @param other The term to compare with. + * @return True if and only if the argument is a) of the same type b) has all components equal. + */ + equals(other: BaseQuad): boolean; +} + /** * An RDF quad, containing the subject, predicate, object and graph terms. */ -export interface Quad { +export interface Quad extends BaseQuad { /** * The subject. * @see Quad_Subject @@ -198,7 +231,7 @@ export interface Quad { * @param other The term to compare with. * @return True if and only if the argument is a) of the same type b) has all components equal. */ - equals(other: Quad): boolean; + equals(other: BaseQuad): boolean; } /** @@ -263,7 +296,7 @@ export interface DataFactory { * @see Triple * @see DefaultGraph */ - triple(subject: Quad_Subject, predicate: Quad_Predicate, object: Quad_Object): Quad; + triple(subject: Q_In['subject'], predicate: Q_In['predicate'], object: Q_In['object']): Q_Out; /** * @param subject The quad subject term. @@ -273,7 +306,7 @@ export interface DataFactory { * @return A new instance of Quad. * @see Quad */ - quad(subject: Quad_Subject, predicate: Quad_Predicate, object: Quad_Object, graph?: Quad_Graph): Quad; + quad(subject: Q_In['subject'], predicate: Q_In['predicate'], object: Q_In['object'], graph?: Q_In['graph']): Q_Out; } /* Stream Interfaces */ @@ -292,14 +325,14 @@ export interface DataFactory { * Optional events: * * prefix(prefix: string, iri: RDF.NamedNode): This event is emitted every time a prefix is mapped to some IRI. */ -export interface Stream extends EventEmitter { +export interface Stream extends EventEmitter { /** * This method pulls a quad out of the internal buffer and returns it. * If there is no quad available, then it will return null. * * @return A quad from the internal buffer, or null if none is available. */ - read(): Quad; + read(): Q; } /** @@ -309,7 +342,7 @@ export interface Stream extends EventEmitter { * * For example, parsers and transformations which generate quads can implement the Source interface. */ -export interface Source { +export interface Source { /** * Returns a stream that processes all quads matching the pattern. * @@ -319,8 +352,7 @@ export interface Source { * @param graph The optional exact graph or graph regex to match. * @return The resulting quad stream. */ - match(subject?: Term | RegExp, predicate?: Term | RegExp, object?: Term | RegExp, graph?: Term | RegExp) - : Stream; + match(subject?: Term | RegExp, predicate?: Term | RegExp, object?: Term | RegExp, graph?: Term | RegExp): Stream; } /** @@ -330,7 +362,7 @@ export interface Source { * * For example parsers, serializers, transformations and stores can implement the Sink interface. */ -export interface Sink { +export interface Sink { /** * Consumes the given stream. * @@ -341,7 +373,7 @@ export interface Sink { * @param stream The stream that will be consumed. * @return The resulting event emitter. */ - import(stream: Stream): EventEmitter; + import(stream: Stream): EventEmitter; } /** @@ -352,7 +384,7 @@ export interface Sink { * * Access to stores LDP or SPARQL endpoints can be implemented with a Store inteface. */ -export interface Store extends Source, Sink { +export interface Store extends Source, Sink { /** * Removes all streamed quads. * @@ -362,7 +394,7 @@ export interface Store extends Source, Sink { * @param stream The stream that will be consumed. * @return The resulting event emitter. */ - remove(stream: Stream): EventEmitter; + remove(stream: Stream): EventEmitter; /** * All quads matching the pattern will be removed. @@ -388,5 +420,5 @@ export interface Store extends Source, Sink { * @param graph The graph term or string to match. * @return The resulting event emitter. */ - deleteGraph(graph: Term | string): EventEmitter; + deleteGraph(graph: Q['graph'] | string): EventEmitter; } diff --git a/types/rdf-js/rdf-js-tests.ts b/types/rdf-js/rdf-js-tests.ts index a29e70bfd4..eb55002149 100644 --- a/types/rdf-js/rdf-js-tests.ts +++ b/types/rdf-js/rdf-js-tests.ts @@ -1,5 +1,5 @@ -import { BlankNode, DataFactory, DefaultGraph, Literal, NamedNode, Quad, Sink, Source, Store, Stream, Triple, Term, - Variable } from "rdf-js"; +import { BlankNode, DataFactory, DefaultGraph, Literal, NamedNode, Quad, BaseQuad, Sink, Source, Store, Stream, Triple, Term, + Variable, Quad_Graph } from "rdf-js"; import { EventEmitter } from "events"; function test_terms() { @@ -71,7 +71,14 @@ function test_datafactory() { const term: NamedNode = {}; const triple: Quad = dataFactory.triple(term, term, term); - const quad: Quad = dataFactory.quad(term, term, term, term); + interface QuadBnode extends BaseQuad { + subject: Term; + predicate: Term; + object: Term; + graph: Term; + } + const quad = dataFactory.quad(literal1, blankNode1, term, term); + const hasBnode = quad.predicate.termType === "BlankNode"; } function test_stream() { @@ -91,6 +98,7 @@ function test_stream() { const matchStream9: Stream = source.match(term, term, term, /.*/); const sink: Sink = {}; + const graph: Quad_Graph = {}; const eventEmitter1: EventEmitter = sink.import(stream); const store: Store = {}; @@ -106,6 +114,6 @@ function test_stream() { const eventEmitter9: EventEmitter = store.removeMatches(term, term, /.*/); const eventEmitter10: EventEmitter = store.removeMatches(term, term, term, term); const eventEmitter11: EventEmitter = store.removeMatches(term, term, term, /.*/); - const eventEmitter12: EventEmitter = store.deleteGraph(term); + const eventEmitter12: EventEmitter = store.deleteGraph(graph); const eventEmitter13: EventEmitter = store.deleteGraph('http://example.org'); } diff --git a/types/rdf-js/tslint.json b/types/rdf-js/tslint.json index 3db14f85ea..e27ad90359 100644 --- a/types/rdf-js/tslint.json +++ b/types/rdf-js/tslint.json @@ -1 +1,6 @@ -{ "extends": "dtslint/dt.json" } +{ + "extends": "dtslint/dt.json", + "rules": { + "no-unnecessary-generics": false + } +}