mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
refactor: Remove RuntimeConfig in favor of config variables, Closes #106
This commit is contained in:
parent
b1991cb08a
commit
1dd140ab61
@ -10,6 +10,7 @@
|
||||
"files-scs:config/presets/ldp/request-parser.json",
|
||||
"files-scs:config/presets/setup.json",
|
||||
"files-scs:config/presets/storage.json",
|
||||
"files-scs:config/presets/storage_wrapper.json"
|
||||
"files-scs:config/presets/storage_wrapper.json",
|
||||
"files-scs:config/presets/cli-params.json"
|
||||
]
|
||||
}
|
||||
|
17
config/presets/cli-params.json
Normal file
17
config/presets/cli-params.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
|
||||
"@graph": [
|
||||
{
|
||||
"@id": "urn:solid-server:default:variable:port",
|
||||
"@type": "Variable"
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:variable:base",
|
||||
"@type": "Variable"
|
||||
},
|
||||
{
|
||||
"@id": "urn:solid-server:default:variable:rootFilePath",
|
||||
"@type": "Variable"
|
||||
}
|
||||
]
|
||||
}
|
@ -13,10 +13,11 @@
|
||||
"Setup:_aclManager": {
|
||||
"@id": "urn:solid-server:default:AclManager"
|
||||
},
|
||||
"Setup:_runtimeConfig": {
|
||||
"@id": "urn:solid-server:default:RuntimeConfig",
|
||||
"@type": "RuntimeConfig",
|
||||
"RuntimeConfigData:_port": 3000
|
||||
"Setup:_base": {
|
||||
"@id": "urn:solid-server:default:variable:base"
|
||||
},
|
||||
"Setup:_port": {
|
||||
"@id": "urn:solid-server:default:variable:port"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -4,8 +4,8 @@
|
||||
{
|
||||
"@id": "urn:solid-server:default:ResourceStore",
|
||||
"@type": "InMemoryResourceStore",
|
||||
"InMemoryResourceStore:_runtimeConfig": {
|
||||
"@id": "urn:solid-server:default:RuntimeConfig"
|
||||
"InMemoryResourceStore:_base": {
|
||||
"@id": "urn:solid-server:default:variable:base"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -72,8 +72,8 @@
|
||||
{
|
||||
"@id": "urn:solid-server:default:UrlContainerManager",
|
||||
"@type": "UrlContainerManager",
|
||||
"UrlContainerManager:_runtimeConfig": {
|
||||
"@id": "urn:solid-server:default:RuntimeConfig"
|
||||
"UrlContainerManager:_base": {
|
||||
"@id": "urn:solid-server:default:variable:base"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
1
index.ts
1
index.ts
@ -12,7 +12,6 @@ export * from './src/authorization/WebAclAuthorizer';
|
||||
|
||||
// Init
|
||||
export * from './src/init/CliRunner';
|
||||
export * from './src/init/RuntimeConfig';
|
||||
export * from './src/init/Setup';
|
||||
|
||||
// LDP/HTTP
|
||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -2519,9 +2519,9 @@
|
||||
}
|
||||
},
|
||||
"componentsjs": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/componentsjs/-/componentsjs-3.4.2.tgz",
|
||||
"integrity": "sha512-ICaSvvxY/CvWwFt0lLsoRL/DHY09akoI6x9WakQQ9g4GYHVaZumWSAdOrzM/htjGpBumpVh1C/4hk0/ghh9jXA==",
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/componentsjs/-/componentsjs-3.6.0.tgz",
|
||||
"integrity": "sha512-G3lMrIbE7iiZpERoPXnxM0aDopq9q1s1C5aIUrnHW3rcRDa3kcCytc4ASt5aFRjNiwBubivcMfJsvF2ihXg7jQ==",
|
||||
"requires": {
|
||||
"@types/lodash": "^4.14.56",
|
||||
"@types/minimist": "^1.2.0",
|
||||
|
@ -42,7 +42,7 @@
|
||||
"prepare": "npm run build",
|
||||
"start": "node ./bin/server.js -p 3000",
|
||||
"test": "jest",
|
||||
"validate": "componentsjs-compile-config urn:solid-server:default -c config/config-default.json > /dev/null",
|
||||
"validate": "componentsjs-compile-config urn:solid-server:default -c config/config-default.json -f > /dev/null",
|
||||
"version": "manual-git-changelog onversion",
|
||||
"watch": "nodemon --watch \"src/**/*.js\" --watch \"bin/**/*.js\" --exec npm start"
|
||||
},
|
||||
@ -76,7 +76,7 @@
|
||||
"@types/yargs": "^15.0.5",
|
||||
"arrayify-stream": "^1.0.0",
|
||||
"async-lock": "^1.2.4",
|
||||
"componentsjs": "^3.4.2",
|
||||
"componentsjs": "^3.6.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"mime-types": "^2.1.27",
|
||||
|
@ -2,7 +2,6 @@ import * as Path from 'path';
|
||||
import { ReadStream, WriteStream } from 'tty';
|
||||
import { Loader, LoaderProperties } from 'componentsjs';
|
||||
import yargs from 'yargs';
|
||||
import { RuntimeConfig } from './RuntimeConfig';
|
||||
import { Setup } from './Setup';
|
||||
|
||||
/**
|
||||
@ -23,12 +22,12 @@ export const runCustom = function(
|
||||
const { argv } = yargs
|
||||
.usage('node ./bin/server.js [args]')
|
||||
.options({
|
||||
port: { type: 'number', alias: 'p' },
|
||||
port: { type: 'number', alias: 'p', default: 3000 },
|
||||
config: { type: 'string', alias: 'c' },
|
||||
})
|
||||
.help();
|
||||
|
||||
new Promise<RuntimeConfig>(async(resolve): Promise<void> => {
|
||||
(async(): Promise<string> => {
|
||||
// Load provided or default config file
|
||||
const configPath = argv.config ?
|
||||
Path.join(process.cwd(), argv.config) :
|
||||
@ -38,10 +37,16 @@ export const runCustom = function(
|
||||
const loader = new Loader(properties);
|
||||
await loader.registerAvailableModuleResources();
|
||||
const setup: Setup = await loader
|
||||
.instantiateFromUrl('urn:solid-server:default', configPath);
|
||||
resolve(await setup.setup({ port: argv.port }));
|
||||
}).then((runtimeConfig: RuntimeConfig): void => {
|
||||
stdout.write(`Running at ${runtimeConfig.base}\n`);
|
||||
.instantiateFromUrl('urn:solid-server:default', configPath, undefined, {
|
||||
variables: {
|
||||
'urn:solid-server:default:variable:port': argv.port,
|
||||
'urn:solid-server:default:variable:base': `http://localhost:${argv.port}/`,
|
||||
'urn:solid-server:default:variable:rootFilePath': process.cwd(),
|
||||
},
|
||||
});
|
||||
return await setup.setup();
|
||||
})().then((base: string): void => {
|
||||
stdout.write(`Running at ${base}\n`);
|
||||
}).catch((error): void => {
|
||||
stderr.write(`${error}\n`);
|
||||
});
|
||||
|
@ -1,43 +0,0 @@
|
||||
import { ensureTrailingSlash } from '../util/Util';
|
||||
|
||||
/**
|
||||
* This class holds all configuration options that can be defined by the user via the command line.
|
||||
*
|
||||
* Concretely, this contains data that is only relevant *after* dependency injection.
|
||||
*/
|
||||
export class RuntimeConfig implements RuntimeConfigData {
|
||||
private pport!: number;
|
||||
private pbase!: string;
|
||||
private prootFilepath!: string;
|
||||
|
||||
public constructor(data: RuntimeConfigData = {}) {
|
||||
this.reset(data);
|
||||
}
|
||||
|
||||
public reset(data: RuntimeConfigData): void {
|
||||
this.pport = data.port ?? 3000;
|
||||
this.pbase = ensureTrailingSlash(data.base ?? `http://localhost:${this.port}/`);
|
||||
this.prootFilepath = data.rootFilepath ?? process.cwd();
|
||||
}
|
||||
|
||||
/**
|
||||
* The returned URL is ensured to have a trailing slash.
|
||||
*/
|
||||
public get base(): string {
|
||||
return this.pbase;
|
||||
}
|
||||
|
||||
public get port(): number {
|
||||
return this.pport;
|
||||
}
|
||||
|
||||
public get rootFilepath(): string {
|
||||
return this.prootFilepath;
|
||||
}
|
||||
}
|
||||
|
||||
export interface RuntimeConfigData {
|
||||
port?: number;
|
||||
base?: string;
|
||||
rootFilepath?: string;
|
||||
}
|
@ -3,7 +3,6 @@ import { AclManager } from '../authorization/AclManager';
|
||||
import { ExpressHttpServer } from '../server/ExpressHttpServer';
|
||||
import { ResourceStore } from '../storage/ResourceStore';
|
||||
import { TEXT_TURTLE } from '../util/ContentTypes';
|
||||
import { RuntimeConfig, RuntimeConfigData } from './RuntimeConfig';
|
||||
|
||||
/**
|
||||
* Invokes all logic to setup a server.
|
||||
@ -12,27 +11,27 @@ export class Setup {
|
||||
private readonly httpServer: ExpressHttpServer;
|
||||
private readonly store: ResourceStore;
|
||||
private readonly aclManager: AclManager;
|
||||
private readonly runtimeConfig: RuntimeConfig;
|
||||
private readonly base: string;
|
||||
private readonly port: number;
|
||||
|
||||
public constructor(
|
||||
httpServer: ExpressHttpServer,
|
||||
store: ResourceStore,
|
||||
aclManager: AclManager,
|
||||
runtimeConfig: RuntimeConfig,
|
||||
base: string,
|
||||
port: number,
|
||||
) {
|
||||
this.httpServer = httpServer;
|
||||
this.store = store;
|
||||
this.aclManager = aclManager;
|
||||
this.runtimeConfig = runtimeConfig;
|
||||
this.base = base;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up a server at the given port and base URL.
|
||||
* @param data - Runtime config data.
|
||||
* Set up a server.
|
||||
*/
|
||||
public async setup(data: RuntimeConfigData = {}): Promise<RuntimeConfig> {
|
||||
this.runtimeConfig.reset(data);
|
||||
|
||||
public async setup(): Promise<string> {
|
||||
// Set up acl so everything can still be done by default
|
||||
// Note that this will need to be adapted to go through all the correct channels later on
|
||||
const aclSetup = async(): Promise<void> => {
|
||||
@ -47,10 +46,10 @@ export class Setup {
|
||||
acl:mode acl:Append;
|
||||
acl:mode acl:Delete;
|
||||
acl:mode acl:Control;
|
||||
acl:accessTo <${this.runtimeConfig.base}>;
|
||||
acl:default <${this.runtimeConfig.base}>.`;
|
||||
acl:accessTo <${this.base}>;
|
||||
acl:default <${this.base}>.`;
|
||||
await this.store.setRepresentation(
|
||||
await this.aclManager.getAcl({ path: this.runtimeConfig.base }),
|
||||
await this.aclManager.getAcl({ path: this.base }),
|
||||
{
|
||||
binary: true,
|
||||
data: streamifyArray([ acl ]),
|
||||
@ -64,8 +63,8 @@ export class Setup {
|
||||
};
|
||||
await aclSetup();
|
||||
|
||||
this.httpServer.listen(this.runtimeConfig.port);
|
||||
this.httpServer.listen(this.port);
|
||||
|
||||
return this.runtimeConfig;
|
||||
return this.base;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { posix } from 'path';
|
||||
import { types } from 'mime-types';
|
||||
import { RuntimeConfig } from '../init/RuntimeConfig';
|
||||
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { APPLICATION_OCTET_STREAM, TEXT_TURTLE } from '../util/ContentTypes';
|
||||
import { ConflictHttpError } from '../util/errors/ConflictHttpError';
|
||||
@ -24,22 +23,22 @@ export interface ResourcePath {
|
||||
}
|
||||
|
||||
export class ExtensionBasedMapper implements FileIdentifierMapper {
|
||||
private readonly runtimeConfig: RuntimeConfig;
|
||||
private readonly base: string;
|
||||
private readonly prootFilepath: string;
|
||||
private readonly types: Record<string, any>;
|
||||
|
||||
public constructor(runtimeConfig: RuntimeConfig, overrideTypes = { acl: TEXT_TURTLE, metadata: TEXT_TURTLE }) {
|
||||
this.runtimeConfig = runtimeConfig;
|
||||
public constructor(base: string, rootFilepath: string, overrideTypes = { acl: TEXT_TURTLE, metadata: TEXT_TURTLE }) {
|
||||
this.base = base;
|
||||
this.prootFilepath = rootFilepath;
|
||||
this.types = { ...types, ...overrideTypes };
|
||||
}
|
||||
|
||||
// Using getters because the values of runtimeConfig get filled in at runtime (so they are still empty at
|
||||
// construction time until issue #106 gets resolved.)
|
||||
public get baseRequestURI(): string {
|
||||
return trimTrailingSlashes(this.runtimeConfig.base);
|
||||
return trimTrailingSlashes(this.base);
|
||||
}
|
||||
|
||||
public get rootFilepath(): string {
|
||||
return trimTrailingSlashes(this.runtimeConfig.rootFilepath);
|
||||
return trimTrailingSlashes(this.prootFilepath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { PassThrough } from 'stream';
|
||||
import arrayifyStream from 'arrayify-stream';
|
||||
import streamifyArray from 'streamify-array';
|
||||
import { RuntimeConfig } from '../init/RuntimeConfig';
|
||||
import { Representation } from '../ldp/representation/Representation';
|
||||
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { TEXT_TURTLE } from '../util/ContentTypes';
|
||||
@ -15,15 +14,15 @@ import { ResourceStore } from './ResourceStore';
|
||||
*/
|
||||
export class InMemoryResourceStore implements ResourceStore {
|
||||
private readonly store: { [id: string]: Representation };
|
||||
private readonly runtimeConfig: RuntimeConfig;
|
||||
private readonly base: string;
|
||||
private index = 0;
|
||||
|
||||
/**
|
||||
* @param runtimeConfig - Config containing base that will be stripped of all incoming URIs
|
||||
* and added to all outgoing ones to find the relative path.
|
||||
* @param base - Base that will be stripped of all incoming URIs
|
||||
* and added to all outgoing ones to find the relative path.
|
||||
*/
|
||||
public constructor(runtimeConfig: RuntimeConfig) {
|
||||
this.runtimeConfig = runtimeConfig;
|
||||
public constructor(base: string) {
|
||||
this.base = ensureTrailingSlash(base);
|
||||
|
||||
this.store = {
|
||||
// Default root entry (what you get when the identifier is equal to the base)
|
||||
@ -105,8 +104,8 @@ export class InMemoryResourceStore implements ResourceStore {
|
||||
* @returns A string representing the relative path.
|
||||
*/
|
||||
private parseIdentifier(identifier: ResourceIdentifier): string {
|
||||
const path = identifier.path.slice(this.runtimeConfig.base.length);
|
||||
if (!identifier.path.startsWith(this.runtimeConfig.base)) {
|
||||
const path = identifier.path.slice(this.base.length);
|
||||
if (!identifier.path.startsWith(this.base)) {
|
||||
throw new NotFoundHttpError();
|
||||
}
|
||||
return path;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { RuntimeConfig } from '../init/RuntimeConfig';
|
||||
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
|
||||
import { ensureTrailingSlash } from '../util/Util';
|
||||
import { ContainerManager } from './ContainerManager';
|
||||
@ -7,15 +6,15 @@ import { ContainerManager } from './ContainerManager';
|
||||
* Determines containers based on URL decomposition.
|
||||
*/
|
||||
export class UrlContainerManager implements ContainerManager {
|
||||
private readonly runtimeConfig: RuntimeConfig;
|
||||
private readonly base: string;
|
||||
|
||||
public constructor(runtimeConfig: RuntimeConfig) {
|
||||
this.runtimeConfig = runtimeConfig;
|
||||
public constructor(base: string) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
public async getContainer(id: ResourceIdentifier): Promise<ResourceIdentifier> {
|
||||
const path = this.canonicalUrl(id.path);
|
||||
if (this.runtimeConfig.base === path) {
|
||||
if (this.base === path) {
|
||||
throw new Error('Root does not have a container.');
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import {
|
||||
ResourceStore,
|
||||
UnsecureWebIdExtractor,
|
||||
QuadToRdfConverter,
|
||||
RuntimeConfig,
|
||||
} from '../../index';
|
||||
import { ServerConfig } from './ServerConfig';
|
||||
import {
|
||||
@ -27,13 +26,13 @@ import {
|
||||
*/
|
||||
|
||||
export class AuthenticatedFileResourceStoreConfig implements ServerConfig {
|
||||
private readonly runtimeConfig: RuntimeConfig;
|
||||
public base: string;
|
||||
public store: ResourceStore;
|
||||
|
||||
public constructor(runtimeConfig: RuntimeConfig) {
|
||||
this.runtimeConfig = runtimeConfig;
|
||||
public constructor(base: string, rootFilepath: string) {
|
||||
this.base = base;
|
||||
this.store = getConvertingStore(
|
||||
getFileResourceStore(runtimeConfig),
|
||||
getFileResourceStore(base, rootFilepath),
|
||||
[ new QuadToRdfConverter(),
|
||||
new RdfToQuadConverter() ],
|
||||
);
|
||||
@ -50,7 +49,7 @@ export class AuthenticatedFileResourceStoreConfig implements ServerConfig {
|
||||
const operationHandler = getOperationHandler(this.store);
|
||||
|
||||
const responseWriter = new BasicResponseWriter();
|
||||
const authorizer = getWebAclAuthorizer(this.store, this.runtimeConfig.base);
|
||||
const authorizer = getWebAclAuthorizer(this.store, this.base);
|
||||
|
||||
const handler = new AuthenticatedLdpHandler({
|
||||
requestParser,
|
||||
|
@ -9,7 +9,6 @@ import {
|
||||
RawBodyParser,
|
||||
RdfToQuadConverter,
|
||||
ResourceStore,
|
||||
RuntimeConfig,
|
||||
UnsecureWebIdExtractor,
|
||||
} from '../../index';
|
||||
import { ServerConfig } from './ServerConfig';
|
||||
@ -25,9 +24,9 @@ import { getFileResourceStore, getOperationHandler, getConvertingStore, getBasic
|
||||
export class FileResourceStoreConfig implements ServerConfig {
|
||||
public store: ResourceStore;
|
||||
|
||||
public constructor(runtimeConfig: RuntimeConfig) {
|
||||
public constructor(base: string, rootFilepath: string) {
|
||||
this.store = getConvertingStore(
|
||||
getFileResourceStore(runtimeConfig),
|
||||
getFileResourceStore(base, rootFilepath),
|
||||
[ new QuadToRdfConverter(), new RdfToQuadConverter() ],
|
||||
);
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import {
|
||||
RepresentationConvertingStore,
|
||||
ResourceStore,
|
||||
ResponseDescription,
|
||||
RuntimeConfig,
|
||||
SingleThreadedResourceLocker,
|
||||
SparqlUpdatePatchHandler,
|
||||
UrlBasedAclManager,
|
||||
@ -32,26 +31,24 @@ import {
|
||||
} from '../../index';
|
||||
import { ExtensionBasedMapper } from '../../src/storage/ExtensionBasedMapper';
|
||||
|
||||
const BASE = 'http://test.com';
|
||||
export const BASE = 'http://test.com';
|
||||
|
||||
/**
|
||||
* Creates a RuntimeConfig with its rootFilePath set based on the given subfolder.
|
||||
* @param subfolder - Folder to use in the global testData folder.
|
||||
*/
|
||||
export const getRuntimeConfig = (subfolder: string): RuntimeConfig => new RuntimeConfig({
|
||||
base: BASE,
|
||||
rootFilepath: join(__dirname, '../testData', subfolder),
|
||||
});
|
||||
export const getRootFilePath = (subfolder: string): string => join(__dirname, '../testData', subfolder);
|
||||
|
||||
/**
|
||||
* Gives a file resource store based on (default) runtime config.
|
||||
* @param runtimeConfig - Optional runtime config.
|
||||
* @param base - Base URL.
|
||||
* @param rootFilepath - The root file path.
|
||||
*
|
||||
* @returns The file resource store.
|
||||
*/
|
||||
export const getFileResourceStore = (runtimeConfig: RuntimeConfig): FileResourceStore =>
|
||||
export const getFileResourceStore = (base: string, rootFilepath: string): FileResourceStore =>
|
||||
new FileResourceStore(
|
||||
new ExtensionBasedMapper(runtimeConfig),
|
||||
new ExtensionBasedMapper(base, rootFilepath),
|
||||
new InteractionController(),
|
||||
new MetadataController(),
|
||||
);
|
||||
@ -63,7 +60,7 @@ export const getFileResourceStore = (runtimeConfig: RuntimeConfig): FileResource
|
||||
* @returns The in memory resource store.
|
||||
*/
|
||||
export const getInMemoryResourceStore = (base = BASE): InMemoryResourceStore =>
|
||||
new InMemoryResourceStore(new RuntimeConfig({ base }));
|
||||
new InMemoryResourceStore(base);
|
||||
|
||||
/**
|
||||
* Gives a converting store given some converters.
|
||||
@ -138,6 +135,6 @@ export const getBasicRequestParser = (bodyParsers: BodyParser[] = []): BasicRequ
|
||||
*/
|
||||
export const getWebAclAuthorizer =
|
||||
(store: ResourceStore, base = BASE, aclManager = new UrlBasedAclManager()): WebAclAuthorizer => {
|
||||
const containerManager = new UrlContainerManager(new RuntimeConfig({ base }));
|
||||
const containerManager = new UrlContainerManager(base);
|
||||
return new WebAclAuthorizer(aclManager, containerManager, store);
|
||||
};
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { copyFileSync, mkdirSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
import * as rimraf from 'rimraf';
|
||||
import { HttpHandler, ResourceStore, RuntimeConfig } from '../../index';
|
||||
import { HttpHandler, ResourceStore } from '../../index';
|
||||
import { ensureTrailingSlash } from '../../src/util/Util';
|
||||
import { AuthenticatedFileResourceStoreConfig } from '../configs/AuthenticatedFileResourceStoreConfig';
|
||||
import { getRuntimeConfig } from '../configs/Util';
|
||||
import { BASE, getRootFilePath } from '../configs/Util';
|
||||
import { AclTestHelper, FileTestHelper } from '../util/TestHelpers';
|
||||
|
||||
describe('A server using a AuthenticatedFileResourceStore', (): void => {
|
||||
@ -12,24 +13,23 @@ describe('A server using a AuthenticatedFileResourceStore', (): void => {
|
||||
let store: ResourceStore;
|
||||
let aclHelper: AclTestHelper;
|
||||
let fileHelper: FileTestHelper;
|
||||
let runtimeConfig: RuntimeConfig;
|
||||
let rootFilePath: string;
|
||||
|
||||
beforeAll(async(): Promise<void> => {
|
||||
runtimeConfig = getRuntimeConfig('AuthenticatedFileResourceStore');
|
||||
config = new AuthenticatedFileResourceStoreConfig(runtimeConfig);
|
||||
const { base, rootFilepath } = runtimeConfig;
|
||||
rootFilePath = getRootFilePath('AuthenticatedFileResourceStore');
|
||||
config = new AuthenticatedFileResourceStoreConfig(BASE, rootFilePath);
|
||||
handler = config.getHttpHandler();
|
||||
({ store } = config);
|
||||
aclHelper = new AclTestHelper(store, base);
|
||||
fileHelper = new FileTestHelper(handler, new URL('http://test.com/'));
|
||||
aclHelper = new AclTestHelper(store, ensureTrailingSlash(BASE));
|
||||
fileHelper = new FileTestHelper(handler, new URL(ensureTrailingSlash(BASE)));
|
||||
|
||||
// Make sure the root directory exists
|
||||
mkdirSync(rootFilepath, { recursive: true });
|
||||
copyFileSync(join(__dirname, '../assets/permanent.txt'), `${rootFilepath}/permanent.txt`);
|
||||
mkdirSync(rootFilePath, { recursive: true });
|
||||
copyFileSync(join(__dirname, '../assets/permanent.txt'), `${rootFilePath}/permanent.txt`);
|
||||
});
|
||||
|
||||
afterAll(async(): Promise<void> => {
|
||||
rimraf.sync(runtimeConfig.rootFilepath, { glob: false });
|
||||
rimraf.sync(rootFilePath, { glob: false });
|
||||
});
|
||||
|
||||
describe('with acl', (): void => {
|
||||
|
@ -1,26 +1,25 @@
|
||||
import * as rimraf from 'rimraf';
|
||||
import { RuntimeConfig } from '../../src/init/RuntimeConfig';
|
||||
import { HttpHandler } from '../../src/server/HttpHandler';
|
||||
import { FileResourceStoreConfig } from '../configs/FileResourceStoreConfig';
|
||||
import { getRuntimeConfig } from '../configs/Util';
|
||||
import { BASE, getRootFilePath } from '../configs/Util';
|
||||
import { FileTestHelper } from '../util/TestHelpers';
|
||||
|
||||
describe('A server using a FileResourceStore', (): void => {
|
||||
describe('without acl', (): void => {
|
||||
let rootFilePath: string;
|
||||
let config: FileResourceStoreConfig;
|
||||
let handler: HttpHandler;
|
||||
let fileHelper: FileTestHelper;
|
||||
let runtimeConfig: RuntimeConfig;
|
||||
|
||||
beforeAll(async(): Promise<void> => {
|
||||
runtimeConfig = getRuntimeConfig('FileResourceStore');
|
||||
config = new FileResourceStoreConfig(runtimeConfig);
|
||||
rootFilePath = getRootFilePath('FileResourceStore');
|
||||
config = new FileResourceStoreConfig(BASE, rootFilePath);
|
||||
handler = config.getHttpHandler();
|
||||
fileHelper = new FileTestHelper(handler, new URL(runtimeConfig.base));
|
||||
fileHelper = new FileTestHelper(handler, new URL(BASE));
|
||||
});
|
||||
|
||||
afterAll(async(): Promise<void> => {
|
||||
rimraf.sync(runtimeConfig.rootFilepath, { glob: false });
|
||||
rimraf.sync(rootFilePath, { glob: false });
|
||||
});
|
||||
|
||||
it('can add a file to the store, read it and delete it.', async():
|
||||
|
@ -1,48 +0,0 @@
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
|
||||
describe('RuntimeConfig', (): void => {
|
||||
it('handles undefined args.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig();
|
||||
expect(config.port).toEqual(3000);
|
||||
expect(config.base).toEqual('http://localhost:3000/');
|
||||
});
|
||||
|
||||
it('handles empty args.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({});
|
||||
expect(config.port).toEqual(3000);
|
||||
expect(config.base).toEqual('http://localhost:3000/');
|
||||
});
|
||||
|
||||
it('handles args with port.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({ port: 1234 });
|
||||
expect(config.port).toEqual(1234);
|
||||
expect(config.base).toEqual('http://localhost:1234/');
|
||||
});
|
||||
|
||||
it('handles args with base.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({ base: 'http://example.org/' });
|
||||
expect(config.port).toEqual(3000);
|
||||
expect(config.base).toEqual('http://example.org/');
|
||||
});
|
||||
|
||||
it('handles args with port and base.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({ port: 1234, base: 'http://example.org/' });
|
||||
expect(config.port).toEqual(1234);
|
||||
expect(config.base).toEqual('http://example.org/');
|
||||
});
|
||||
|
||||
it('handles resetting data.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({});
|
||||
expect(config.port).toEqual(3000);
|
||||
expect(config.base).toEqual('http://localhost:3000/');
|
||||
|
||||
config.reset({ port: 1234, base: 'http://example.org/' });
|
||||
expect(config.port).toEqual(1234);
|
||||
expect(config.base).toEqual('http://example.org/');
|
||||
});
|
||||
|
||||
it('ensures trailing slash in base.', async(): Promise<void> => {
|
||||
const config = new RuntimeConfig({ base: 'http://example.org' });
|
||||
expect(config.base).toEqual('http://example.org/');
|
||||
});
|
||||
});
|
@ -1,4 +1,3 @@
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
import { Setup } from '../../../src/init/Setup';
|
||||
|
||||
describe('Setup', (): void => {
|
||||
@ -16,7 +15,7 @@ describe('Setup', (): void => {
|
||||
httpServer = {
|
||||
listen: jest.fn(),
|
||||
};
|
||||
setup = new Setup(httpServer, store, aclManager, new RuntimeConfig());
|
||||
setup = new Setup(httpServer, store, aclManager, 'http://localhost:3000/', 3000);
|
||||
});
|
||||
|
||||
it('starts an HTTP server.', async(): Promise<void> => {
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
import { ExtensionBasedMapper } from '../../../src/storage/ExtensionBasedMapper';
|
||||
|
||||
describe('An ExtensionBasedMapper', (): void => {
|
||||
const base = 'http://test.com/';
|
||||
const rootFilepath = 'uploads/';
|
||||
const resourceMapper = new ExtensionBasedMapper(new RuntimeConfig({ base, rootFilepath }));
|
||||
const resourceMapper = new ExtensionBasedMapper(base, rootFilepath);
|
||||
|
||||
it('returns the correct url of a file.', async(): Promise<void> => {
|
||||
let result = resourceMapper.mapFilePathToUrl(`${rootFilepath}test.txt`);
|
||||
|
@ -5,7 +5,6 @@ import { literal, namedNode, quad as quadRDF, triple } from '@rdfjs/data-model';
|
||||
import arrayifyStream from 'arrayify-stream';
|
||||
import { DataFactory } from 'n3';
|
||||
import streamifyArray from 'streamify-array';
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
import { Representation } from '../../../src/ldp/representation/Representation';
|
||||
import { RepresentationMetadata } from '../../../src/ldp/representation/RepresentationMetadata';
|
||||
import { ExtensionBasedMapper } from '../../../src/storage/ExtensionBasedMapper';
|
||||
@ -55,7 +54,7 @@ describe('A FileResourceStore', (): void => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
store = new FileResourceStore(
|
||||
new ExtensionBasedMapper(new RuntimeConfig({ base, rootFilepath })),
|
||||
new ExtensionBasedMapper(base, rootFilepath),
|
||||
new InteractionController(),
|
||||
new MetadataController(),
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Readable } from 'stream';
|
||||
import streamifyArray from 'streamify-array';
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
import { Representation } from '../../../src/ldp/representation/Representation';
|
||||
import { RepresentationMetadata } from '../../../src/ldp/representation/RepresentationMetadata';
|
||||
import { InMemoryResourceStore } from '../../../src/storage/InMemoryResourceStore';
|
||||
@ -15,7 +14,7 @@ describe('A InMemoryResourceStore', (): void => {
|
||||
const dataString = '<http://test.com/s> <http://test.com/p> <http://test.com/o>.';
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
store = new InMemoryResourceStore(new RuntimeConfig({ base }));
|
||||
store = new InMemoryResourceStore(base);
|
||||
|
||||
representation = {
|
||||
binary: true,
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
|
||||
import { UrlContainerManager } from '../../../src/storage/UrlContainerManager';
|
||||
|
||||
describe('An UrlContainerManager', (): void => {
|
||||
it('returns the parent URl for a single call.', async(): Promise<void> => {
|
||||
const manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
|
||||
const manager = new UrlContainerManager('http://test.com/foo/');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo/bar' }))
|
||||
.resolves.toEqual({ path: 'http://test.com/foo/' });
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo/bar/' }))
|
||||
@ -11,13 +10,13 @@ describe('An UrlContainerManager', (): void => {
|
||||
});
|
||||
|
||||
it('errors when getting the container of root.', async(): Promise<void> => {
|
||||
let manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
|
||||
let manager = new UrlContainerManager('http://test.com/foo/');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo/' }))
|
||||
.rejects.toThrow('Root does not have a container.');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo' }))
|
||||
.rejects.toThrow('Root does not have a container.');
|
||||
|
||||
manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo' }));
|
||||
manager = new UrlContainerManager('http://test.com/foo/');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo/' }))
|
||||
.rejects.toThrow('Root does not have a container.');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/foo' }))
|
||||
@ -25,7 +24,7 @@ describe('An UrlContainerManager', (): void => {
|
||||
});
|
||||
|
||||
it('errors when the root of an URl is reached that does not match the input root.', async(): Promise<void> => {
|
||||
const manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
|
||||
const manager = new UrlContainerManager('http://test.com/foo/');
|
||||
await expect(manager.getContainer({ path: 'http://test.com/' }))
|
||||
.rejects.toThrow('URL root reached.');
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user