Expose auth repos in context; create routes commands
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
9796a7277e
commit
36b451c32b
@ -10,6 +10,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/bcrypt": "^5.0.0",
|
"@types/bcrypt": "^5.0.0",
|
||||||
"@types/busboy": "^0.2.3",
|
"@types/busboy": "^0.2.3",
|
||||||
|
"@types/cli-table": "^0.3.0",
|
||||||
"@types/mkdirp": "^1.0.1",
|
"@types/mkdirp": "^1.0.1",
|
||||||
"@types/negotiator": "^0.6.1",
|
"@types/negotiator": "^0.6.1",
|
||||||
"@types/node": "^14.14.37",
|
"@types/node": "^14.14.37",
|
||||||
@ -21,6 +22,7 @@
|
|||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"bcrypt": "^5.0.1",
|
"bcrypt": "^5.0.1",
|
||||||
"busboy": "^0.3.1",
|
"busboy": "^0.3.1",
|
||||||
|
"cli-table": "^0.3.6",
|
||||||
"colors": "^1.4.0",
|
"colors": "^1.4.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"mkdirp": "^1.0.4",
|
"mkdirp": "^1.0.4",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/bcrypt': 5.0.0
|
'@types/bcrypt': 5.0.0
|
||||||
'@types/busboy': 0.2.3
|
'@types/busboy': 0.2.3
|
||||||
|
'@types/cli-table': 0.3.0
|
||||||
'@types/mkdirp': 1.0.1
|
'@types/mkdirp': 1.0.1
|
||||||
'@types/negotiator': 0.6.1
|
'@types/negotiator': 0.6.1
|
||||||
'@types/node': 14.14.37
|
'@types/node': 14.14.37
|
||||||
@ -12,6 +13,7 @@ dependencies:
|
|||||||
'@types/uuid': 8.3.0
|
'@types/uuid': 8.3.0
|
||||||
bcrypt: 5.0.1
|
bcrypt: 5.0.1
|
||||||
busboy: 0.3.1
|
busboy: 0.3.1
|
||||||
|
cli-table: 0.3.6
|
||||||
colors: 1.4.0
|
colors: 1.4.0
|
||||||
dotenv: 8.2.0
|
dotenv: 8.2.0
|
||||||
mkdirp: 1.0.4
|
mkdirp: 1.0.4
|
||||||
@ -138,6 +140,10 @@ packages:
|
|||||||
dev: false
|
dev: false
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha1-ZpetKYcyRsUw8Jo/9aQIYYJCMNU=
|
integrity: sha1-ZpetKYcyRsUw8Jo/9aQIYYJCMNU=
|
||||||
|
/@types/cli-table/0.3.0:
|
||||||
|
dev: false
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-QnZUISJJXyhyD6L1e5QwXDV/A5i2W1/gl6D6YMc8u0ncPepbv/B4w3S+izVvtAg60m6h+JP09+Y/0zF2mojlFQ==
|
||||||
/@types/glob/7.1.3:
|
/@types/glob/7.1.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/minimatch': 3.0.4
|
'@types/minimatch': 3.0.4
|
||||||
@ -554,6 +560,14 @@ packages:
|
|||||||
node: '>=10'
|
node: '>=10'
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
|
||||||
|
/cli-table/0.3.6:
|
||||||
|
dependencies:
|
||||||
|
colors: 1.0.3
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>= 0.2.0'
|
||||||
|
resolution:
|
||||||
|
integrity: sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ==
|
||||||
/code-point-at/1.1.0:
|
/code-point-at/1.1.0:
|
||||||
dev: false
|
dev: false
|
||||||
engines:
|
engines:
|
||||||
@ -582,6 +596,12 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
resolution:
|
resolution:
|
||||||
integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
/colors/1.0.3:
|
||||||
|
dev: false
|
||||||
|
engines:
|
||||||
|
node: '>=0.1.90'
|
||||||
|
resolution:
|
||||||
|
integrity: sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
|
||||||
/colors/1.4.0:
|
/colors/1.4.0:
|
||||||
dev: false
|
dev: false
|
||||||
engines:
|
engines:
|
||||||
@ -2214,6 +2234,7 @@ packages:
|
|||||||
specifiers:
|
specifiers:
|
||||||
'@types/bcrypt': ^5.0.0
|
'@types/bcrypt': ^5.0.0
|
||||||
'@types/busboy': ^0.2.3
|
'@types/busboy': ^0.2.3
|
||||||
|
'@types/cli-table': ^0.3.0
|
||||||
'@types/mkdirp': ^1.0.1
|
'@types/mkdirp': ^1.0.1
|
||||||
'@types/negotiator': ^0.6.1
|
'@types/negotiator': ^0.6.1
|
||||||
'@types/node': ^14.14.37
|
'@types/node': ^14.14.37
|
||||||
@ -2227,6 +2248,7 @@ specifiers:
|
|||||||
'@typescript-eslint/parser': ^4.26.0
|
'@typescript-eslint/parser': ^4.26.0
|
||||||
bcrypt: ^5.0.1
|
bcrypt: ^5.0.1
|
||||||
busboy: ^0.3.1
|
busboy: ^0.3.1
|
||||||
|
cli-table: ^0.3.6
|
||||||
colors: ^1.4.0
|
colors: ^1.4.0
|
||||||
dotenv: ^8.2.0
|
dotenv: ^8.2.0
|
||||||
eslint: ^7.27.0
|
eslint: ^7.27.0
|
||||||
|
@ -24,6 +24,10 @@ export class Authentication extends Unit {
|
|||||||
this.middleware.registerNamespace('@auth', this.getMiddlewareResolver())
|
this.middleware.registerNamespace('@auth', this.getMiddlewareResolver())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the canonical namespace resolver for auth middleware.
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
protected getMiddlewareResolver(): CanonicalResolver<StaticClass<Middleware, Instantiable<Middleware>>> {
|
protected getMiddlewareResolver(): CanonicalResolver<StaticClass<Middleware, Instantiable<Middleware>>> {
|
||||||
return (key: string) => {
|
return (key: string) => {
|
||||||
return ({
|
return ({
|
||||||
|
@ -19,7 +19,7 @@ export abstract class SecurityContext {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
/** The repository from which to draw users. */
|
/** The repository from which to draw users. */
|
||||||
protected readonly repository: AuthenticatableRepository,
|
public readonly repository: AuthenticatableRepository,
|
||||||
|
|
||||||
/** The name of this context. */
|
/** The name of this context. */
|
||||||
public readonly name: string,
|
public readonly name: string,
|
||||||
|
@ -14,7 +14,7 @@ export class SessionSecurityContext extends SecurityContext {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
/** The repository from which to draw users. */
|
/** The repository from which to draw users. */
|
||||||
protected readonly repository: AuthenticatableRepository,
|
public readonly repository: AuthenticatableRepository,
|
||||||
) {
|
) {
|
||||||
super(repository, 'session')
|
super(repository, 'session')
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import {AuthenticatableRepository} from '../types'
|
|||||||
import {SessionSecurityContext} from '../contexts/SessionSecurityContext'
|
import {SessionSecurityContext} from '../contexts/SessionSecurityContext'
|
||||||
import {SecurityContext} from '../SecurityContext'
|
import {SecurityContext} from '../SecurityContext'
|
||||||
import {ORMUserRepository} from '../orm/ORMUserRepository'
|
import {ORMUserRepository} from '../orm/ORMUserRepository'
|
||||||
import {AuthConfig} from '../config'
|
import {AuthConfig, AuthenticatableRepositories} from '../config'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects a SessionSecurityContext into the request and attempts to
|
* Injects a SessionSecurityContext into the request and attempts to
|
||||||
@ -29,6 +29,7 @@ export class SessionAuthMiddleware extends Middleware {
|
|||||||
*/
|
*/
|
||||||
protected getRepository(): AuthenticatableRepository {
|
protected getRepository(): AuthenticatableRepository {
|
||||||
const config: AuthConfig | undefined = this.config.get('auth')
|
const config: AuthConfig | undefined = this.config.get('auth')
|
||||||
return this.make<AuthenticatableRepository>(config?.repositories?.session ?? ORMUserRepository)
|
const repo: typeof AuthenticatableRepository = AuthenticatableRepositories[config?.repositories?.session ?? 'orm']
|
||||||
|
return this.make<AuthenticatableRepository>(repo ?? ORMUserRepository)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
71
src/cli/directive/RouteDirective.ts
Normal file
71
src/cli/directive/RouteDirective.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import {Directive, OptionDefinition} from '../Directive'
|
||||||
|
import {Inject, Injectable} from '../../di'
|
||||||
|
import {Routing} from '../../service/Routing'
|
||||||
|
import Table = require('cli-table')
|
||||||
|
import {RouteHandler} from '../../http/routing/Route'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RouteDirective extends Directive {
|
||||||
|
@Inject()
|
||||||
|
protected readonly routing!: Routing
|
||||||
|
|
||||||
|
getDescription(): string {
|
||||||
|
return 'Get information about a specific route'
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeywords(): string | string[] {
|
||||||
|
return ['route']
|
||||||
|
}
|
||||||
|
|
||||||
|
getOptions(): OptionDefinition[] {
|
||||||
|
return [
|
||||||
|
'{route} | the path of the route',
|
||||||
|
'--method -m {value} | the HTTP method of the route',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(): Promise<void> {
|
||||||
|
const method: string | undefined = this.option('method')
|
||||||
|
?.toLowerCase()
|
||||||
|
?.trim()
|
||||||
|
|
||||||
|
const route: string = this.option('route')
|
||||||
|
.toLowerCase()
|
||||||
|
.trim()
|
||||||
|
|
||||||
|
this.routing.getCompiled()
|
||||||
|
.filter(match => match.getRoute().trim() === route && (!method || match.getMethod() === method))
|
||||||
|
.tap(matches => {
|
||||||
|
if ( !matches.length ) {
|
||||||
|
this.error('No matching routes found. (Use `./ex routes` to list)')
|
||||||
|
process.exitCode = 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.each(match => {
|
||||||
|
const pre = match.getMiddlewares()
|
||||||
|
.where('stage', '=', 'pre')
|
||||||
|
.map<[string, string]>(ware => [ware.stage, this.handlerToString(ware.handler)])
|
||||||
|
|
||||||
|
const post = match.getMiddlewares()
|
||||||
|
.where('stage', '=', 'post')
|
||||||
|
.map<[string, string]>(ware => [ware.stage, this.handlerToString(ware.handler)])
|
||||||
|
|
||||||
|
const maxLen = match.getMiddlewares().max(ware => this.handlerToString(ware.handler).length)
|
||||||
|
|
||||||
|
const table = new Table({
|
||||||
|
head: ['Stage', 'Handler'],
|
||||||
|
colWidths: [10, Math.max(maxLen, match.getDisplayableHandler().length) + 2],
|
||||||
|
})
|
||||||
|
|
||||||
|
table.push(...pre.toArray())
|
||||||
|
table.push(['handler', match.getDisplayableHandler()])
|
||||||
|
table.push(...post.toArray())
|
||||||
|
|
||||||
|
this.info(`\nRoute: ${match}\n\n${table}`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
protected handlerToString(handler: RouteHandler): string {
|
||||||
|
return typeof handler === 'string' ? handler : '(anonymous function)'
|
||||||
|
}
|
||||||
|
}
|
33
src/cli/directive/RoutesDirective.ts
Normal file
33
src/cli/directive/RoutesDirective.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import {Directive} from '../Directive'
|
||||||
|
import {Inject, Injectable} from '../../di'
|
||||||
|
import {Routing} from '../../service/Routing'
|
||||||
|
import Table = require('cli-table')
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RoutesDirective extends Directive {
|
||||||
|
@Inject()
|
||||||
|
protected readonly routing!: Routing
|
||||||
|
|
||||||
|
getDescription(): string {
|
||||||
|
return 'List routes registered in the application'
|
||||||
|
}
|
||||||
|
|
||||||
|
getKeywords(): string | string[] {
|
||||||
|
return ['routes']
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(): Promise<void> {
|
||||||
|
const maxRouteLength = this.routing.getCompiled().max(route => String(route).length)
|
||||||
|
const maxHandlerLength = this.routing.getCompiled().max(route => route.getDisplayableHandler().length)
|
||||||
|
const rows = this.routing.getCompiled().map<[string, string]>(route => [String(route), route.getDisplayableHandler()])
|
||||||
|
|
||||||
|
const table = new Table({
|
||||||
|
head: ['Route', 'Handler'],
|
||||||
|
colWidths: [maxRouteLength + 2, maxHandlerLength + 2],
|
||||||
|
})
|
||||||
|
|
||||||
|
table.push(...rows.toArray())
|
||||||
|
|
||||||
|
this.info('\n' + table)
|
||||||
|
}
|
||||||
|
}
|
@ -34,6 +34,7 @@ export class ShellDirective extends Directive {
|
|||||||
async handle(): Promise<void> {
|
async handle(): Promise<void> {
|
||||||
const state: any = {
|
const state: any = {
|
||||||
app: this.app(),
|
app: this.app(),
|
||||||
|
lib: await import('../../index'),
|
||||||
make: (target: DependencyKey, ...parameters: any[]) => this.make(target, ...parameters),
|
make: (target: DependencyKey, ...parameters: any[]) => this.make(target, ...parameters),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import {Directive} from '../Directive'
|
|||||||
import {ShellDirective} from '../directive/ShellDirective'
|
import {ShellDirective} from '../directive/ShellDirective'
|
||||||
import {TemplateDirective} from '../directive/TemplateDirective'
|
import {TemplateDirective} from '../directive/TemplateDirective'
|
||||||
import {RunDirective} from '../directive/RunDirective'
|
import {RunDirective} from '../directive/RunDirective'
|
||||||
|
import {RoutesDirective} from '../directive/RoutesDirective'
|
||||||
|
import {RouteDirective} from '../directive/RouteDirective'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit that takes the place of the final unit in the application that handles
|
* Unit that takes the place of the final unit in the application that handles
|
||||||
@ -42,6 +44,8 @@ export class CommandLineApplication extends Unit {
|
|||||||
this.cli.registerDirective(ShellDirective)
|
this.cli.registerDirective(ShellDirective)
|
||||||
this.cli.registerDirective(TemplateDirective)
|
this.cli.registerDirective(TemplateDirective)
|
||||||
this.cli.registerDirective(RunDirective)
|
this.cli.registerDirective(RunDirective)
|
||||||
|
this.cli.registerDirective(RoutesDirective)
|
||||||
|
this.cli.registerDirective(RouteDirective)
|
||||||
|
|
||||||
const argv = process.argv.slice(2)
|
const argv = process.argv.slice(2)
|
||||||
const match = this.cli.getDirectives()
|
const match = this.cli.getDirectives()
|
||||||
|
@ -224,6 +224,34 @@ export class Route extends AppClass {
|
|||||||
super()
|
super()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string-form of the route.
|
||||||
|
*/
|
||||||
|
public getRoute(): string {
|
||||||
|
return this.route
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string-form method of the route.
|
||||||
|
*/
|
||||||
|
public getMethod(): HTTPMethod | HTTPMethod[] {
|
||||||
|
return this.method
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get collection of applied middlewares.
|
||||||
|
*/
|
||||||
|
public getMiddlewares(): Collection<{ stage: 'pre' | 'post', handler: RouteHandler }> {
|
||||||
|
return this.middlewares.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string-form of the route handler.
|
||||||
|
*/
|
||||||
|
public getDisplayableHandler(): string {
|
||||||
|
return typeof this.handler === 'string' ? this.handler : '(anonymous function)'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this route matches the given HTTP verb and request path.
|
* Returns true if this route matches the given HTTP verb and request path.
|
||||||
* @param method
|
* @param method
|
||||||
|
14
src/orm/schema/Schema.ts
Normal file
14
src/orm/schema/Schema.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import {Connection} from '../connection/Connection'
|
||||||
|
import {Awaitable} from '../../util'
|
||||||
|
|
||||||
|
export abstract class Schema {
|
||||||
|
constructor(
|
||||||
|
protected readonly connection: Connection,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public abstract hasTable(name: string): Awaitable<boolean>
|
||||||
|
|
||||||
|
public abstract hasColumn(table: string, name: string): Awaitable<boolean>
|
||||||
|
|
||||||
|
public abstract hasColumns(table: string, name: string[]): Awaitable<boolean>
|
||||||
|
}
|
109
src/orm/schema/TableBuilder.ts
Normal file
109
src/orm/schema/TableBuilder.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import {Pipe} from '../../util'
|
||||||
|
|
||||||
|
export abstract class SchemaBuilderBase {
|
||||||
|
protected shouldDrop: 'yes'|'no'|'exists' = 'no'
|
||||||
|
|
||||||
|
protected shouldRenameTo?: string
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected readonly name: string,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
public drop(): this {
|
||||||
|
this.shouldDrop = 'yes'
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public dropIfExists(): this {
|
||||||
|
this.shouldDrop = 'exists'
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public rename(to: string): this {
|
||||||
|
this.shouldRenameTo = to
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
pipe(): Pipe<this> {
|
||||||
|
return Pipe.wrap<this>(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ColumnBuilder extends SchemaBuilderBase {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IndexBuilder extends SchemaBuilderBase {
|
||||||
|
|
||||||
|
protected fields: Set<string> = new Set<string>()
|
||||||
|
|
||||||
|
protected removedFields: Set<string> = new Set<string>()
|
||||||
|
|
||||||
|
protected shouldBeUnique = false
|
||||||
|
|
||||||
|
protected shouldBePrimary = false
|
||||||
|
|
||||||
|
protected field(name: string): this {
|
||||||
|
this.fields.add(name)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
protected removeField(name: string): this {
|
||||||
|
this.removedFields.add(name)
|
||||||
|
this.fields.delete(name)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
primary(): this {
|
||||||
|
this.shouldBePrimary = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
unique(): this {
|
||||||
|
this.shouldBeUnique = true
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TableBuilder extends SchemaBuilderBase {
|
||||||
|
|
||||||
|
protected columns: {[key: string]: ColumnBuilder} = {}
|
||||||
|
|
||||||
|
protected indexes: {[key: string]: IndexBuilder} = {}
|
||||||
|
|
||||||
|
public dropColumn(name: string): this {
|
||||||
|
this.column(name).drop()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public renameColumn(from: string, to: string): this {
|
||||||
|
this.column(from).rename(to)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public dropIndex(name: string): this {
|
||||||
|
this.index(name).drop()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public renameIndex(from: string, to: string): this {
|
||||||
|
this.index(from).rename(to)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public column(name: string) {
|
||||||
|
if ( !this.columns[name] ) {
|
||||||
|
this.columns[name] = new ColumnBuilder(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.columns[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
public index(name: string) {
|
||||||
|
if ( !this.indexes[name] ) {
|
||||||
|
this.indexes[name] = new IndexBuilder(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.indexes[name]
|
||||||
|
}
|
||||||
|
}
|
@ -56,4 +56,11 @@ export class Routing extends Unit {
|
|||||||
public get path(): UniversalPath {
|
public get path(): UniversalPath {
|
||||||
return this.app().appPath('http', 'routes')
|
return this.app().appPath('http', 'routes')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the collection of compiled routes.
|
||||||
|
*/
|
||||||
|
public getCompiled(): Collection<Route> {
|
||||||
|
return this.compiledRoutes
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user