refactor: Use declarations style for functions.

This commit is contained in:
Ruben Verborgh
2021-01-06 11:24:43 +01:00
parent e70e060225
commit f9a20799eb
23 changed files with 208 additions and 162 deletions

View File

@@ -24,7 +24,9 @@ export type Guarded<T extends NodeJS.EventEmitter = NodeJS.EventEmitter> = T & G
/**
* Determines whether the stream is guarded from emitting errors.
*/
export const isGuarded = <T extends NodeJS.EventEmitter>(stream: T): stream is Guarded<T> => guardedErrors in stream;
export function isGuarded<T extends NodeJS.EventEmitter>(stream: T): stream is Guarded<T> {
return guardedErrors in stream;
}
/**
* Makes sure that listeners always receive the error event of a stream,
@@ -34,20 +36,20 @@ export const isGuarded = <T extends NodeJS.EventEmitter>(stream: T): stream is G
*
* @returns The stream.
*/
export const guardStream = <T extends NodeJS.EventEmitter>(stream: T): Guarded<T> => {
export function guardStream<T extends NodeJS.EventEmitter>(stream: T): Guarded<T> {
const guarded = stream as Guarded<T>;
if (!isGuarded(stream)) {
guarded[guardedErrors] = [];
attachDefaultErrorListener.call(guarded, 'error');
}
return guarded;
};
}
/**
* Callback that is used when a stream emits an error and no error listener is attached.
* Used to store the error and start the logger timer.
*/
const defaultErrorListener = function(this: Guarded, error: Error): void {
function defaultErrorListener(this: Guarded, error: Error): void {
this[guardedErrors].push(error);
if (!this[guardedTimeout]) {
this[guardedTimeout] = setTimeout((): void => {
@@ -55,14 +57,13 @@ const defaultErrorListener = function(this: Guarded, error: Error): void {
logger.error(message, { error });
}, 1000);
}
};
}
/**
* Callback that is used when a new listener is attached to remove the current error-related fallback functions,
* or to emit an error if one was thrown in the meantime.
*/
const removeDefaultErrorListener = function(this: Guarded, event: string):
void {
function removeDefaultErrorListener(this: Guarded, event: string): void {
if (event === 'error') {
// Remove default guard listeners (but reattach when all error listeners are removed)
this.removeListener('error', defaultErrorListener);
@@ -86,7 +87,7 @@ void {
});
}
}
};
}
/**
* Callback that is used to make sure the error-related fallback functions are re-applied

View File

@@ -108,7 +108,7 @@ const token = /^[a-zA-Z0-9!#$%&'*+-.^_`|~]+$/u;
*
* @returns The transformed string and a map with keys `"0"`, etc. and values the original string that was there.
*/
export const transformQuotedStrings = (input: string): { result: string; replacements: Record<string, string> } => {
export function transformQuotedStrings(input: string): { result: string; replacements: Record<string, string> } {
let idx = 0;
const replacements: Record<string, string> = {};
const result = input.replace(/"(?:[^"\\]|\\.)*"/gu, (match): string => {
@@ -123,17 +123,18 @@ export const transformQuotedStrings = (input: string): { result: string; replace
return replacement;
});
return { result, replacements };
};
}
/**
* Splits the input string on commas, trims all parts and filters out empty ones.
*
* @param input - Input header string.
*/
export const splitAndClean = (input: string): string[] =>
input.split(',')
export function splitAndClean(input: string): string[] {
return input.split(',')
.map((part): string => part.trim())
.filter((part): boolean => part.length > 0);
}
/**
* Checks if the input string matches the qvalue regex.
@@ -143,14 +144,14 @@ export const splitAndClean = (input: string): string[] =>
* @throws {@link BadRequestHttpError}
* Thrown on invalid syntax.
*/
const testQValue = (qvalue: string): void => {
function testQValue(qvalue: string): void {
if (!/^(?:(?:0(?:\.\d{0,3})?)|(?:1(?:\.0{0,3})?))$/u.test(qvalue)) {
logger.warn(`Invalid q value: ${qvalue}`);
throw new BadRequestHttpError(
`Invalid q value: ${qvalue} does not match ( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] ).`,
);
}
};
}
/**
* Parses a list of split parameters and checks their validity.
@@ -164,28 +165,30 @@ const testQValue = (qvalue: string): void => {
*
* @returns An array of name/value objects corresponding to the parameters.
*/
export const parseParameters = (parameters: string[], replacements: Record<string, string>):
{ name: string; value: string }[] => parameters.map((param): { name: string; value: string } => {
const [ name, rawValue ] = param.split('=').map((str): string => str.trim());
export function parseParameters(parameters: string[], replacements: Record<string, string>):
{ name: string; value: string }[] {
return parameters.map((param): { name: string; value: string } => {
const [ name, rawValue ] = param.split('=').map((str): string => str.trim());
// Test replaced string for easier check
// parameter = token "=" ( token / quoted-string )
// second part is optional for certain parameters
if (!(token.test(name) && (!rawValue || /^"\d+"$/u.test(rawValue) || token.test(rawValue)))) {
logger.warn(`Invalid parameter value: ${name}=${replacements[rawValue] || rawValue}`);
throw new BadRequestHttpError(
`Invalid parameter value: ${name}=${replacements[rawValue] || rawValue} ` +
`does not match (token ( "=" ( token / quoted-string ))?). `,
);
}
// Test replaced string for easier check
// parameter = token "=" ( token / quoted-string )
// second part is optional for certain parameters
if (!(token.test(name) && (!rawValue || /^"\d+"$/u.test(rawValue) || token.test(rawValue)))) {
logger.warn(`Invalid parameter value: ${name}=${replacements[rawValue] || rawValue}`);
throw new BadRequestHttpError(
`Invalid parameter value: ${name}=${replacements[rawValue] || rawValue} ` +
`does not match (token ( "=" ( token / quoted-string ))?). `,
);
}
let value = rawValue;
if (value in replacements) {
value = replacements[rawValue];
}
let value = rawValue;
if (value in replacements) {
value = replacements[rawValue];
}
return { name, value };
});
return { name, value };
});
}
/**
* Parses a single media range with corresponding parameters from an Accept header.
@@ -201,7 +204,7 @@ export const parseParameters = (parameters: string[], replacements: Record<strin
*
* @returns {@link Accept} object corresponding to the header string.
*/
const parseAcceptPart = (part: string, replacements: Record<string, string>): Accept => {
function parseAcceptPart(part: string, replacements: Record<string, string>): Accept {
const [ range, ...parameters ] = part.split(';').map((param): string => param.trim());
// No reason to test differently for * since we don't check if the type exists
@@ -242,7 +245,7 @@ const parseAcceptPart = (part: string, replacements: Record<string, string>): Ac
extension: extensionParams,
},
};
};
}
/**
* Parses an Accept-* header where each part is only a value and a weight, so roughly /.*(q=.*)?/ separated by commas.
@@ -253,7 +256,7 @@ const parseAcceptPart = (part: string, replacements: Record<string, string>): Ac
*
* @returns An array of ranges and weights.
*/
const parseNoParameters = (input: string): AcceptHeader[] => {
function parseNoParameters(input: string): AcceptHeader[] {
const parts = splitAndClean(input);
return parts.map((part): AcceptHeader => {
@@ -270,7 +273,7 @@ const parseNoParameters = (input: string): AcceptHeader[] => {
}
return result;
}).sort((left, right): number => right.weight - left.weight);
};
}
// EXPORTED FUNCTIONS
@@ -284,13 +287,13 @@ const parseNoParameters = (input: string): AcceptHeader[] => {
*
* @returns An array of {@link Accept} objects, sorted by weight.
*/
export const parseAccept = (input: string): Accept[] => {
export function parseAccept(input: string): Accept[] {
// Quoted strings could prevent split from having correct results
const { result, replacements } = transformQuotedStrings(input);
return splitAndClean(result)
.map((part): Accept => parseAcceptPart(part, replacements))
.sort((left, right): number => right.weight - left.weight);
};
}
/**
* Parses an Accept-Charset header string.
@@ -302,7 +305,7 @@ export const parseAccept = (input: string): Accept[] => {
*
* @returns An array of {@link AcceptCharset} objects, sorted by weight.
*/
export const parseAcceptCharset = (input: string): AcceptCharset[] => {
export function parseAcceptCharset(input: string): AcceptCharset[] {
const results = parseNoParameters(input);
results.forEach((result): void => {
if (!token.test(result.range)) {
@@ -313,7 +316,7 @@ export const parseAcceptCharset = (input: string): AcceptCharset[] => {
}
});
return results;
};
}
/**
* Parses an Accept-Encoding header string.
@@ -325,7 +328,7 @@ export const parseAcceptCharset = (input: string): AcceptCharset[] => {
*
* @returns An array of {@link AcceptEncoding} objects, sorted by weight.
*/
export const parseAcceptEncoding = (input: string): AcceptEncoding[] => {
export function parseAcceptEncoding(input: string): AcceptEncoding[] {
const results = parseNoParameters(input);
results.forEach((result): void => {
if (!token.test(result.range)) {
@@ -334,7 +337,7 @@ export const parseAcceptEncoding = (input: string): AcceptEncoding[] => {
}
});
return results;
};
}
/**
* Parses an Accept-Language header string.
@@ -346,7 +349,7 @@ export const parseAcceptEncoding = (input: string): AcceptEncoding[] => {
*
* @returns An array of {@link AcceptLanguage} objects, sorted by weight.
*/
export const parseAcceptLanguage = (input: string): AcceptLanguage[] => {
export function parseAcceptLanguage(input: string): AcceptLanguage[] {
const results = parseNoParameters(input);
results.forEach((result): void => {
// (1*8ALPHA *("-" 1*8alphanum)) / "*"
@@ -360,7 +363,7 @@ export const parseAcceptLanguage = (input: string): AcceptLanguage[] => {
}
});
return results;
};
}
// eslint-disable-next-line max-len
const rfc1123Date = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/u;
@@ -372,7 +375,7 @@ const rfc1123Date = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|
*
* @returns An array with a single {@link AcceptDatetime} object.
*/
export const parseAcceptDateTime = (input: string): AcceptDatetime[] => {
export function parseAcceptDateTime(input: string): AcceptDatetime[] {
const results: AcceptDatetime[] = [];
const range = input.trim();
if (range) {
@@ -387,12 +390,12 @@ export const parseAcceptDateTime = (input: string): AcceptDatetime[] => {
results.push({ range, weight: 1 });
}
return results;
};
}
/**
* Adds a header value without overriding previous values.
*/
export const addHeader = (response: HttpResponse, name: string, value: string | string[]): void => {
export function addHeader(response: HttpResponse, name: string, value: string | string[]): void {
let allValues: string[] = [];
if (response.hasHeader(name)) {
let oldValues = response.getHeader(name)!;
@@ -409,7 +412,7 @@ export const addHeader = (response: HttpResponse, name: string, value: string |
allValues.push(value);
}
response.setHeader(name, allValues.length === 1 ? allValues[0] : allValues);
};
}
/**
* The Forwarded header from RFC7239
@@ -432,7 +435,7 @@ export interface Forwarded {
*
* @returns The parsed Forwarded header.
*/
export const parseForwarded = (value = ''): Forwarded => {
export function parseForwarded(value = ''): Forwarded {
const forwarded: Record<string, string> = {};
if (value) {
for (const pair of value.replace(/\s*,.*$/u, '').split(';')) {
@@ -443,4 +446,4 @@ export const parseForwarded = (value = ''): Forwarded => {
}
}
return forwarded;
};
}

View File

@@ -8,7 +8,9 @@ import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifie
*
* @returns The potentially changed path (POSIX).
*/
const windowsToPosixPath = (path: string): string => path.replace(/\\+/gu, '/');
function windowsToPosixPath(path: string): string {
return path.replace(/\\+/gu, '/');
}
/**
* Resolves relative segments in the path/
@@ -17,8 +19,9 @@ const windowsToPosixPath = (path: string): string => path.replace(/\\+/gu, '/');
*
* @returns The potentially changed path (POSIX).
*/
export const normalizeFilePath = (path: string): string =>
posix.normalize(windowsToPosixPath(path));
export function normalizeFilePath(path: string): string {
return posix.normalize(windowsToPosixPath(path));
}
/**
* Adds the paths to the base path.
@@ -28,8 +31,9 @@ export const normalizeFilePath = (path: string): string =>
*
* @returns The potentially changed path (POSIX).
*/
export const joinFilePath = (basePath: string, ...paths: string[]): string =>
posix.join(windowsToPosixPath(basePath), ...paths);
export function joinFilePath(basePath: string, ...paths: string[]): string {
return posix.join(windowsToPosixPath(basePath), ...paths);
}
/**
* Converts the path into an OS-dependent path.
@@ -38,8 +42,9 @@ export const joinFilePath = (basePath: string, ...paths: string[]): string =>
*
* @returns The potentially changed path (OS-dependent).
*/
export const toSystemFilePath = (path: string): string =>
platform.normalize(path);
export function toSystemFilePath(path: string): string {
return platform.normalize(path);
}
/**
* Makes sure the input path has exactly 1 slash at the end.
@@ -50,7 +55,9 @@ export const toSystemFilePath = (path: string): string =>
*
* @returns The potentially changed path.
*/
export const ensureTrailingSlash = (path: string): string => path.replace(/\/*$/u, '/');
export function ensureTrailingSlash(path: string): string {
return path.replace(/\/*$/u, '/');
}
/**
* Makes sure the input path has no slashes at the end.
@@ -59,34 +66,46 @@ export const ensureTrailingSlash = (path: string): string => path.replace(/\/*$/
*
* @returns The potentially changed path.
*/
export const trimTrailingSlashes = (path: string): string => path.replace(/\/+$/u, '');
export function trimTrailingSlashes(path: string): string {
return path.replace(/\/+$/u, '');
}
/**
* Converts a URI path to the canonical version by splitting on slashes,
* decoding any percent-based encodings,
* and then encoding any special characters.
*/
export const toCanonicalUriPath = (path: string): string => path.split('/').map((part): string =>
encodeURIComponent(decodeURIComponent(part))).join('/');
export function toCanonicalUriPath(path: string): string {
return path.split('/').map((part): string =>
encodeURIComponent(decodeURIComponent(part))).join('/');
}
/**
* Decodes all components of a URI path.
*/
export const decodeUriPathComponents = (path: string): string => path.split('/').map(decodeURIComponent).join('/');
export function decodeUriPathComponents(path: string): string {
return path.split('/').map(decodeURIComponent).join('/');
}
/**
* Encodes all (non-slash) special characters in a URI path.
*/
export const encodeUriPathComponents = (path: string): string => path.split('/').map(encodeURIComponent).join('/');
export function encodeUriPathComponents(path: string): string {
return path.split('/').map(encodeURIComponent).join('/');
}
/**
* Checks if the path corresponds to a container path (ending in a /).
* @param path - Path to check.
*/
export const isContainerPath = (path: string): boolean => path.endsWith('/');
export function isContainerPath(path: string): boolean {
return path.endsWith('/');
}
/**
* Checks if the identifier corresponds to a container identifier.
* @param identifier - Identifier to check.
*/
export const isContainerIdentifier = (identifier: ResourceIdentifier): boolean => isContainerPath(identifier.path);
export function isContainerIdentifier(identifier: ResourceIdentifier): boolean {
return isContainerPath(identifier.path);
}

View File

@@ -10,14 +10,14 @@ import { toSubjectTerm, toPredicateTerm, toObjectTerm } from './TermUtil';
/**
* Generates a quad with the given subject/predicate/object and pushes it to the given array.
*/
export const pushQuad = (
export function pushQuad(
quads: Quad[] | PassThrough,
subject: string | NamedNode,
predicate: string | NamedNode,
object: string | NamedNode | Literal,
): void => {
): void {
quads.push(DataFactory.quad(toSubjectTerm(subject), toPredicateTerm(predicate), toObjectTerm(object)));
};
}
/**
* Helper function for serializing an array of quads, with as result a Readable object.
@@ -26,8 +26,9 @@ export const pushQuad = (
*
* @returns The Readable object.
*/
export const serializeQuads = (quads: Quad[], contentType?: string): Guarded<Readable> =>
pipeSafely(streamifyArray(quads), new StreamWriter({ format: contentType }));
export function serializeQuads(quads: Quad[], contentType?: string): Guarded<Readable> {
return pipeSafely(streamifyArray(quads), new StreamWriter({ format: contentType }));
}
/**
* Helper function to convert a Readable into an array of quads.
@@ -36,5 +37,6 @@ export const serializeQuads = (quads: Quad[], contentType?: string): Guarded<Rea
*
* @returns A promise containing the array of quads.
*/
export const parseQuads = async(readable: Guarded<Readable>, contentType?: string): Promise<Quad[]> =>
arrayifyStream(pipeSafely(readable, new StreamParser({ format: contentType })));
export async function parseQuads(readable: Guarded<Readable>, contentType?: string): Promise<Quad[]> {
return arrayifyStream(pipeSafely(readable, new StreamParser({ format: contentType })));
}

View File

@@ -11,7 +11,7 @@ import { LDP, RDF } from './Vocabularies';
*
* @returns The generated quads.
*/
export const generateResourceQuads = (subject: NamedNode, isContainer: boolean): Quad[] => {
export function generateResourceQuads(subject: NamedNode, isContainer: boolean): Quad[] {
const quads: Quad[] = [];
if (isContainer) {
pushQuad(quads, subject, RDF.terms.type, LDP.terms.Container);
@@ -20,7 +20,7 @@ export const generateResourceQuads = (subject: NamedNode, isContainer: boolean):
pushQuad(quads, subject, RDF.terms.type, LDP.terms.Resource);
return quads;
};
}
/**
* Helper function to generate the quads describing that the resource URIs are children of the container URI.
@@ -29,5 +29,7 @@ export const generateResourceQuads = (subject: NamedNode, isContainer: boolean):
*
* @returns The generated quads.
*/
export const generateContainmentQuads = (containerURI: NamedNode, childURIs: string[]): Quad[] =>
new RepresentationMetadata(containerURI, { [LDP.contains]: childURIs.map(DataFactory.namedNode) }).quads();
export function generateContainmentQuads(containerURI: NamedNode, childURIs: string[]): Quad[] {
return new RepresentationMetadata(containerURI,
{ [LDP.contains]: childURIs.map(DataFactory.namedNode) }).quads();
}

View File

@@ -13,7 +13,9 @@ const logger = getLoggerFor('StreamUtil');
*
* @returns The joined string.
*/
export const readableToString = async(stream: Readable): Promise<string> => (await arrayifyStream(stream)).join('');
export async function readableToString(stream: Readable): Promise<string> {
return (await arrayifyStream(stream)).join('');
}
/**
* Pipes one stream into another and emits errors of the first stream with the second.
@@ -25,8 +27,8 @@ export const readableToString = async(stream: Readable): Promise<string> => (awa
*
* @returns The destination stream.
*/
export const pipeSafely = <T extends Writable>(readable: NodeJS.ReadableStream, destination: T,
mapError?: (error: Error) => Error): Guarded<T> => {
export function pipeSafely<T extends Writable>(readable: NodeJS.ReadableStream, destination: T,
mapError?: (error: Error) => Error): Guarded<T> {
// Not using `stream.pipeline` since the result there only emits an error event if the last stream has the error
readable.pipe(destination);
readable.on('error', (error): void => {
@@ -39,12 +41,13 @@ export const pipeSafely = <T extends Writable>(readable: NodeJS.ReadableStream,
destination.destroy(mapError ? mapError(error) : error);
});
return guardStream(destination);
};
}
/**
* Converts an iterable to a stream and applies an error guard so that it is {@link Guarded}.
* @param iterable - Data to stream.
* @param options - Options to pass to the Readable constructor. See {@link Readable.from}.
*/
export const guardedStreamFrom = (iterable: Iterable<any>, options?: ReadableOptions): Guarded<Readable> =>
guardStream(Readable.from(iterable, options));
export function guardedStreamFrom(iterable: Iterable<any>, options?: ReadableOptions): Guarded<Readable> {
return guardStream(Readable.from(iterable, options));
}

View File

@@ -20,7 +20,7 @@ const cachedNamedNodes: Record<string, NamedNode> = {
* so only use this for internal constants!
* @param name - Predicate to potentially transform.
*/
export const toCachedNamedNode = (name: NamedNode | string): NamedNode => {
export function toCachedNamedNode(name: NamedNode | string): NamedNode {
if (typeof name !== 'string') {
return name;
}
@@ -28,20 +28,22 @@ export const toCachedNamedNode = (name: NamedNode | string): NamedNode => {
cachedNamedNodes[name] = namedNode(name);
}
return cachedNamedNodes[name];
};
}
/**
* @param input - Checks if this is a {@link Term}.
*/
export const isTerm = (input?: any): input is Term =>
input && typeof input.termType === 'string';
export function isTerm(input?: any): input is Term {
return input && typeof input.termType === 'string';
}
/**
* Converts a subject to a named node when needed.
* @param subject - Subject to potentially transform.
*/
export const toSubjectTerm = (subject: NamedNode | string): NamedNode =>
typeof subject === 'string' ? namedNode(subject) : subject;
export function toSubjectTerm(subject: NamedNode | string): NamedNode {
return typeof subject === 'string' ? namedNode(subject) : subject;
}
export const toPredicateTerm = toSubjectTerm;
@@ -50,17 +52,18 @@ export const toPredicateTerm = toSubjectTerm;
* @param object - Object to potentially transform.
* @param preferLiteral - Whether strings are converted to literals or named nodes.
*/
export const toObjectTerm = <T extends Term>(object: T | string, preferLiteral = false): T => {
export function toObjectTerm<T extends Term>(object: T | string, preferLiteral = false): T {
if (typeof object === 'string') {
return (preferLiteral ? literal(object) : namedNode(object)) as any;
}
return object;
};
}
/**
* Creates a literal by first converting the dataType string to a named node.
* @param object - Object value.
* @param dataType - Object data type (as string).
*/
export const toLiteral = (object: string | number, dataType: NamedNode): Literal =>
literal(object, dataType);
export function toLiteral(object: string | number, dataType: NamedNode): Literal {
return literal(`${object}`, dataType);
}

View File

@@ -12,11 +12,11 @@ export type Namespace<TKey extends any[], TValue> =
* Creates a function that expands local names from the given base URI,
* and exports the given local names as properties on the returned object.
*/
export const createNamespace = <TKey extends string, TValue>(
export function createNamespace<TKey extends string, TValue>(
baseUri: string,
toValue: (expanded: string) => TValue,
...localNames: TKey[]):
Namespace<typeof localNames, TValue> => {
Namespace<typeof localNames, TValue> {
// Create a function that expands local names
const expanded = {} as Record<string, TValue>;
const namespace = ((localName: string): TValue => {
@@ -31,33 +31,36 @@ Namespace<typeof localNames, TValue> => {
(namespace as RecordOf<typeof localNames, TValue>)[localName] = namespace(localName);
}
return namespace;
};
}
/**
* Creates a function that expands local names from the given base URI into strings,
* and exports the given local names as properties on the returned object.
*/
export const createUriNamespace = <T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, string> =>
createNamespace(baseUri, (expanded): string => expanded, ...localNames);
export function createUriNamespace<T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, string> {
return createNamespace(baseUri, (expanded): string => expanded, ...localNames);
}
/**
* Creates a function that expands local names from the given base URI into named nodes,
* and exports the given local names as properties on the returned object.
*/
export const createTermNamespace = <T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, NamedNode> =>
createNamespace(baseUri, namedNode, ...localNames);
export function createTermNamespace<T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, NamedNode> {
return createNamespace(baseUri, namedNode, ...localNames);
}
/**
* Creates a function that expands local names from the given base URI into string,
* and exports the given local names as properties on the returned object.
* Under the `terms` property, it exposes the expanded local names as named nodes.
*/
export const createUriAndTermNamespace = <T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, string> & { terms: Namespace<typeof localNames, NamedNode> } =>
Object.assign(createUriNamespace(baseUri, ...localNames),
export function createUriAndTermNamespace<T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, string> & { terms: Namespace<typeof localNames, NamedNode> } {
return Object.assign(createUriNamespace(baseUri, ...localNames),
{ terms: createTermNamespace(baseUri, ...localNames) });
}
export const ACL = createUriAndTermNamespace('http://www.w3.org/ns/auth/acl#',
'accessTo',

View File

@@ -41,4 +41,6 @@ export interface SystemError extends Error {
syscall: string;
}
export const isSystemError = (error: any): error is SystemError => error.code && error.syscall;
export function isSystemError(error: any): error is SystemError {
return error.code && error.syscall;
}