Replace path with universal paths

This commit is contained in:
Garrett Mills 2020-09-05 11:35:15 -05:00
parent b780d35db1
commit e2efc6f39f
Signed by: garrettmills
GPG Key ID: D2BF5FBA8298F246
7 changed files with 37 additions and 60 deletions

View File

@ -4,6 +4,7 @@ import {file_server} from '../../external/std.ts'
import {HTTPStatus} from '../../const/http.ts' import {HTTPStatus} from '../../const/http.ts'
import {Logging} from '../../service/logging/Logging.ts' import {Logging} from '../../service/logging/Logging.ts'
import {Injectable} from '../../../../di/src/decorator/Injection.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. * 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. * The path to the file to be sent.
* @type string * @type string
*/ */
public readonly path: string, public readonly path: PathLike,
) { super() } ) { super() }
/** /**
@ -29,14 +30,16 @@ export default class FileResponseFactory extends ResponseFactory {
public async write(request: Request): Promise<Request> { public async write(request: Request): Promise<Request> {
request = await super.write(request) 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') const length = content.headers && content.headers.get('content-length')
if ( content.headers && content.body && length ) { if ( content.headers && content.body && length ) {
request.response.body = content.body request.response.body = content.body
request.response.headers.set('Content-Length', length) request.response.headers.set('Content-Length', length)
} else { } 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 request.response.status = HTTPStatus.NOT_FOUND
} }

View File

@ -10,6 +10,7 @@ import HTTPErrorResponseFactory from './HTTPErrorResponseFactory.ts'
import HTTPError from '../../error/HTTPError.ts' import HTTPError from '../../error/HTTPError.ts'
import ViewResponseFactory from './ViewResponseFactory.ts' import ViewResponseFactory from './ViewResponseFactory.ts'
import FileResponseFactory from './FileResponseFactory.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. * 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 * @param {string} path
* @return FileResponseFactory * @return FileResponseFactory
*/ */
export function file(path: string): FileResponseFactory { export function file(path: PathLike): FileResponseFactory {
return make(FileResponseFactory, path) return make(FileResponseFactory, path)
} }

View File

