Commit dc5cb26b authored by Fabrizio Ruggeri's avatar Fabrizio Ruggeri
Browse files

Can work under a subfolder

parent 987a39e9
......@@ -71,24 +71,28 @@ export type CacheOptions =
| NoneCacheOptions;
export interface Config {
/**
* Set this value if caravaggio is served from a subfolder. i.e "/api"
*/
basePath?: string;
/**
* Caravaggio has several caches
*/
caches: {
caches?: {
/**
* OUTPUT CACHE
* Cache for the transformed images.
* Given the same input url and the same transformation options,
* this cache saves the output buffer to avoir re-compute the transformations
*/
output: CacheConfig;
output?: CacheConfig;
/**
* INPUT CACHE
* This cache let you avoid download several time the same input image
* Given the same url, the original image is cached and not re-downloaded
* This accept the same type as the output cache
*/
input: CacheConfig;
input?: CacheConfig;
};
/**
* Define the cache directive sent in the response
......@@ -113,7 +117,7 @@ export interface Config {
/**
* Logger definition. Define how the application should log event
*/
logger: {
logger?: {
/**
* level: The log level. One among: fatal, error, warn, info, debug, trace, silent
* The log will appear from your choosen level and upon, i.e.
......@@ -121,11 +125,11 @@ export interface Config {
* (info -> info, warn, error, fatal)
* pretty: Print a pretty out instead of the json one
*/
options: LoggerOptions;
options?: LoggerOptions;
/**
* destination: Where to stream the log. Can be `stdout`, `stderr` or a file path
* destination: Where to stream the log. Can be `process.stdout`, `process.stderr` or a file path
*/
destination: DestinationStream;
destination?: DestinationStream;
};
/**
* Let you decide how to show errors.
......
import CError from './CError';
class BadRequestError extends CError {
constructor(message: string, docUri: string) {
constructor(message: string, docUri: string | null) {
super(message || 'Bad request error', docUri, 400);
}
}
......
class CError extends Error {
public statusCode: number;
public docUri: string;
public docUri: string | null = null;
constructor(message: string, docUri: string, statusCode = 500) {
constructor(message: string, docUri: string | null, statusCode = 500) {
super(message);
this.statusCode = statusCode;
this.docUri = docUri;
......
......@@ -2,6 +2,6 @@ import BadRequestError from './BadRequestError';
export default class UnknownOperationError extends BadRequestError {
constructor(operation: string) {
super(`Unknown operation "${operation}"`, 'docs.html');
super(`Unknown operation "${operation}"`, null);
}
}
......@@ -6,7 +6,10 @@ let logger: pino.Logger;
const createLogger = (config: Config) => {
if (logger) return logger;
const {
logger: { options, destination },
logger: { options = {}, destination = process.stdout } = {
destination: process.stdout,
options: {},
},
} = config;
logger = pino(options, destination);
......
......@@ -67,13 +67,10 @@ const buildHtmlError: ErrorBuilder = (err, res) => {
<div>
<h1>Error</h1>
<p>${err.message || UNKNOWN_ERROR_MESSAGE}
${
err.docUri !== null
? `<br />See <a target="_blank" href="${buildDocumentationLink(
err.docUri
)}">${buildDocumentationLink(err.docUri)}</a>`
: ''
}</p>
<br />See <a target="_blank" href="${buildDocumentationLink(
err.docUri
)}">${buildDocumentationLink(err.docUri)}</a>
</p>
</div>
</div>
</div>
......@@ -95,12 +92,8 @@ const buildJsonError: ErrorBuilder = (err, res) => {
const buildErrorText: ErrorBuilder = (err, res) => {
res.setHeader('Content-Type', 'text/plain; charset=UTF-8');
return `${err.message || UNKNOWN_ERROR_MESSAGE}${
err.docUri !== null
? `
See ${buildDocumentationLink(err.docUri)}`
: ''
}`;
return `${err.message || UNKNOWN_ERROR_MESSAGE}
See ${buildDocumentationLink(err.docUri)}`;
};
const errorHandler = (context: Context) => {
......
......@@ -5,15 +5,26 @@ import operationParser from '../utils/operationParser';
import pipelineCreator from '../pipeline';
import senderCreator from '../utils/sender';
import CError from '../errors/CError';
import { CacheConfig } from '../config/default';
const defaultOutputCacheConfig: CacheConfig = {
type: 'memory',
options: {
limit: 100,
},
};
const indexRoute = (context: Context) => {
const { logger, config } = context;
const cache = cacheFactory(config.caches.output);
const cache = cacheFactory(config.caches?.output || defaultOutputCacheConfig);
const sender = senderCreator(config);
const pipeline = pipelineCreator(context);
const basePathRegexp = new RegExp(`^${config.basePath}`);
const basePathReplacer = (url: string) =>
config.basePath ? url.replace(basePathRegexp, '') : url;
const handler: AugmentedRequestHandler = async (req, res) => {
const url = req.url || '/';
const url = basePathReplacer(req.url || '/');
const cachedResource = await cache.get(url);
if (cachedResource) {
logger.info(`Cache hit for resource "${url}"`);
......
import { Context } from '..';
import cache from '../caches/cache';
import { CacheConfig } from '../config/default';
const defaultInputCache: CacheConfig = {
type: 'none',
options: null,
};
interface ImageLoader {
/**
......@@ -11,7 +17,7 @@ interface ImageLoader {
const imageLoader = (context: Context): ImageLoader => {
const { logger } = context;
const inputCache = cache(context.config.caches.input);
const inputCache = cache(context.config.caches?.input || defaultInputCache);
return {
get: async (url) => {
const cached = await inputCache.get(url);
......
......@@ -39,8 +39,10 @@ export const isPercentage = (percentage: string | number | null) =>
export const percentageToPixel = (percentage: number, dimension: number) =>
Math.round(percentage * dimension);
export const buildDocumentationLink = (doc: string) =>
`https://caravaggio.ramielcreations.com/docs/${doc}`;
export const buildDocumentationLink = (doc: string | null) =>
doc
? `https://caravaggio.ramielcreations.com/docs/${doc}`
: 'https://caravaggio.ramielcreations.com/docs';
export const compose = (...fns: Function[]) =>
fns.reduce((f, g) => (...args: unknown[]) => f(g(...args)));
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment