mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
chore: Update lint dependencies
This commit is contained in:
parent
d1282f6b1a
commit
ecd031e69f
@ -39,9 +39,16 @@
|
|||||||
},
|
},
|
||||||
"enabledJWA": {
|
"enabledJWA": {
|
||||||
"dPoPSigningAlgValues": [
|
"dPoPSigningAlgValues": [
|
||||||
"RS256", "RS384", "RS512",
|
"RS256",
|
||||||
"PS256", "PS384", "PS512",
|
"RS384",
|
||||||
"ES256", "ES256K", "ES384", "ES512",
|
"RS512",
|
||||||
|
"PS256",
|
||||||
|
"PS384",
|
||||||
|
"PS512",
|
||||||
|
"ES256",
|
||||||
|
"ES256K",
|
||||||
|
"ES384",
|
||||||
|
"ES512",
|
||||||
"EdDSA"
|
"EdDSA"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@ antfu.GLOB_EXCLUDE.splice(index, 1);
|
|||||||
module.exports = antfu.default(
|
module.exports = antfu.default(
|
||||||
{
|
{
|
||||||
// Don't want to lint test assets, or TS snippets in markdown files
|
// Don't want to lint test assets, or TS snippets in markdown files
|
||||||
ignores: [ 'test/assets/*', '**/*.md/**/*.ts' ],
|
ignores: [ 'test/assets/*', '**/*.md' ],
|
||||||
typescript: {
|
typescript: {
|
||||||
tsconfigPath: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ],
|
tsconfigPath: [ './tsconfig.json', './scripts/tsconfig.json', './test/tsconfig.json' ],
|
||||||
},
|
},
|
||||||
@ -26,12 +26,12 @@ module.exports = antfu.default(
|
|||||||
.append(unicornConfig)
|
.append(unicornConfig)
|
||||||
.append(fileNamesConfig)
|
.append(fileNamesConfig)
|
||||||
// Using an override here so all the type settings are also applied correctly
|
// Using an override here so all the type settings are also applied correctly
|
||||||
.override('antfu:typescript:rules-type-aware', typedConfig)
|
.override('antfu/typescript/rules-type-aware', typedConfig)
|
||||||
.append({
|
.append({
|
||||||
...testConfig,
|
...testConfig,
|
||||||
files: [ 'test/**/*.ts' ],
|
files: [ 'test/**/*.ts' ],
|
||||||
})
|
})
|
||||||
.override('antfu:jsonc:rules', {
|
.override('antfu/jsonc/rules', {
|
||||||
rules: {
|
rules: {
|
||||||
// Consistent with how we do it in code
|
// Consistent with how we do it in code
|
||||||
'jsonc/array-bracket-spacing': [ 'error', 'always', {
|
'jsonc/array-bracket-spacing': [ 'error', 'always', {
|
||||||
@ -48,7 +48,7 @@ module.exports = antfu.default(
|
|||||||
'unicorn/filename-case': 'off',
|
'unicorn/filename-case': 'off',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.override('antfu:markdown:parser', {
|
.override('antfu/markdown/parser', {
|
||||||
rules: {
|
rules: {
|
||||||
// We want to be able to use these in Markdown text
|
// We want to be able to use these in Markdown text
|
||||||
'no-irregular-whitespace': 'off',
|
'no-irregular-whitespace': 'off',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
module.exports = [
|
module.exports = [
|
||||||
{
|
{
|
||||||
name: 'opinionated:file-names:all',
|
name: 'opinionated/file-names/all',
|
||||||
rules: {
|
rules: {
|
||||||
'unicorn/filename-case': [ 'error', {
|
'unicorn/filename-case': [ 'error', {
|
||||||
cases: {
|
cases: {
|
||||||
@ -17,7 +17,7 @@ module.exports = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'opinionated:file-names:ts',
|
name: 'opinionated/file-names/ts',
|
||||||
files: [ '**/*.ts' ],
|
files: [ '**/*.ts' ],
|
||||||
rules: {
|
rules: {
|
||||||
'unicorn/filename-case': [ 'error', {
|
'unicorn/filename-case': [ 'error', {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'opinionated:general',
|
name: 'opinionated/general',
|
||||||
rules: {
|
rules: {
|
||||||
'antfu/consistent-list-newline': 'error',
|
'antfu/consistent-list-newline': 'error',
|
||||||
|
|
||||||
@ -126,6 +126,8 @@ module.exports = {
|
|||||||
'ts/prefer-for-of': 'error',
|
'ts/prefer-for-of': 'error',
|
||||||
'ts/prefer-function-type': 'error',
|
'ts/prefer-function-type': 'error',
|
||||||
|
|
||||||
|
// Only need 1 unused vars rule
|
||||||
|
'no-unused-vars': 'off',
|
||||||
'unused-imports/no-unused-vars': [
|
'unused-imports/no-unused-vars': [
|
||||||
'error',
|
'error',
|
||||||
{ args: 'after-used', vars: 'all', ignoreRestSiblings: true },
|
{ args: 'after-used', vars: 'all', ignoreRestSiblings: true },
|
||||||
|
@ -2,7 +2,7 @@ const jest = require('eslint-plugin-jest');
|
|||||||
|
|
||||||
// Specifically for tests
|
// Specifically for tests
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'opinionated:test',
|
name: 'opinionated/test',
|
||||||
// See https://github.com/jest-community/eslint-plugin-jest/issues/1408
|
// See https://github.com/jest-community/eslint-plugin-jest/issues/1408
|
||||||
plugins: {
|
plugins: {
|
||||||
jest,
|
jest,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
|
name: 'opinionated/typed',
|
||||||
rules: {
|
rules: {
|
||||||
'ts/consistent-type-assertions': [ 'error', {
|
'ts/consistent-type-assertions': [ 'error', {
|
||||||
assertionStyle: 'as',
|
assertionStyle: 'as',
|
||||||
@ -45,6 +46,8 @@ module.exports = {
|
|||||||
'ts/prefer-readonly': 'error',
|
'ts/prefer-readonly': 'error',
|
||||||
'ts/prefer-reduce-type-parameter': 'error',
|
'ts/prefer-reduce-type-parameter': 'error',
|
||||||
'ts/prefer-regexp-exec': 'error',
|
'ts/prefer-regexp-exec': 'error',
|
||||||
|
// Not sure if this would make code better
|
||||||
|
'ts/strict-boolean-expressions': 'off',
|
||||||
'ts/prefer-string-starts-ends-with': 'error',
|
'ts/prefer-string-starts-ends-with': 'error',
|
||||||
'ts/require-array-sort-compare': 'error',
|
'ts/require-array-sort-compare': 'error',
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'opinionated:unicorn',
|
name: 'opinionated/unicorn',
|
||||||
rules: {
|
rules: {
|
||||||
'unicorn/better-regex': 'error',
|
'unicorn/better-regex': 'error',
|
||||||
'unicorn/empty-brace-spaces': 'error',
|
'unicorn/empty-brace-spaces': 'error',
|
||||||
|
5842
package-lock.json
generated
5842
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@ -143,9 +143,9 @@
|
|||||||
"yup": "^1.3.2"
|
"yup": "^1.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "2.11.4",
|
"@antfu/eslint-config": "2.21.3",
|
||||||
"@commitlint/cli": "^17.7.2",
|
"@commitlint/cli": "^19.3.0",
|
||||||
"@commitlint/config-conventional": "^17.7.0",
|
"@commitlint/config-conventional": "^19.2.2",
|
||||||
"@inrupt/solid-client-authn-core": "^2.0.0",
|
"@inrupt/solid-client-authn-core": "^2.0.0",
|
||||||
"@inrupt/solid-client-authn-node": "^2.0.0",
|
"@inrupt/solid-client-authn-node": "^2.0.0",
|
||||||
"@tsconfig/node18": "^18.2.2",
|
"@tsconfig/node18": "^18.2.2",
|
||||||
@ -167,8 +167,8 @@
|
|||||||
"supertest": "^6.3.3",
|
"supertest": "^6.3.3",
|
||||||
"ts-jest": "^29.1.1",
|
"ts-jest": "^29.1.1",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typedoc": "^0.25.2",
|
"typedoc": "^0.26.4",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.5.3"
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
@ -20,7 +20,7 @@ import { readFile, writeFile } from 'fs-extra';
|
|||||||
* @returns Promise with output string
|
* @returns Promise with output string
|
||||||
*/
|
*/
|
||||||
async function capitalizeListEntries(input: string): Promise<string> {
|
async function capitalizeListEntries(input: string): Promise<string> {
|
||||||
return input.replaceAll(/^(\W*\* [a-z])/gmu, (match): string => match.toUpperCase());
|
return input.replaceAll(/^\W*\* [a-z]/gmu, (match): string => match.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,7 @@ export class UnsecureWebIdExtractor extends CredentialsExtractor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async handle({ headers }: HttpRequest): Promise<Credentials> {
|
public async handle({ headers }: HttpRequest): Promise<Credentials> {
|
||||||
const webId = /^WebID\s+(.*)/ui.exec(headers.authorization!)![1];
|
const webId = /^WebID\s+(.*)/iu.exec(headers.authorization!)![1];
|
||||||
this.logger.info(`Agent unsecurely claims to be ${webId}`);
|
this.logger.info(`Agent unsecurely claims to be ${webId}`);
|
||||||
return { agent: { webId }};
|
return { agent: { webId }};
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import { AclMode } from './permissions/AclPermissionSet';
|
|||||||
import { AccessMode } from './permissions/Permissions';
|
import { AccessMode } from './permissions/Permissions';
|
||||||
import type { PermissionMap, PermissionSet } from './permissions/Permissions';
|
import type { PermissionMap, PermissionSet } from './permissions/Permissions';
|
||||||
|
|
||||||
const modesMap: Record<string, Readonly<(keyof AclPermissionSet)[]>> = {
|
const modesMap: Record<string, readonly (keyof AclPermissionSet)[]> = {
|
||||||
[ACL.Read]: [ AccessMode.read ],
|
[ACL.Read]: [ AccessMode.read ],
|
||||||
[ACL.Write]: [ AccessMode.append, AccessMode.write ],
|
[ACL.Write]: [ AccessMode.append, AccessMode.write ],
|
||||||
[ACL.Append]: [ AccessMode.append ],
|
[ACL.Append]: [ AccessMode.append ],
|
||||||
|
@ -22,7 +22,7 @@ import type { PermissionMap } from './permissions/Permissions';
|
|||||||
import { AccessMode } from './permissions/Permissions';
|
import { AccessMode } from './permissions/Permissions';
|
||||||
|
|
||||||
// Maps WebACL-specific modes to generic access modes.
|
// Maps WebACL-specific modes to generic access modes.
|
||||||
const modesMap: Record<string, Readonly<(keyof AclPermissionSet)[]>> = {
|
const modesMap: Record<string, readonly (keyof AclPermissionSet)[]> = {
|
||||||
[ACL.Read]: [ AccessMode.read ],
|
[ACL.Read]: [ AccessMode.read ],
|
||||||
[ACL.Write]: [ AccessMode.append, AccessMode.write ],
|
[ACL.Write]: [ AccessMode.append, AccessMode.write ],
|
||||||
[ACL.Append]: [ AccessMode.append ],
|
[ACL.Append]: [ AccessMode.append ],
|
||||||
@ -69,7 +69,7 @@ export class WebAclReader extends PermissionReader {
|
|||||||
this.logger.debug(`Retrieving permissions of ${credentials.agent?.webId ?? 'an unknown agent'}`);
|
this.logger.debug(`Retrieving permissions of ${credentials.agent?.webId ?? 'an unknown agent'}`);
|
||||||
const aclMap = await this.getAclMatches(requestedModes.distinctKeys());
|
const aclMap = await this.getAclMatches(requestedModes.distinctKeys());
|
||||||
const storeMap = await this.findAuthorizationStatements(aclMap);
|
const storeMap = await this.findAuthorizationStatements(aclMap);
|
||||||
return await this.findPermissions(storeMap, credentials);
|
return this.findPermissions(storeMap, credentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,7 +21,7 @@ export class AgentGroupAccessChecker extends AccessChecker {
|
|||||||
const { webId } = credentials.agent;
|
const { webId } = credentials.agent;
|
||||||
const groups = acl.getObjects(rule, ACL.terms.agentGroup, null);
|
const groups = acl.getObjects(rule, ACL.terms.agentGroup, null);
|
||||||
|
|
||||||
return await promiseSome(groups.map(async(group: Term): Promise<boolean> =>
|
return promiseSome(groups.map(async(group: Term): Promise<boolean> =>
|
||||||
this.isMemberOfGroup(webId, group)));
|
this.isMemberOfGroup(webId, group)));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -51,6 +51,6 @@ export class AgentGroupAccessChecker extends AccessChecker {
|
|||||||
const representation = await fetchDataset(url);
|
const representation = await fetchDataset(url);
|
||||||
return readableToQuads(representation.data);
|
return readableToQuads(representation.data);
|
||||||
})();
|
})();
|
||||||
return await prom;
|
return prom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ class WebSocketListener extends WebSocketListenerEmitter {
|
|||||||
|
|
||||||
private onMessage(message: string): void {
|
private onMessage(message: string): void {
|
||||||
// Parse the message
|
// Parse the message
|
||||||
const match = /^(\w+)\s+(.+)$/u.exec(message);
|
const match = /^(\w+)\s+(\S.+)$/u.exec(message);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
this.sendMessage('warning', `Unrecognized message format: ${message}`);
|
this.sendMessage('warning', `Unrecognized message format: ${message}`);
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +23,7 @@ export class BaseCookieStore implements CookieStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async get(cookie: string): Promise<string | undefined> {
|
public async get(cookie: string): Promise<string | undefined> {
|
||||||
return await this.storage.get(cookie);
|
return this.storage.get(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async refresh(cookie: string): Promise<Date | undefined> {
|
public async refresh(cookie: string): Promise<Date | undefined> {
|
||||||
|
@ -103,7 +103,7 @@ export class BaseLoginAccountStorage<T extends IndexTypeCollection<T>> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async findIds<TType extends StringKey<T>>(type: TType, query: IndexedQuery<T, TType>): Promise<string[]> {
|
public async findIds<TType extends StringKey<T>>(type: TType, query: IndexedQuery<T, TType>): Promise<string[]> {
|
||||||
return await this.storage.findIds(type, query);
|
return this.storage.findIds(type, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async set<TType extends StringKey<T>>(type: TType, value: TypeObject<T[TType]>): Promise<void> {
|
public async set<TType extends StringKey<T>>(type: TType, value: TypeObject<T[TType]>): Promise<void> {
|
||||||
|
@ -149,7 +149,7 @@ export class V6MigrationInitializer extends Initializer {
|
|||||||
].join(' '), resolve);
|
].join(' '), resolve);
|
||||||
});
|
});
|
||||||
readline.close();
|
readline.close();
|
||||||
if (!/^y(?:es)?$/ui.test(answer)) {
|
if (!/^y(?:es)?$/iu.test(answer)) {
|
||||||
throw new Error('Stopping server as migration was cancelled.');
|
throw new Error('Stopping server as migration was cancelled.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,6 @@ export class BaseComponentsJsFactory implements ComponentsJsFactory {
|
|||||||
Promise<T> {
|
Promise<T> {
|
||||||
const manager = await this.buildManager();
|
const manager = await this.buildManager();
|
||||||
await manager.configRegistry.register(configPath);
|
await manager.configRegistry.register(configPath);
|
||||||
return await manager.instantiate(componentIri, { variables });
|
return manager.instantiate(componentIri, { variables });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,6 @@ export class RedirectingHttpHandler extends HttpHandler {
|
|||||||
throw new NotImplementedHttpError('Target is already correct.');
|
throw new NotImplementedHttpError('Target is already correct.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return /^(?:[a-z]+:)?\/\//ui.test(redirect) ? redirect : joinUrl(this.baseUrl, redirect);
|
return /^(?:[a-z]+:)?\/\//iu.test(redirect) ? redirect : joinUrl(this.baseUrl, redirect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -258,7 +258,7 @@ export class DataAccessorBasedStore implements ResourceStore {
|
|||||||
this.validateConditions(conditions, oldMetadata);
|
this.validateConditions(conditions, oldMetadata);
|
||||||
|
|
||||||
if (this.metadataStrategy.isAuxiliaryIdentifier(identifier)) {
|
if (this.metadataStrategy.isAuxiliaryIdentifier(identifier)) {
|
||||||
return await this.writeMetadata(identifier, representation);
|
return this.writeMetadata(identifier, representation);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Potentially have to create containers if it didn't exist yet
|
// Potentially have to create containers if it didn't exist yet
|
||||||
|
@ -184,7 +184,7 @@ export class FileDataAccessor implements DataAccessor {
|
|||||||
*/
|
*/
|
||||||
private async getDirectoryMetadata(link: ResourceLink, stats: Stats):
|
private async getDirectoryMetadata(link: ResourceLink, stats: Stats):
|
||||||
Promise<RepresentationMetadata> {
|
Promise<RepresentationMetadata> {
|
||||||
return await this.getBaseMetadata(link, stats, true);
|
return this.getBaseMetadata(link, stats, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +73,7 @@ export class SparqlDataAccessor implements DataAccessor {
|
|||||||
*/
|
*/
|
||||||
public async getData(identifier: ResourceIdentifier): Promise<Guarded<Readable>> {
|
public async getData(identifier: ResourceIdentifier): Promise<Guarded<Readable>> {
|
||||||
const name = namedNode(identifier.path);
|
const name = namedNode(identifier.path);
|
||||||
return await this.sendSparqlConstruct(this.sparqlConstruct(name));
|
return this.sendSparqlConstruct(this.sparqlConstruct(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +98,7 @@ export class ContainerToTemplateConverter extends BaseTypedRepresentationConvert
|
|||||||
* Derives a short name for the given resource.
|
* Derives a short name for the given resource.
|
||||||
*/
|
*/
|
||||||
private getLocalName(iri: string): string {
|
private getLocalName(iri: string): string {
|
||||||
const match = /:\/+([^/]+).*?\/([^/]*)\/?$/u.exec(iri);
|
const match = /:\/+([^/]+)(?:\/[^/]*)*?\/([^/]*)\/?$/u.exec(iri);
|
||||||
return match?.[2] ? decodeURIComponent(match[2]) : match?.[1] ?? iri;
|
return match?.[2] ? decodeURIComponent(match[2]) : match?.[1] ?? iri;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,8 @@ export class JsonResourceStorage<T> implements KeyValueStorage<string, T> {
|
|||||||
const identifier = this.keyToIdentifier(key);
|
const identifier = this.keyToIdentifier(key);
|
||||||
// eslint-disable-next-line ts/naming-convention
|
// eslint-disable-next-line ts/naming-convention
|
||||||
const representation = await this.source.getRepresentation(identifier, { type: { 'application/json': 1 }});
|
const representation = await this.source.getRepresentation(identifier, { type: { 'application/json': 1 }});
|
||||||
return JSON.parse(await readableToString(representation.data)) as Promise<T>;
|
// eslint-disable-next-line ts/no-unsafe-return
|
||||||
|
return JSON.parse(await readableToString(representation.data));
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
if (!NotFoundHttpError.isInstance(error)) {
|
if (!NotFoundHttpError.isInstance(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
@ -48,7 +49,7 @@ export class JsonResourceStorage<T> implements KeyValueStorage<string, T> {
|
|||||||
|
|
||||||
public async has(key: string): Promise<boolean> {
|
public async has(key: string): Promise<boolean> {
|
||||||
const identifier = this.keyToIdentifier(key);
|
const identifier = this.keyToIdentifier(key);
|
||||||
return await this.source.hasResource(identifier);
|
return this.source.hasResource(identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async set(key: string, value: unknown): Promise<this> {
|
public async set(key: string, value: unknown): Promise<this> {
|
||||||
|
@ -48,7 +48,7 @@ export class ExtensionBasedMapper extends BaseFileIdentifierMapper {
|
|||||||
// Existing file
|
// Existing file
|
||||||
if (!contentType) {
|
if (!contentType) {
|
||||||
// Find a matching file
|
// Find a matching file
|
||||||
const [ , folder, documentName ] = /^(.*\/)(.*)$/u.exec(filePath)!;
|
const [ , folder, documentName ] = /^(.*\/)([^/]*)$/u.exec(filePath)!;
|
||||||
let fileName: string | undefined;
|
let fileName: string | undefined;
|
||||||
try {
|
try {
|
||||||
const files = await fsPromises.readdir(folder);
|
const files = await fsPromises.readdir(folder);
|
||||||
|
@ -118,7 +118,7 @@ export interface LinkEntry {
|
|||||||
//
|
//
|
||||||
|
|
||||||
// REUSED REGEXES
|
// REUSED REGEXES
|
||||||
export const TCHAR = /[a-zA-Z0-9!#$%&'*+-.^_`|~]/u;
|
export const TCHAR = /[-\w!#$%&'*+.^`|~]/u;
|
||||||
export const TOKEN = new RegExp(`^${TCHAR.source}+$`, 'u');
|
export const TOKEN = new RegExp(`^${TCHAR.source}+$`, 'u');
|
||||||
export const SIMPLE_MEDIA_RANGE = new RegExp(`^${TCHAR.source}+/${TCHAR.source}+$`, 'u');
|
export const SIMPLE_MEDIA_RANGE = new RegExp(`^${TCHAR.source}+/${TCHAR.source}+$`, 'u');
|
||||||
export const QUOTED_STRING =
|
export const QUOTED_STRING =
|
||||||
|
@ -493,7 +493,7 @@ const authSchemeRegexCache: Map<string, RegExp> = new Map();
|
|||||||
export function matchesAuthorizationScheme(scheme: string, authorization?: string): boolean {
|
export function matchesAuthorizationScheme(scheme: string, authorization?: string): boolean {
|
||||||
const lowerCaseScheme = scheme.toLowerCase();
|
const lowerCaseScheme = scheme.toLowerCase();
|
||||||
if (!authSchemeRegexCache.has(lowerCaseScheme)) {
|
if (!authSchemeRegexCache.has(lowerCaseScheme)) {
|
||||||
authSchemeRegexCache.set(lowerCaseScheme, new RegExp(`^${escapeStringRegexp(lowerCaseScheme)} `, 'ui'));
|
authSchemeRegexCache.set(lowerCaseScheme, new RegExp(`^${escapeStringRegexp(lowerCaseScheme)} `, 'iu'));
|
||||||
}
|
}
|
||||||
// Support authorization being undefined (for the sake of usability).
|
// Support authorization being undefined (for the sake of usability).
|
||||||
return typeof authorization !== 'undefined' && authSchemeRegexCache.get(lowerCaseScheme)!.test(authorization);
|
return typeof authorization !== 'undefined' && authSchemeRegexCache.get(lowerCaseScheme)!.test(authorization);
|
||||||
|
@ -126,7 +126,7 @@ export function getExtension(path: string): string {
|
|||||||
* preserving but normalizing path delimiters and their escaped forms.
|
* preserving but normalizing path delimiters and their escaped forms.
|
||||||
*/
|
*/
|
||||||
function transformPathComponents(path: string, transform: (part: string) => string): string {
|
function transformPathComponents(path: string, transform: (part: string) => string): string {
|
||||||
const [ , base, queryString ] = /^([^?]*)(.*)$/u.exec(path)!;
|
const [ , base, queryString ] = /^([^?]*)(\?.*)?$/u.exec(path)!;
|
||||||
const transformed = base
|
const transformed = base
|
||||||
// We split on actual URI path component delimiters (slash and backslash),
|
// We split on actual URI path component delimiters (slash and backslash),
|
||||||
// but also on things that could be wrongly interpreted as component delimiters,
|
// but also on things that could be wrongly interpreted as component delimiters,
|
||||||
@ -135,7 +135,7 @@ function transformPathComponents(path: string, transform: (part: string) => stri
|
|||||||
// since they would become _actual_ delimiters if accidentally decoded.
|
// since they would become _actual_ delimiters if accidentally decoded.
|
||||||
// Additionally, we need to preserve any encoded percent signs (%25)
|
// Additionally, we need to preserve any encoded percent signs (%25)
|
||||||
// that precede them, because these might change their interpretation as well.
|
// that precede them, because these might change their interpretation as well.
|
||||||
.split(/(\/|\\|%(?:25)*(?:2f|5c))/ui)
|
.split(/(\/|\\|%(?:25)*(?:2f|5c))/iu)
|
||||||
// Even parts map to components that need to be transformed,
|
// Even parts map to components that need to be transformed,
|
||||||
// odd parts to (possibly escaped) delimiters that need to be normalized.
|
// odd parts to (possibly escaped) delimiters that need to be normalized.
|
||||||
.map((part, index): string =>
|
.map((part, index): string =>
|
||||||
@ -172,7 +172,7 @@ const forbiddenSymbols = {
|
|||||||
'*': '%2A',
|
'*': '%2A',
|
||||||
} as const;
|
} as const;
|
||||||
/* eslint-enable ts/naming-convention */
|
/* eslint-enable ts/naming-convention */
|
||||||
const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, 'ug');
|
const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, 'gu');
|
||||||
/**
|
/**
|
||||||
* This function is used when converting a URI to a file path. Decodes all components of a URI path,
|
* This function is used when converting a URI to a file path. Decodes all components of a URI path,
|
||||||
* with the exception of encoded slash characters, as this would lead to unexpected file locations
|
* with the exception of encoded slash characters, as this would lead to unexpected file locations
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* Helper class for instantiating multiple objects with Components.js.
|
* Helper class for instantiating multiple objects with Components.js.
|
||||||
* See https://github.com/LinkedSoftwareDependencies/Components.js/issues/26
|
* See https://github.com/LinkedSoftwareDependencies/Components.js/issues/26
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line ts/no-extraneous-class
|
||||||
export class RecordObject implements Record<string, unknown> {
|
export class RecordObject implements Record<string, unknown> {
|
||||||
public constructor(record: Record<string, unknown> = {}) {
|
public constructor(record: Record<string, unknown> = {}) {
|
||||||
// eslint-disable-next-line no-constructor-return
|
// eslint-disable-next-line no-constructor-return
|
||||||
|
@ -6,9 +6,9 @@ import { types } from 'node:util';
|
|||||||
export function isError(error: unknown): error is Error {
|
export function isError(error: unknown): error is Error {
|
||||||
return types.isNativeError(error) ||
|
return types.isNativeError(error) ||
|
||||||
(Boolean(error) &&
|
(Boolean(error) &&
|
||||||
typeof (error as Error).name === 'string' &&
|
typeof (error as Error).name === 'string' &&
|
||||||
typeof (error as Error).message === 'string' &&
|
typeof (error as Error).message === 'string' &&
|
||||||
(typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string'));
|
(typeof (error as Error).stack === 'undefined' || typeof (error as Error).stack === 'string'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,8 @@ const BaseHttpError = generateHttpErrorClass(405, 'MethodNotAllowedHttpError');
|
|||||||
* Can keep track of the methods that are not allowed.
|
* Can keep track of the methods that are not allowed.
|
||||||
*/
|
*/
|
||||||
export class MethodNotAllowedHttpError extends BaseHttpError {
|
export class MethodNotAllowedHttpError extends BaseHttpError {
|
||||||
|
// Components.js can't parse `readonly`
|
||||||
|
// eslint-disable-next-line ts/array-type
|
||||||
public readonly methods: Readonly<string[]>;
|
public readonly methods: Readonly<string[]>;
|
||||||
|
|
||||||
public constructor(methods: string[] = [], message?: string, options?: HttpErrorOptions) {
|
public constructor(methods: string[] = [], message?: string, options?: HttpErrorOptions) {
|
||||||
|
@ -31,7 +31,7 @@ export async function instantiateFromConfig(
|
|||||||
for (const configPath of configPaths) {
|
for (const configPath of configPaths) {
|
||||||
await manager.configRegistry.register(configPath);
|
await manager.configRegistry.register(configPath);
|
||||||
}
|
}
|
||||||
return await manager.instantiate(componentUrl, { variables });
|
return manager.instantiate(componentUrl, { variables });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTestConfigPath(configFile: string): string {
|
export function getTestConfigPath(configFile: string): string {
|
||||||
|
@ -257,9 +257,9 @@ describe('AppRunner', (): void => {
|
|||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
caughtError = error as Error;
|
caughtError = error as Error;
|
||||||
}
|
}
|
||||||
expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu);
|
expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/u);
|
||||||
expect(caughtError?.message).toMatch(
|
expect(caughtError?.message).toMatch(
|
||||||
/\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/mu,
|
/\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/u,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(write).toHaveBeenCalledTimes(0);
|
expect(write).toHaveBeenCalledTimes(0);
|
||||||
@ -295,7 +295,7 @@ describe('AppRunner', (): void => {
|
|||||||
}
|
}
|
||||||
expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu);
|
expect(caughtError?.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu);
|
||||||
expect(caughtError?.message).toMatch(
|
expect(caughtError?.message).toMatch(
|
||||||
/\[ViolatingClass1, ViolatingClass2\] are not threadsafe and should not be run in multithreaded setups!/mu,
|
/\[ViolatingClass1, ViolatingClass2\] are not threadsafe and should not be run in multithreaded setups!/u,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(write).toHaveBeenCalledTimes(0);
|
expect(write).toHaveBeenCalledTimes(0);
|
||||||
@ -481,7 +481,7 @@ describe('AppRunner', (): void => {
|
|||||||
}
|
}
|
||||||
expect(caughtError.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu);
|
expect(caughtError.message).toMatch(/^Cannot run a singlethreaded-only component in a multithreaded setup!/mu);
|
||||||
expect(caughtError?.message).toMatch(
|
expect(caughtError?.message).toMatch(
|
||||||
/\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/mu,
|
/\[ViolatingClass\] is not threadsafe and should not be run in multithreaded setups!/u,
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(write).toHaveBeenCalledTimes(0);
|
expect(write).toHaveBeenCalledTimes(0);
|
||||||
@ -820,7 +820,7 @@ describe('AppRunner', (): void => {
|
|||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(write).toHaveBeenCalledTimes(1);
|
expect(write).toHaveBeenCalledTimes(1);
|
||||||
expect(write).toHaveBeenLastCalledWith(expect.stringMatching(/Error: Fatal/mu));
|
expect(write).toHaveBeenLastCalledWith(expect.stringMatching(/Error: Fatal/u));
|
||||||
|
|
||||||
expect(exit).toHaveBeenCalledTimes(1);
|
expect(exit).toHaveBeenCalledTimes(1);
|
||||||
expect(exit).toHaveBeenLastCalledWith(1);
|
expect(exit).toHaveBeenLastCalledWith(1);
|
||||||
|
@ -302,7 +302,7 @@ describe('A DataAccessorBasedStore', (): void => {
|
|||||||
|
|
||||||
const generatedID = [ ...result.keys() ].find((id): boolean => id.path !== resourceID.path)!;
|
const generatedID = [ ...result.keys() ].find((id): boolean => id.path !== resourceID.path)!;
|
||||||
expect(generatedID).toBeDefined();
|
expect(generatedID).toBeDefined();
|
||||||
expect(generatedID.path).toMatch(new RegExp(`^${root}[^/]+?/$`, 'u'));
|
expect(generatedID.path).toMatch(new RegExp(`^${root}[^/]*/$`, 'u'));
|
||||||
|
|
||||||
expect(accessor.data[generatedID.path]).toBeDefined();
|
expect(accessor.data[generatedID.path]).toBeDefined();
|
||||||
expect(accessor.data[generatedID.path].metadata.contentType).toBeUndefined();
|
expect(accessor.data[generatedID.path].metadata.contentType).toBeUndefined();
|
||||||
@ -630,8 +630,7 @@ describe('A DataAccessorBasedStore', (): void => {
|
|||||||
data: guardedStreamFrom([ resourceData ]),
|
data: guardedStreamFrom([ resourceData ]),
|
||||||
metadata: new RepresentationMetadata({
|
metadata: new RepresentationMetadata({
|
||||||
[CONTENT_TYPE]: 'text/plain',
|
[CONTENT_TYPE]: 'text/plain',
|
||||||
[RDF.type]: namedNode(LDP.Resource),
|
[RDF.type]: [ namedNode(LDP.Resource), namedNode('http://example.org/Type') ],
|
||||||
[RDF.type]: namedNode('http://example.org/Type'),
|
|
||||||
}),
|
}),
|
||||||
isEmpty: false,
|
isEmpty: false,
|
||||||
};
|
};
|
||||||
@ -659,8 +658,7 @@ describe('A DataAccessorBasedStore', (): void => {
|
|||||||
data: guardedStreamFrom([ '<a> <b> <c>' ]),
|
data: guardedStreamFrom([ '<a> <b> <c>' ]),
|
||||||
metadata: new RepresentationMetadata({
|
metadata: new RepresentationMetadata({
|
||||||
[CONTENT_TYPE]: 'text/turtle',
|
[CONTENT_TYPE]: 'text/turtle',
|
||||||
[RDF.type]: namedNode(LDP.Resource),
|
[RDF.type]: [ namedNode(LDP.Resource), namedNode('http://example.org/Type') ],
|
||||||
[RDF.type]: namedNode('http://example.org/Type'),
|
|
||||||
}),
|
}),
|
||||||
isEmpty: false,
|
isEmpty: false,
|
||||||
};
|
};
|
||||||
|
@ -17,9 +17,9 @@ describe('A JsonFileStorage', (): void => {
|
|||||||
cache = mockFileSystem(rootFilePath);
|
cache = mockFileSystem(rootFilePath);
|
||||||
locker = {
|
locker = {
|
||||||
withReadLock:
|
withReadLock:
|
||||||
jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise<any> => await whileLocked()),
|
jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise<any> => whileLocked()),
|
||||||
withWriteLock:
|
withWriteLock:
|
||||||
jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise<any> => await whileLocked()),
|
jest.fn(async(identifier: ResourceIdentifier, whileLocked: () => any): Promise<any> => whileLocked()),
|
||||||
};
|
};
|
||||||
storage = new JsonFileStorage(`${rootFilePath}${jsonPath}`, locker);
|
storage = new JsonFileStorage(`${rootFilePath}${jsonPath}`, locker);
|
||||||
});
|
});
|
||||||
|
@ -78,7 +78,7 @@ export function getSocket(name: typeof socketNames[number]): string {
|
|||||||
|
|
||||||
export function describeIf(envFlag: string): Describe {
|
export function describeIf(envFlag: string): Describe {
|
||||||
const flag = `TEST_${envFlag.toUpperCase()}`;
|
const flag = `TEST_${envFlag.toUpperCase()}`;
|
||||||
const enabled = !/^(|0|false)$/iu.test(process.env[flag] ?? '');
|
const enabled = !/^(?:0|false)?$/iu.test(process.env[flag] ?? '');
|
||||||
return enabled ? describe : describe.skip;
|
return enabled ? describe : describe.skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +316,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any
|
|||||||
return mockFs.createWriteStream(path);
|
return mockFs.createWriteStream(path);
|
||||||
},
|
},
|
||||||
async realpath(path: string): Promise<string> {
|
async realpath(path: string): Promise<string> {
|
||||||
return await mockFs.promises.realpath(path);
|
return mockFs.promises.realpath(path);
|
||||||
},
|
},
|
||||||
async stat(path: string): Promise<Stats> {
|
async stat(path: string): Promise<Stats> {
|
||||||
return mockFs.promises.lstat(await mockFs.promises.realpath(path));
|
return mockFs.promises.lstat(await mockFs.promises.realpath(path));
|
||||||
@ -334,7 +334,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any
|
|||||||
await mockFs.promises.rm(path);
|
await mockFs.promises.rm(path);
|
||||||
},
|
},
|
||||||
async readdir(path: string): Promise<string[]> {
|
async readdir(path: string): Promise<string[]> {
|
||||||
return await mockFs.promises.readdir(path);
|
return mockFs.promises.readdir(path);
|
||||||
},
|
},
|
||||||
async* opendir(path: string): AsyncIterableIterator<Dirent> {
|
async* opendir(path: string): AsyncIterableIterator<Dirent> {
|
||||||
for await (const entry of mockFs.promises.opendir(path)) {
|
for await (const entry of mockFs.promises.opendir(path)) {
|
||||||
@ -345,7 +345,7 @@ export function mockFileSystem(rootFilepath?: string, time?: Date): { data: any
|
|||||||
await mockFs.promises.mkdir(path);
|
await mockFs.promises.mkdir(path);
|
||||||
},
|
},
|
||||||
async readFile(path: string): Promise<string> {
|
async readFile(path: string): Promise<string> {
|
||||||
return await mockFs.promises.readFile(path);
|
return mockFs.promises.readFile(path);
|
||||||
},
|
},
|
||||||
async writeFile(path: string, data: string): Promise<void> {
|
async writeFile(path: string, data: string): Promise<void> {
|
||||||
await mockFs.promises.writeFile(path, data);
|
await mockFs.promises.writeFile(path, data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user