@ -4,6 +4,7 @@ import {Injectable} from '../../../../di/src/decorator/Injection.ts'
import {file, http} from '../response/helpers.ts' import {file, http} from '../response/helpers.ts'
import {HTTPStatus} from '../../const/http.ts' import {HTTPStatus} from '../../const/http.ts'
import {Logging} from '../../service/logging/Logging.ts' import {Logging} from '../../service/logging/Logging.ts'
import {UniversalPath} from "../../support/UniversalPath.ts";
/** /**
* Daton-provided middleware that serves files from a static directory. * Daton-provided middleware that serves files from a static directory.
@ -51,7 +52,7 @@ export default class StaticServer extends Middleware {
* @param {string} rel_file * @param {string} rel_file
* @return string * @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) return this.app.path(asset_dir, rel_file)
} }
@ -60,9 +61,9 @@ export default class StaticServer extends Middleware {
* @param {string} path * @param {string} path
* @return Promise<boolean> * @return Promise<boolean>
*/ */
protected async fileExists(path: string): Promise<boolean> { protected async fileExists(path: UniversalPath): Promise<boolean> {
try { try {
const stat = await Deno.lstat(path) const stat = await Deno.lstat(path.to_local)
return stat && stat.isFile return stat && stat.isFile
} catch (e) { } catch (e) {
if ( e && e instanceof Deno.errors.NotFound ) { if ( e && e instanceof Deno.errors.NotFound ) {

View File

@ -10,6 +10,7 @@ import {Collection} from '../collection/Collection.ts'
import {path} from '../external/std.ts' import {path} from '../external/std.ts'
import Scaffolding from '../unit/Scaffolding.ts' import Scaffolding from '../unit/Scaffolding.ts'
import {Container} from '../../../di/src/Container.ts' import {Container} from '../../../di/src/Container.ts'
import {PathLike} from "../support/UniversalPath.ts";
/** /**
* Central class for Daton applications. * Central class for Daton applications.
@ -115,7 +116,7 @@ export default class Application {
* @type string * @type string
*/ */
get root() { 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 * @type string
*/ */
get app_root() { get app_root() {
let base_dir = this.injector.make(Scaffolding).base_dir return this.root.concat('app')
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
}
} }
/** /**
@ -141,18 +132,8 @@ export default class Application {
* @param {...string} parts * @param {...string} parts
* @return string * @return string
*/ */
path(...parts: string[]) { path(...parts: PathLike[]) {
let root = this.root return this.root.concat(...parts)
if ( root.startsWith('file://') ) {
root = root.slice(7)
}
const resolved = path.resolve(root, ...parts)
if ( resolved.startsWith('/') ) {
return `file://${resolved}`
} else {
return resolved
}
} }
/** /**
@ -160,17 +141,7 @@ export default class Application {
* @param {...string} parts * @param {...string} parts
* @return string * @return string
*/ */
app_path(...parts: string[]) { app_path(...parts: PathLike[]) {
let app_root = this.app_root return this.app_root.concat(...parts)
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
}
} }
} }

View File

@ -2,6 +2,7 @@ import LifecycleUnit from '../lifecycle/Unit.ts'
import {fs, path} from '../external/std.ts' import {fs, path} from '../external/std.ts'
import {Canon} from './Canon.ts' import {Canon} from './Canon.ts'
import {Logging} from '../service/logging/Logging.ts' import {Logging} from '../service/logging/Logging.ts'
import {universal_path, UniversalPath} from '../support/UniversalPath.ts'
/** /**
* Base type for a canonical definition. * Base type for a canonical definition.
@ -82,8 +83,8 @@ export class Canonical<T> extends LifecycleUnit {
* Get the fully-qualified path to the base directory for this unit. * Get the fully-qualified path to the base directory for this unit.
* @type string * @type string
*/ */
public get path(): string { public get path(): UniversalPath {
return path.resolve(this.base_path) return universal_path(this.base_path)
} }
/** /**
@ -96,7 +97,7 @@ export class Canonical<T> extends LifecycleUnit {
public async up() { public async up() {
const logger = this.make(Logging) 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 || !entry.path.endsWith(this.suffix) ) {
if ( entry.isFile ) logger.debug(`Skipping file in canonical path with invalid suffix: ${entry.path}`) if ( entry.isFile ) logger.debug(`Skipping file in canonical path with invalid suffix: ${entry.path}`)
continue continue
@ -125,19 +126,16 @@ export class Canonical<T> extends LifecycleUnit {
* @return Promise<CanonicalDefinition> * @return Promise<CanonicalDefinition>
*/ */
private async _get_canonical_definition(file_path: string): Promise<CanonicalDefinition> { private async _get_canonical_definition(file_path: string): Promise<CanonicalDefinition> {
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 path_regex = new RegExp(path.SEP, 'g')
const canonical_name = original_name.replace(path_regex, ':') const canonical_name = original_name.replace(path_regex, ':')
.split('').reverse().join('') .split('').reverse().join('')
.substr(this.suffix.length) .substr(this.suffix.length)
.split('').reverse().join('') .split('').reverse().join('')
if ( file_path.startsWith('/') ) { const file_universal_path = universal_path(file_path)
file_path = `file://${file_path}` this.make(Logging).debug(`Importing from: ${file_universal_path}`)
} const imported = await import(file_universal_path.to_remote)
this.make(Logging).debug(`Importing from: ${file_path}`)
const imported = await import(file_path)
return { canonical_name, original_name, imported } return { canonical_name, original_name, imported }
} }

View File

@ -4,12 +4,13 @@ import { Logging } from '../service/logging/Logging.ts'
import StandardLogger from '../service/logging/StandardLogger.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 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 'https://deno.land/x/dotenv/load.ts'
import { Container } from '../../../di/src/Container.ts' import { Container } from '../../../di/src/Container.ts'
import { Inject } from '../../../di/src/decorator/Injection.ts' import { Inject } from '../../../di/src/decorator/Injection.ts'
import CacheFactory from '../support/CacheFactory.ts' import CacheFactory from '../support/CacheFactory.ts'
import { path } from '../external/std.ts' import { path } from '../external/std.ts'
import {universal_path, UniversalPath} from '../support/UniversalPath.ts'
/** /**
* Simple helper for loading ENV values with fallback. * Simple helper for loading ENV values with fallback.
@ -31,6 +32,7 @@ export { env }
@Unit() @Unit()
export default class Scaffolding extends LifecycleUnit { export default class Scaffolding extends LifecycleUnit {
public base_dir!: string public base_dir!: string
public base_path!: UniversalPath
constructor( constructor(
protected logger: Logging, protected logger: Logging,
@ -39,7 +41,8 @@ export default class Scaffolding extends LifecycleUnit {
base_script: string base_script: string
) { ) {
super() 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.setup_logging()
this.register_factories() this.register_factories()
this.logger.info(`Base directory: ${this.base_dir}`) this.logger.info(`Base path: ${this.base_path}`)
} }
/** /**

View File

@ -57,7 +57,7 @@ export default class ViewEngine extends LifecycleUnit {
throw new ConfigError('app.views.base_dir', base_dir) 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.engine = config
this.logger.info(`Determined view engine from config: ${config}`) this.logger.info(`Determined view engine from config: ${config}`)
this.logger.info(`Determined base directory for templates: ${this.template_dir}`) this.logger.info(`Determined base directory for templates: ${this.template_dir}`)