diff --git a/lib/src/http/response/FileResponseFactory.ts b/lib/src/http/response/FileResponseFactory.ts index 92b5f70..1d9f34e 100644 --- a/lib/src/http/response/FileResponseFactory.ts +++ b/lib/src/http/response/FileResponseFactory.ts @@ -4,6 +4,7 @@ import {file_server} from '../../external/std.ts' import {HTTPStatus} from '../../const/http.ts' import {Logging} from '../../service/logging/Logging.ts' import {Injectable} from '../../../../di/src/decorator/Injection.ts' +import {PathLike, universal_path} from '../../support/UniversalPath.ts' /** * Response factory to send the contents of a file given its path. @@ -18,7 +19,7 @@ export default class FileResponseFactory extends ResponseFactory { * The path to the file to be sent. * @type string */ - public readonly path: string, + public readonly path: PathLike, ) { super() } /** @@ -29,14 +30,16 @@ export default class FileResponseFactory extends ResponseFactory { public async write(request: Request): Promise { request = await super.write(request) - const content = await file_server.serveFile(request.to_native, this.path) + const path = typeof this.path === 'string' ? universal_path(this.path) : this.path + + const content = await file_server.serveFile(request.to_native, path.to_local) const length = content.headers && content.headers.get('content-length') if ( content.headers && content.body && length ) { request.response.body = content.body request.response.headers.set('Content-Length', length) } else { - this.logger.debug(`Tried to serve file that does not exist: ${this.path}`) + this.logger.debug(`Tried to serve file that does not exist: ${path}`) request.response.status = HTTPStatus.NOT_FOUND } diff --git a/lib/src/http/response/helpers.ts b/lib/src/http/response/helpers.ts index 0ab548d..87bdafa 100644 --- a/lib/src/http/response/helpers.ts +++ b/lib/src/http/response/helpers.ts @@ -10,6 +10,7 @@ import HTTPErrorResponseFactory from './HTTPErrorResponseFactory.ts' import HTTPError from '../../error/HTTPError.ts' import ViewResponseFactory from './ViewResponseFactory.ts' import FileResponseFactory from './FileResponseFactory.ts' +import {PathLike} from '../../support/UniversalPath.ts' /** * Get a new JSON response factory that writes the given object as JSON. @@ -83,6 +84,6 @@ export function view(view: string, data?: any): ViewResponseFactory { * @param {string} path * @return FileResponseFactory */ -export function file(path: string): FileResponseFactory { +export function file(path: PathLike): FileResponseFactory { return make(FileResponseFactory, path) } diff --git a/lib/src/http/system_middleware/StaticServer.ts b/lib/src/http/system_middleware/StaticServer.ts index 3b9ac17..3529ef5 100644 --- a/lib/src/http/system_middleware/StaticServer.ts +++ b/lib/src/http/system_middleware/StaticServer.ts @@ -4,6 +4,7 @@ import {Injectable} from '../../../../di/src/decorator/Injection.ts' import {file, http} from '../response/helpers.ts' import {HTTPStatus} from '../../const/http.ts' import {Logging} from '../../service/logging/Logging.ts' +import {UniversalPath} from "../../support/UniversalPath.ts"; /** * Daton-provided middleware that serves files from a static directory. @@ -51,7 +52,7 @@ export default class StaticServer extends Middleware { * @param {string} rel_file * @return string */ - protected resolve(asset_dir: string, rel_file: string): string { + protected resolve(asset_dir: string, rel_file: string): UniversalPath { return this.app.path(asset_dir, rel_file) } @@ -60,9 +61,9 @@ export default class StaticServer extends Middleware { * @param {string} path * @return Promise */ - protected async fileExists(path: string): Promise { + protected async fileExists(path: UniversalPath): Promise { try { - const stat = await Deno.lstat(path) + const stat = await Deno.lstat(path.to_local) return stat && stat.isFile } catch (e) { if ( e && e instanceof Deno.errors.NotFound ) { diff --git a/lib/src/lifecycle/Application.ts b/lib/src/lifecycle/Application.ts index b95e868..ab8ac3e 100644 --- a/lib/src/lifecycle/Application.ts +++ b/lib/src/lifecycle/Application.ts @@ -10,6 +10,7 @@ import {Collection} from '../collection/Collection.ts' import {path} from '../external/std.ts' import Scaffolding from '../unit/Scaffolding.ts' import {Container} from '../../../di/src/Container.ts' +import {PathLike} from "../support/UniversalPath.ts"; /** * Central class for Daton applications. @@ -115,7 +116,7 @@ export default class Application { * @type string */ get root() { - return this.injector.make(Scaffolding).base_dir + return this.injector.make(Scaffolding).base_path } /** @@ -123,17 +124,7 @@ export default class Application { * @type string */ get app_root() { - let base_dir = this.injector.make(Scaffolding).base_dir - if ( base_dir.startsWith('file://') ) { - base_dir = base_dir.slice(7) - } - - const resolved = path.resolve(base_dir, 'app') - if ( resolved.startsWith('/') ) { - return `file://${resolved}` - } else { - return resolved - } + return this.root.concat('app') } /** @@ -141,18 +132,8 @@ export default class Application { * @param {...string} parts * @return string */ - path(...parts: string[]) { - let root = this.root - if ( root.startsWith('file://') ) { - root = root.slice(7) - } - - const resolved = path.resolve(root, ...parts) - if ( resolved.startsWith('/') ) { - return `file://${resolved}` - } else { - return resolved - } + path(...parts: PathLike[]) { + return this.root.concat(...parts) } /** @@ -160,17 +141,7 @@ export default class Application { * @param {...string} parts * @return string */ - app_path(...parts: string[]) { - let app_root = this.app_root - if ( app_root.startsWith('file://') ) { - app_root = app_root.slice(7) - } - - const resolved = path.resolve(app_root, ...parts) - if ( resolved.startsWith('/') ) { - return `file://${resolved}` - } else { - return resolved - } + app_path(...parts: PathLike[]) { + return this.app_root.concat(...parts) } } diff --git a/lib/src/unit/Canonical.ts b/lib/src/unit/Canonical.ts index d941d38..b322430 100644 --- a/lib/src/unit/Canonical.ts +++ b/lib/src/unit/Canonical.ts @@ -2,6 +2,7 @@ import LifecycleUnit from '../lifecycle/Unit.ts' import {fs, path} from '../external/std.ts' import {Canon} from './Canon.ts' import {Logging} from '../service/logging/Logging.ts' +import {universal_path, UniversalPath} from '../support/UniversalPath.ts' /** * Base type for a canonical definition. @@ -82,8 +83,8 @@ export class Canonical extends LifecycleUnit { * Get the fully-qualified path to the base directory for this unit. * @type string */ - public get path(): string { - return path.resolve(this.base_path) + public get path(): UniversalPath { + return universal_path(this.base_path) } /** @@ -96,7 +97,7 @@ export class Canonical extends LifecycleUnit { public async up() { const logger = this.make(Logging) - for await ( const entry of fs.walk(this.path) ) { + for await ( const entry of fs.walk(this.path.to_local) ) { if ( !entry.isFile || !entry.path.endsWith(this.suffix) ) { if ( entry.isFile ) logger.debug(`Skipping file in canonical path with invalid suffix: ${entry.path}`) continue @@ -125,19 +126,16 @@ export class Canonical extends LifecycleUnit { * @return Promise */ private async _get_canonical_definition(file_path: string): Promise { - const original_name = file_path.replace(this.path, '').substr(1) + const original_name = file_path.replace(this.path.to_local, '').substr(1) const path_regex = new RegExp(path.SEP, 'g') const canonical_name = original_name.replace(path_regex, ':') .split('').reverse().join('') .substr(this.suffix.length) .split('').reverse().join('') - if ( file_path.startsWith('/') ) { - file_path = `file://${file_path}` - } - - this.make(Logging).debug(`Importing from: ${file_path}`) - const imported = await import(file_path) + const file_universal_path = universal_path(file_path) + this.make(Logging).debug(`Importing from: ${file_universal_path}`) + const imported = await import(file_universal_path.to_remote) return { canonical_name, original_name, imported } } diff --git a/lib/src/unit/Scaffolding.ts b/lib/src/unit/Scaffolding.ts index bd7b905..959380d 100644 --- a/lib/src/unit/Scaffolding.ts +++ b/lib/src/unit/Scaffolding.ts @@ -1,15 +1,16 @@ import LifecycleUnit from '../lifecycle/Unit.ts' -import { Unit } from '../lifecycle/decorators.ts' -import { Logging } from '../service/logging/Logging.ts' +import {Unit} from '../lifecycle/decorators.ts' +import {Logging} from '../service/logging/Logging.ts' import StandardLogger from '../service/logging/StandardLogger.ts' -import { isLoggingLevel } from '../service/logging/types.ts' +import {isLoggingLevel} from '../service/logging/types.ts' import Utility from '../service/utility/Utility.ts' -import {container, make} from '../../../di/src/global.ts' +import {make} from '../../../di/src/global.ts' import 'https://deno.land/x/dotenv/load.ts' import { Container } from '../../../di/src/Container.ts' import { Inject } from '../../../di/src/decorator/Injection.ts' import CacheFactory from '../support/CacheFactory.ts' import { path } from '../external/std.ts' +import {universal_path, UniversalPath} from '../support/UniversalPath.ts' /** * Simple helper for loading ENV values with fallback. @@ -31,6 +32,7 @@ export { env } @Unit() export default class Scaffolding extends LifecycleUnit { public base_dir!: string + public base_path!: UniversalPath constructor( protected logger: Logging, @@ -39,7 +41,8 @@ export default class Scaffolding extends LifecycleUnit { base_script: string ) { super() - this.base_dir = path.dirname(base_script)//.replace('file:///', '/') + this.base_dir = path.dirname(base_script) + this.base_path = universal_path(this.base_dir) } /** @@ -55,7 +58,7 @@ export default class Scaffolding extends LifecycleUnit { this.setup_logging() this.register_factories() - this.logger.info(`Base directory: ${this.base_dir}`) + this.logger.info(`Base path: ${this.base_path}`) } /** diff --git a/lib/src/unit/ViewEngine.ts b/lib/src/unit/ViewEngine.ts index 0bd36d0..01ecd07 100644 --- a/lib/src/unit/ViewEngine.ts +++ b/lib/src/unit/ViewEngine.ts @@ -57,7 +57,7 @@ export default class ViewEngine extends LifecycleUnit { throw new ConfigError('app.views.base_dir', base_dir) } - this.template_dir = universal_path(this.app.app_path(base_dir)) + this.template_dir = this.app.app_path(base_dir) this.engine = config this.logger.info(`Determined view engine from config: ${config}`) this.logger.info(`Determined base directory for templates: ${this.template_dir}`)