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 {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> {
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
}

View File

@ -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)
}

View File

@ -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<boolean>
*/
protected async fileExists(path: string): Promise<boolean> {
protected async fileExists(path: UniversalPath): Promise<boolean> {
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 ) {

View File

@ -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)
}
}

View File

@ -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<T> 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<T> 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<T> extends LifecycleUnit {
* @return 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 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 }
}

View File

@ -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}`)
}
/**

View File

@ -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}`)