Support registering namespaced view directories; add lib() universal path
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
a69c81ed35
commit
7506d6567d
@ -38,12 +38,14 @@
|
||||
"typedoc-plugin-pages-fork": "^0.0.1",
|
||||
"typedoc-plugin-sourcefile-url": "^1.0.6",
|
||||
"typescript": "^4.2.3",
|
||||
"copyfiles": "^2.4.1",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"prebuild": "pnpm run lint",
|
||||
"build": "tsc",
|
||||
"postbuild": "copyfiles -u 1 \"src/resources/**/*\" lib",
|
||||
"app": "tsc && node lib/index.js",
|
||||
"prepare": "pnpm run build",
|
||||
"docs:build": "typedoc --options typedoc.json",
|
||||
|
122
pnpm-lock.yaml
122
pnpm-lock.yaml
@ -15,6 +15,7 @@ dependencies:
|
||||
busboy: 0.3.1
|
||||
cli-table: 0.3.6
|
||||
colors: 1.4.0
|
||||
copyfiles: 2.4.1
|
||||
dotenv: 8.2.0
|
||||
mkdirp: 1.0.4
|
||||
negotiator: 0.6.2
|
||||
@ -383,7 +384,6 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||
/ansi-regex/5.0.0:
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
@ -399,7 +399,6 @@ packages:
|
||||
/ansi-styles/4.3.0:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
@ -568,6 +567,14 @@ packages:
|
||||
node: '>= 0.2.0'
|
||||
resolution:
|
||||
integrity: sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==
|
||||
/cliui/7.0.4:
|
||||
dependencies:
|
||||
string-width: 4.2.2
|
||||
strip-ansi: 6.0.0
|
||||
wrap-ansi: 7.0.0
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
/code-point-at/1.1.0:
|
||||
dev: false
|
||||
engines:
|
||||
@ -583,7 +590,6 @@ packages:
|
||||
/color-convert/2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=7.0.0'
|
||||
resolution:
|
||||
@ -593,7 +599,6 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
/color-name/1.1.4:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
/colors/1.0.3:
|
||||
@ -626,6 +631,19 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==
|
||||
/copyfiles/2.4.1:
|
||||
dependencies:
|
||||
glob: 7.1.7
|
||||
minimatch: 3.0.4
|
||||
mkdirp: 1.0.4
|
||||
noms: 0.0.0
|
||||
through2: 2.0.5
|
||||
untildify: 4.0.0
|
||||
yargs: 16.2.0
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
|
||||
/core-util-is/1.0.2:
|
||||
dev: false
|
||||
resolution:
|
||||
@ -722,7 +740,6 @@ packages:
|
||||
resolution:
|
||||
integrity: sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
|
||||
/emoji-regex/8.0.0:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
/enquirer/2.3.6:
|
||||
@ -733,6 +750,12 @@ packages:
|
||||
node: '>=8.6'
|
||||
resolution:
|
||||
integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==
|
||||
/escalade/3.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=6'
|
||||
resolution:
|
||||
integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
/escape-string-regexp/1.0.5:
|
||||
dev: true
|
||||
engines:
|
||||
@ -986,6 +1009,12 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
|
||||
/get-caller-file/2.0.5:
|
||||
dev: false
|
||||
engines:
|
||||
node: 6.* || 8.* || >= 10.*
|
||||
resolution:
|
||||
integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
/get-intrinsic/1.1.1:
|
||||
dependencies:
|
||||
function-bind: 1.1.1
|
||||
@ -1168,7 +1197,6 @@ packages:
|
||||
resolution:
|
||||
integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
|
||||
/is-fullwidth-code-point/3.0.0:
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
@ -1200,6 +1228,10 @@ packages:
|
||||
node: '>= 0.4'
|
||||
resolution:
|
||||
integrity: sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==
|
||||
/isarray/0.0.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
|
||||
/isarray/1.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
@ -1391,6 +1423,13 @@ packages:
|
||||
node: 4.x || >=6.0.0
|
||||
resolution:
|
||||
integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
/noms/0.0.0:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
readable-stream: 1.0.34
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=
|
||||
/nopt/5.0.0:
|
||||
dependencies:
|
||||
abbrev: 1.1.1
|
||||
@ -1697,6 +1736,15 @@ packages:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
/readable-stream/1.0.34:
|
||||
dependencies:
|
||||
core-util-is: 1.0.2
|
||||
inherits: 2.0.4
|
||||
isarray: 0.0.1
|
||||
string_decoder: 0.10.31
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
|
||||
/readable-stream/2.3.7:
|
||||
dependencies:
|
||||
core-util-is: 1.0.2
|
||||
@ -1737,6 +1785,12 @@ packages:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
|
||||
/require-directory/2.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
/require-from-string/2.0.2:
|
||||
dev: true
|
||||
engines:
|
||||
@ -1913,11 +1967,14 @@ packages:
|
||||
emoji-regex: 8.0.0
|
||||
is-fullwidth-code-point: 3.0.0
|
||||
strip-ansi: 6.0.0
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
|
||||
/string_decoder/0.10.31:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
|
||||
/string_decoder/1.1.1:
|
||||
dependencies:
|
||||
safe-buffer: 5.1.2
|
||||
@ -1941,7 +1998,6 @@ packages:
|
||||
/strip-ansi/6.0.0:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.0
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
@ -1998,6 +2054,13 @@ packages:
|
||||
dev: true
|
||||
resolution:
|
||||
integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
/through2/2.0.5:
|
||||
dependencies:
|
||||
readable-stream: 2.3.7
|
||||
xtend: 4.0.2
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
|
||||
/to-fast-properties/2.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
@ -2144,6 +2207,12 @@ packages:
|
||||
node: '>= 10.0.0'
|
||||
resolution:
|
||||
integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||
/untildify/4.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=8'
|
||||
resolution:
|
||||
integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
|
||||
/uri-js/4.4.1:
|
||||
dependencies:
|
||||
punycode: 2.1.1
|
||||
@ -2209,6 +2278,16 @@ packages:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
|
||||
/wrap-ansi/7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.2
|
||||
strip-ansi: 6.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=10'
|
||||
resolution:
|
||||
integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
/wrappy/1.0.2:
|
||||
resolution:
|
||||
integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
@ -2218,6 +2297,12 @@ packages:
|
||||
node: '>=0.4'
|
||||
resolution:
|
||||
integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
/y18n/5.0.8:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=10'
|
||||
resolution:
|
||||
integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||
/yallist/3.1.1:
|
||||
dev: false
|
||||
resolution:
|
||||
@ -2225,6 +2310,26 @@ packages:
|
||||
/yallist/4.0.0:
|
||||
resolution:
|
||||
integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
/yargs-parser/20.2.9:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=10'
|
||||
resolution:
|
||||
integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
/yargs/16.2.0:
|
||||
dependencies:
|
||||
cliui: 7.0.4
|
||||
escalade: 3.1.1
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
string-width: 4.2.2
|
||||
y18n: 5.0.8
|
||||
yargs-parser: 20.2.9
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=10'
|
||||
resolution:
|
||||
integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
/yn/3.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
@ -2250,6 +2355,7 @@ specifiers:
|
||||
busboy: ^0.3.1
|
||||
cli-table: ^0.3.6
|
||||
colors: ^1.4.0
|
||||
copyfiles: ^2.4.1
|
||||
dotenv: ^8.2.0
|
||||
eslint: ^7.27.0
|
||||
mkdirp: ^1.0.4
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {Instantiable} from './types'
|
||||
import {DependencyKey, Instantiable} from './types'
|
||||
import NamedFactory from './factory/NamedFactory'
|
||||
import {AbstractFactory} from './factory/AbstractFactory'
|
||||
import {Factory} from './factory/Factory'
|
||||
import {ClosureFactory} from './factory/ClosureFactory'
|
||||
|
||||
export class ContainerBlueprint {
|
||||
private static instance?: ContainerBlueprint
|
||||
@ -36,6 +37,16 @@ export class ContainerBlueprint {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a producer function as a ClosureFactory with this container.
|
||||
* @param key
|
||||
* @param producer
|
||||
*/
|
||||
registerProducer(key: DependencyKey, producer: () => any): this {
|
||||
this.factories.push(() => new ClosureFactory(key, producer))
|
||||
return this
|
||||
}
|
||||
|
||||
resolve(): AbstractFactory<any>[] {
|
||||
return this.factories.map(x => x())
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
export * from './util'
|
||||
export * from './lib'
|
||||
export * from './di'
|
||||
|
||||
export * from './event/types'
|
||||
|
8
src/lib.ts
Normal file
8
src/lib.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import {UniversalPath} from './util'
|
||||
|
||||
/**
|
||||
* Get the path to the root of the @extollo/lib package.
|
||||
*/
|
||||
export function lib(): UniversalPath {
|
||||
return new UniversalPath(__dirname)
|
||||
}
|
3
src/resources/views/auth/login.pug
Normal file
3
src/resources/views/auth/login.pug
Normal file
@ -0,0 +1,3 @@
|
||||
html
|
||||
body
|
||||
h1 Extollo Login Page
|
@ -5,6 +5,8 @@ import {Logging} from './Logging'
|
||||
import {Route} from '../http/routing/Route'
|
||||
import {HTTPMethod} from '../http/lifecycle/Request'
|
||||
import {ViewEngineFactory} from '../views/ViewEngineFactory'
|
||||
import {ViewEngine} from '../views/ViewEngine'
|
||||
import {lib} from '../lib'
|
||||
|
||||
/**
|
||||
* Application unit that loads the various route files from `app/http/routes` and pre-compiles the route handlers.
|
||||
@ -18,6 +20,9 @@ export class Routing extends Unit {
|
||||
|
||||
public async up(): Promise<void> {
|
||||
this.app().registerFactory(new ViewEngineFactory())
|
||||
const engine = <ViewEngine> this.make(ViewEngine)
|
||||
this.logging.verbose('Registering @extollo view engine namespace.')
|
||||
engine.registerNamespace('extollo', lib().concat('resources', 'views'))
|
||||
|
||||
for await ( const entry of this.path.walk() ) {
|
||||
if ( !entry.endsWith('.routes.js') ) {
|
||||
|
@ -20,11 +20,8 @@ export class PugViewEngine extends ViewEngine {
|
||||
return compiled(locals)
|
||||
}
|
||||
|
||||
if ( !templateName.endsWith('.pug') ) {
|
||||
templateName += '.pug'
|
||||
}
|
||||
const filePath = this.path.concat(...templateName.split(':'))
|
||||
compiled = pug.compileFile(filePath.toLocal, this.getOptions())
|
||||
const filePath = this.resolveName(templateName)
|
||||
compiled = pug.compileFile(filePath.toLocal, this.getOptions(templateName))
|
||||
|
||||
this.compileCache[templateName] = compiled
|
||||
return compiled(locals)
|
||||
@ -34,9 +31,9 @@ export class PugViewEngine extends ViewEngine {
|
||||
* Get the object of options passed to Pug's compile methods.
|
||||
* @protected
|
||||
*/
|
||||
protected getOptions(): pug.Options {
|
||||
protected getOptions(templateName?: string): pug.Options {
|
||||
return {
|
||||
basedir: this.path.toLocal,
|
||||
basedir: templateName ? this.resolveBasePath(templateName).toLocal : this.path.toLocal,
|
||||
debug: this.debug,
|
||||
compileDebug: this.debug,
|
||||
globals: [],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {AppClass} from '../lifecycle/AppClass'
|
||||
import {Config} from '../service/Config'
|
||||
import {Container} from '../di'
|
||||
import {UniversalPath} from '../util'
|
||||
import {ErrorWithContext, UniversalPath} from '../util'
|
||||
|
||||
/**
|
||||
* Abstract base class for rendering views via different view engines.
|
||||
@ -11,6 +11,8 @@ export abstract class ViewEngine extends AppClass {
|
||||
|
||||
protected readonly debug: boolean
|
||||
|
||||
protected readonly namespaces: {[key: string]: UniversalPath} = {}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.config = Container.getContainer().make(Config)
|
||||
@ -38,4 +40,53 @@ export abstract class ViewEngine extends AppClass {
|
||||
* @param locals
|
||||
*/
|
||||
public abstract renderByName(templateName: string, locals: {[key: string]: any}): string | Promise<string>
|
||||
|
||||
public registerNamespace(namespace: string, basePath: UniversalPath): this {
|
||||
if ( namespace.startsWith('@') ) {
|
||||
namespace = namespace.substr(1)
|
||||
}
|
||||
|
||||
this.namespaces[namespace] = basePath
|
||||
return this
|
||||
}
|
||||
|
||||
public resolveName(templateName: string): UniversalPath {
|
||||
let path = this.path
|
||||
if ( templateName.startsWith('@') ) {
|
||||
const [namespace, ...parts] = templateName.split(':')
|
||||
path = this.namespaces[namespace.substr(1)]
|
||||
|
||||
if ( !path ) {
|
||||
throw new ErrorWithContext('Invalid template namespace: ' + namespace, {
|
||||
namespace,
|
||||
templateName,
|
||||
})
|
||||
}
|
||||
|
||||
templateName = parts.join(':')
|
||||
}
|
||||
|
||||
if ( !templateName.endsWith('.pug') ) {
|
||||
templateName += '.pug'
|
||||
}
|
||||
|
||||
return path.concat(...templateName.split(':'))
|
||||
}
|
||||
|
||||
public resolveBasePath(templateName: string): UniversalPath {
|
||||
let path = this.path
|
||||
if ( templateName.startsWith('@') ) {
|
||||
const [namespace] = templateName.split(':')
|
||||
path = this.namespaces[namespace.substr(1)]
|
||||
|
||||
if ( !path ) {
|
||||
throw new ErrorWithContext('Invalid template namespace: ' + namespace, {
|
||||
namespace,
|
||||
templateName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user