mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Use declarations style for functions.
This commit is contained in:
parent
e70e060225
commit
f9a20799eb
@ -48,6 +48,8 @@ module.exports = {
|
||||
'class-methods-use-this': 'off',
|
||||
'comma-dangle': [ 'error', 'always-multiline' ],
|
||||
'dot-location': [ 'error', 'property' ],
|
||||
// Allow declaring overloads in TypeScript (https://eslint.org/docs/rules/func-style)
|
||||
'func-style': [ 'error', 'declaration' ],
|
||||
'generator-star-spacing': [ 'error', 'after' ],
|
||||
// Conflicts with padded-blocks
|
||||
'lines-around-comment': 'off',
|
||||
|
@ -12,9 +12,9 @@ export type MetadataOverrideValue = NamedNode | Literal | string | (NamedNode |
|
||||
/**
|
||||
* Determines whether the object is a `RepresentationMetadata`.
|
||||
*/
|
||||
export const isRepresentationMetadata = function(object: any): object is RepresentationMetadata {
|
||||
export function isRepresentationMetadata(object: any): object is RepresentationMetadata {
|
||||
return typeof object?.setMetadata === 'function';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the metadata triples and provides methods for easy access.
|
||||
|
@ -11,6 +11,6 @@ export interface ResourceIdentifier {
|
||||
/**
|
||||
* Determines whether the object is a `ResourceIdentifier`.
|
||||
*/
|
||||
export const isResourceIdentifier = function(object: any): object is ResourceIdentifier {
|
||||
export function isResourceIdentifier(object: any): object is ResourceIdentifier {
|
||||
return object && (typeof object.path === 'string');
|
||||
};
|
||||
}
|
||||
|
@ -20,17 +20,19 @@ import type { LoggerFactory } from './LoggerFactory';
|
||||
*
|
||||
* @param loggable - A class instance or a class string name.
|
||||
*/
|
||||
export const getLoggerFor = (loggable: string | Instance): Logger => LazyLoggerFactory.getInstance()
|
||||
.createLogger(typeof loggable === 'string' ? loggable : loggable.constructor.name);
|
||||
export function getLoggerFor(loggable: string | Instance): Logger {
|
||||
return LazyLoggerFactory.getInstance()
|
||||
.createLogger(typeof loggable === 'string' ? loggable : loggable.constructor.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the global logger factory.
|
||||
* This will cause all loggers created by {@link getLoggerFor} to be delegated to a logger from the given factory.
|
||||
* @param loggerFactory - A logger factory.
|
||||
*/
|
||||
export const setGlobalLoggerFactory = (loggerFactory: LoggerFactory): void => {
|
||||
export function setGlobalLoggerFactory(loggerFactory: LoggerFactory): void {
|
||||
LazyLoggerFactory.getInstance().loggerFactory = loggerFactory;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the global logger factory to undefined.
|
||||
@ -38,7 +40,9 @@ export const setGlobalLoggerFactory = (loggerFactory: LoggerFactory): void => {
|
||||
* This typically only needs to be called during testing.
|
||||
* Call this at your own risk.
|
||||
*/
|
||||
export const resetGlobalLoggerFactory = (): void => LazyLoggerFactory.getInstance().resetLoggerFactory();
|
||||
export function resetGlobalLoggerFactory(): void {
|
||||
LazyLoggerFactory.getInstance().resetLoggerFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper interface to identify class instances.
|
||||
|
@ -18,8 +18,8 @@ import { NotImplementedHttpError } from '../../util/errors/NotImplementedHttpErr
|
||||
*
|
||||
* @returns The weighted and filtered list of matching types.
|
||||
*/
|
||||
export const matchingMediaTypes = (preferredTypes: ValuePreferences = {}, availableTypes: ValuePreferences = {}):
|
||||
string[] => {
|
||||
export function matchingMediaTypes(preferredTypes: ValuePreferences = {}, availableTypes: ValuePreferences = {}):
|
||||
string[] {
|
||||
// No preference means anything is acceptable
|
||||
const preferred = { ...preferredTypes };
|
||||
if (Object.keys(preferredTypes).length === 0) {
|
||||
@ -53,7 +53,7 @@ string[] => {
|
||||
.filter(([ , weight ]): boolean => weight !== 0)
|
||||
.sort(([ , weightA ], [ , weightB ]): number => weightB - weightA)
|
||||
.map(([ type ]): string => type);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given two media types/ranges match each other.
|
||||
@ -63,7 +63,7 @@ string[] => {
|
||||
*
|
||||
* @returns True if the media type patterns can match each other.
|
||||
*/
|
||||
export const matchesMediaType = (mediaA: string, mediaB: string): boolean => {
|
||||
export function matchesMediaType(mediaA: string, mediaB: string): boolean {
|
||||
if (mediaA === mediaB) {
|
||||
return true;
|
||||
}
|
||||
@ -80,7 +80,7 @@ export const matchesMediaType = (mediaA: string, mediaB: string): boolean => {
|
||||
return true;
|
||||
}
|
||||
return subTypeA === subTypeB;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given conversion request is supported,
|
||||
@ -94,10 +94,10 @@ export const matchesMediaType = (mediaA: string, mediaB: string): boolean => {
|
||||
* @param convertorIn - Media types that can be parsed by the converter.
|
||||
* @param convertorOut - Media types that can be produced by the converter.
|
||||
*/
|
||||
export const supportsMediaTypeConversion = (
|
||||
export function supportsMediaTypeConversion(
|
||||
inputType = 'unknown', outputTypes: ValuePreferences = {},
|
||||
convertorIn: ValuePreferences = {}, convertorOut: ValuePreferences = {},
|
||||
): void => {
|
||||
): void {
|
||||
if (!Object.keys(convertorIn).some((type): boolean => matchesMediaType(inputType, type)) ||
|
||||
matchingMediaTypes(outputTypes, convertorOut).length === 0) {
|
||||
throw new NotImplementedHttpError(
|
||||
@ -105,4 +105,4 @@ export const supportsMediaTypeConversion = (
|
||||
}, only from ${Object.keys(convertorIn)} to ${Object.keys(convertorOut)}.`,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -14,8 +14,9 @@ const logger = getLoggerFor('MapperUtil');
|
||||
*
|
||||
* @returns Absolute path of the file.
|
||||
*/
|
||||
export const getAbsolutePath = (rootFilepath: string, path: string, identifier = ''): string =>
|
||||
joinFilePath(rootFilepath, path, identifier);
|
||||
export function getAbsolutePath(rootFilepath: string, path: string, identifier = ''): string {
|
||||
return joinFilePath(rootFilepath, path, identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the baseRequestURI from the identifier and checks if the stripped base URI matches the store's one.
|
||||
@ -27,13 +28,13 @@ export const getAbsolutePath = (rootFilepath: string, path: string, identifier =
|
||||
*
|
||||
* @returns A string representing the relative path.
|
||||
*/
|
||||
export const getRelativePath = (baseRequestURI: string, identifier: ResourceIdentifier): string => {
|
||||
export function getRelativePath(baseRequestURI: string, identifier: ResourceIdentifier): string {
|
||||
if (!identifier.path.startsWith(baseRequestURI)) {
|
||||
logger.warn(`The URL ${identifier.path} is outside of the scope ${baseRequestURI}`);
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
return decodeUriPathComponents(identifier.path.slice(baseRequestURI.length));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given relative path is valid.
|
||||
@ -44,7 +45,7 @@ export const getRelativePath = (baseRequestURI: string, identifier: ResourceIden
|
||||
* @param path - A relative path, as generated by {@link getRelativePath}.
|
||||
* @param identifier - A resource identifier.
|
||||
*/
|
||||
export const validateRelativePath = (path: string, identifier: ResourceIdentifier): void => {
|
||||
export function validateRelativePath(path: string, identifier: ResourceIdentifier): void {
|
||||
if (!path.startsWith('/')) {
|
||||
logger.warn(`URL ${identifier.path} needs a / after the base`);
|
||||
throw new BadRequestHttpError('URL needs a / after the base');
|
||||
@ -54,4 +55,4 @@ export const validateRelativePath = (path: string, identifier: ResourceIdentifie
|
||||
logger.warn(`Disallowed /.. segment in URL ${identifier.path}.`);
|
||||
throw new BadRequestHttpError('Disallowed /.. segment in URL');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 })));
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ export const BASE = 'http://test.com';
|
||||
/**
|
||||
* Returns a component instantiated from a Components.js configuration.
|
||||
*/
|
||||
export const instantiateFromConfig = async(componentUrl: string, configFile: string,
|
||||
variables?: Record<string, any>): Promise<any> => {
|
||||
export async function instantiateFromConfig(componentUrl: string, configFile: string,
|
||||
variables?: Record<string, any>): Promise<any> {
|
||||
// Initialize the Components.js loader
|
||||
const mainModulePath = joinFilePath(__dirname, '../../');
|
||||
const loader = new Loader({ mainModulePath });
|
||||
@ -18,15 +18,16 @@ export const instantiateFromConfig = async(componentUrl: string, configFile: str
|
||||
// Instantiate the component from the config
|
||||
const configPath = toSystemFilePath(joinFilePath(__dirname, 'config', configFile));
|
||||
return loader.instantiateFromUrl(componentUrl, configPath, undefined, { variables });
|
||||
};
|
||||
}
|
||||
|
||||
export const getTestFolder = (name: string): string =>
|
||||
joinFilePath(__dirname, '../tmp', name);
|
||||
export function getTestFolder(name: string): string {
|
||||
return joinFilePath(__dirname, '../tmp', name);
|
||||
}
|
||||
|
||||
export const createFolder = (folder: string): void => {
|
||||
export function createFolder(folder: string): void {
|
||||
mkdirSync(folder, { recursive: true });
|
||||
};
|
||||
}
|
||||
|
||||
export const removeFolder = (folder: string): void => {
|
||||
export function removeFolder(folder: string): void {
|
||||
rimraf.sync(folder, { glob: false });
|
||||
};
|
||||
}
|
||||
|
@ -29,13 +29,13 @@ class DummyFactory implements FileIdentifierMapperFactory {
|
||||
}
|
||||
}
|
||||
|
||||
const genToArray = async<T>(iterable: AsyncIterable<T>): Promise<T[]> => {
|
||||
async function genToArray<T>(iterable: AsyncIterable<T>): Promise<T[]> {
|
||||
const arr: T[] = [];
|
||||
for await (const result of iterable) {
|
||||
arr.push(result);
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
}
|
||||
|
||||
describe('A TemplatedResourcesGenerator', (): void => {
|
||||
const rootFilePath = 'templates';
|
||||
|
@ -21,13 +21,13 @@ describe('A LockingResourceStore', (): void => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
order = [];
|
||||
const delayedResolve = (resolve: (resolveParams: any) => void, name: string, resolveParams?: any): void => {
|
||||
function delayedResolve(resolve: (value: any) => void, name: string, resolveValue?: any): void {
|
||||
// `setImmediate` is introduced to make sure the promise doesn't execute immediately
|
||||
setImmediate((): void => {
|
||||
order.push(name);
|
||||
resolve(resolveParams);
|
||||
resolve(resolveValue);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
const readable = streamifyArray([ 1, 2, 3 ]);
|
||||
source = {
|
||||
@ -70,14 +70,14 @@ describe('A LockingResourceStore', (): void => {
|
||||
store = new LockingResourceStore(source, locker);
|
||||
});
|
||||
|
||||
const registerEventOrder = async(eventSource: EventEmitter, event: string): Promise<void> => {
|
||||
async function registerEventOrder(eventSource: EventEmitter, event: string): Promise<void> {
|
||||
await new Promise((resolve): any => {
|
||||
eventSource.prependListener(event, (): any => {
|
||||
order.push(event);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
it('acquires a lock on the container when adding a representation.', async(): Promise<void> => {
|
||||
await store.addResource({ path: 'path' }, {} as Representation);
|
||||
|
@ -20,12 +20,12 @@ const { literal, namedNode, quad } = DataFactory;
|
||||
|
||||
jest.mock('fetch-sparql-endpoint');
|
||||
|
||||
const simplifyQuery = (query: string | string[]): string => {
|
||||
function simplifyQuery(query: string | string[]): string {
|
||||
if (Array.isArray(query)) {
|
||||
query = query.join(' ');
|
||||
}
|
||||
return query.replace(/\n/gu, ' ').trim();
|
||||
};
|
||||
}
|
||||
|
||||
describe('A SparqlDataAccessor', (): void => {
|
||||
const endpoint = 'http://test.com/sparql';
|
||||
|
@ -65,7 +65,7 @@ describe('A SparqlUpdatePatchHandler', (): void => {
|
||||
handler = new SparqlUpdatePatchHandler(source, locker);
|
||||
});
|
||||
|
||||
const basicChecks = async(quads: Quad[]): Promise<boolean> => {
|
||||
async function basicChecks(quads: Quad[]): Promise<boolean> {
|
||||
expect(source.getRepresentation).toHaveBeenCalledTimes(1);
|
||||
expect(source.getRepresentation).toHaveBeenLastCalledWith(
|
||||
{ path: 'path' }, { type: { [INTERNAL_QUADS]: 1 }},
|
||||
@ -81,7 +81,7 @@ describe('A SparqlUpdatePatchHandler', (): void => {
|
||||
expect(setParams[1].metadata.contentType).toEqual(INTERNAL_QUADS);
|
||||
await expect(arrayifyStream(setParams[1].data)).resolves.toBeRdfIsomorphic(quads);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
it('only accepts SPARQL updates.', async(): Promise<void> => {
|
||||
const input = { identifier: { path: 'path' },
|
||||
|
@ -9,14 +9,14 @@ describe('A WrappedExpiringResourceLocker', (): void => {
|
||||
order = [];
|
||||
});
|
||||
|
||||
const registerEventOrder = async(eventSource: EventEmitter, event: string): Promise<void> => {
|
||||
async function registerEventOrder(eventSource: EventEmitter, event: string): Promise<void> {
|
||||
await new Promise((resolve): any => {
|
||||
eventSource.prependListener(event, (): any => {
|
||||
order.push(event);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
it('emits an error event when releasing the lock errors.', async(): Promise<void> => {
|
||||
jest.useFakeTimers();
|
||||
|
@ -199,9 +199,9 @@ export class ResourceHelper {
|
||||
}
|
||||
}
|
||||
|
||||
export const describeIf = (envFlag: string, name: string, fn: () => void): void => {
|
||||
export function describeIf(envFlag: string, name: string, fn: () => void): void {
|
||||
const flag = `TEST_${envFlag.toUpperCase()}`;
|
||||
const enabled = !/^(|0|false)$/iu.test(process.env[flag] ?? '');
|
||||
// eslint-disable-next-line jest/valid-describe, jest/valid-title, jest/no-disabled-tests
|
||||
return enabled ? describe(name, fn) : describe.skip(name, fn);
|
||||
};
|
||||
}
|
||||
|
@ -9,13 +9,13 @@ import type { HttpHandler } from '../../src/server/HttpHandler';
|
||||
import type { HttpRequest } from '../../src/server/HttpRequest';
|
||||
import type { SystemError } from '../../src/util/errors/SystemError';
|
||||
|
||||
export const performRequest = async(
|
||||
export async function performRequest(
|
||||
handler: HttpHandler,
|
||||
requestUrl: URL,
|
||||
method: string,
|
||||
headers: IncomingHttpHeaders,
|
||||
data: string[],
|
||||
): Promise<MockResponse<any>> => {
|
||||
): Promise<MockResponse<any>> {
|
||||
const request = streamifyArray(data) as HttpRequest;
|
||||
request.url = requestUrl.pathname;
|
||||
request.method = method;
|
||||
@ -36,7 +36,7 @@ export const performRequest = async(
|
||||
await endPromise;
|
||||
|
||||
return response;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Mocks (some) functions of the fs system library.
|
||||
@ -56,21 +56,21 @@ export const performRequest = async(
|
||||
* @param rootFilepath - The name of the root folder in which fs will start.
|
||||
* @param time - The date object to use for time functions (currently only mtime from lstats)
|
||||
*/
|
||||
export const mockFs = (rootFilepath?: string, time?: Date): { data: any } => {
|
||||
export function mockFs(rootFilepath?: string, time?: Date): { data: any } {
|
||||
const cache: { data: any } = { data: {}};
|
||||
|
||||
rootFilepath = rootFilepath ?? 'folder';
|
||||
time = time ?? new Date();
|
||||
|
||||
// eslint-disable-next-line unicorn/consistent-function-scoping
|
||||
const throwSystemError = (code: string): void => {
|
||||
function throwSystemError(code: string): void {
|
||||
const error = new Error('error') as SystemError;
|
||||
error.code = code;
|
||||
error.syscall = 'this exists for isSystemError';
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
|
||||
const getFolder = (path: string): { folder: any; name: string } => {
|
||||
function getFolder(path: string): { folder: any; name: string } {
|
||||
let parts = path.slice(rootFilepath!.length).split('/').filter((part): boolean => part.length > 0);
|
||||
|
||||
if (parts.length === 0) {
|
||||
@ -91,7 +91,7 @@ export const mockFs = (rootFilepath?: string, time?: Date): { data: any } => {
|
||||
});
|
||||
|
||||
return { folder, name };
|
||||
};
|
||||
}
|
||||
|
||||
const mock = {
|
||||
createReadStream(path: string): any {
|
||||
@ -171,4 +171,4 @@ export const mockFs = (rootFilepath?: string, time?: Date): { data: any } => {
|
||||
Object.assign(fs, mock);
|
||||
|
||||
return cache;
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user