@typetron/framework 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -6
- package/.eslintrc-old.js +0 -208
- package/Cache/Cache.ts +0 -13
- package/Cache/Stores/DatabaseStore.ts +0 -120
- package/Cache/Stores/FileStore.ts +0 -69
- package/Cache/Stores/MemoryStore.ts +0 -71
- package/Cache/index.ts +0 -5
- package/Cache/types.ts +0 -4
- package/Container/ClassResolver.ts +0 -106
- package/Container/Container.ts +0 -144
- package/Container/Contracts.ts +0 -3
- package/Container/Decorators.ts +0 -20
- package/Container/Metadata.ts +0 -16
- package/Container/Resolver.ts +0 -27
- package/Container/index.ts +0 -5
- package/Database/Clauses/Where.ts +0 -0
- package/Database/Connection.ts +0 -52
- package/Database/Decorators.ts +0 -142
- package/Database/Drivers/DatabaseDriver.ts +0 -37
- package/Database/Drivers/MySQL/Alter/index.ts +0 -55
- package/Database/Drivers/MySQL/ColumnDefinition.ts +0 -16
- package/Database/Drivers/MySQL/Create.ts +0 -47
- package/Database/Drivers/MySQL/MysqlDriver.ts +0 -123
- package/Database/Drivers/MySQL/Schema.ts +0 -82
- package/Database/Drivers/MySQL/index.ts +0 -13
- package/Database/Drivers/SQL/Schema.ts +0 -73
- package/Database/Drivers/SQL/Statements/Alter.ts +0 -22
- package/Database/Drivers/SQL/Statements/BaseStatement.ts +0 -55
- package/Database/Drivers/SQL/Statements/Delete.ts +0 -20
- package/Database/Drivers/SQL/Statements/Insert.ts +0 -24
- package/Database/Drivers/SQL/Statements/Select.ts +0 -55
- package/Database/Drivers/SQL/Statements/Update.ts +0 -33
- package/Database/Drivers/SQL/index.ts +0 -8
- package/Database/Drivers/SQLite/Create.ts +0 -45
- package/Database/Drivers/SQLite/Schema.ts +0 -54
- package/Database/Drivers/SQLite/SqliteDriver.ts +0 -144
- package/Database/Drivers/SQLite/index.ts +0 -15
- package/Database/Drivers/SchemaContract.ts +0 -11
- package/Database/Drivers/Statement.ts +0 -16
- package/Database/Drivers/index.ts +0 -4
- package/Database/Entity.ts +0 -377
- package/Database/EntityNotFoundError.ts +0 -5
- package/Database/EntityProxyHandler.ts +0 -43
- package/Database/EntityQuery.ts +0 -197
- package/Database/Expression.ts +0 -3
- package/Database/Fields.ts +0 -816
- package/Database/Helpers.ts +0 -12
- package/Database/List.ts +0 -71
- package/Database/Migrations/Migration.ts +0 -10
- package/Database/Migrations/MigrationHistory.ts +0 -20
- package/Database/Migrations/Migrator.ts +0 -122
- package/Database/Migrations/index.ts +0 -3
- package/Database/ORM/BaseRelationship.ts +0 -10
- package/Database/Query.ts +0 -374
- package/Database/Seeders/Seeder.ts +0 -3
- package/Database/Seeders/SeederManager.ts +0 -27
- package/Database/Seeders/index.ts +0 -2
- package/Database/StringExpression.ts +0 -9
- package/Database/Types.ts +0 -165
- package/Database/index.ts +0 -23
- package/Encryption/index.ts +0 -51
- package/Forms/Decorators.ts +0 -29
- package/Forms/Form.ts +0 -70
- package/Forms/FormFields.ts +0 -36
- package/Forms/index.ts +0 -3
- package/Framework/App.ts +0 -10
- package/Framework/Application.ts +0 -118
- package/Framework/Auth/Auth.ts +0 -122
- package/Framework/Auth/Authenticatable.ts +0 -9
- package/Framework/Auth/User.ts +0 -27
- package/Framework/Auth/index.ts +0 -29
- package/Framework/Config/AppConfig.ts +0 -25
- package/Framework/Config/AuthConfig.ts +0 -9
- package/Framework/Config/BaseConfig.ts +0 -9
- package/Framework/Config/CacheConfig.ts +0 -38
- package/Framework/Config/DatabaseConfig.ts +0 -21
- package/Framework/Config/MailConfig.ts +0 -30
- package/Framework/Config/index.ts +0 -6
- package/Framework/Middleware/AuthMiddleware.ts +0 -31
- package/Framework/Middleware/CorsMiddleware.ts +0 -32
- package/Framework/Middleware/StaticAssetsMiddleware.ts +0 -76
- package/Framework/Middleware/index.ts +0 -2
- package/Framework/Provider.ts +0 -9
- package/Framework/Providers/CacheProvider.ts +0 -28
- package/Framework/Providers/DatabaseProvider.ts +0 -36
- package/Framework/Providers/MailProvider.ts +0 -31
- package/Framework/Providers/WebsocketsProvider.ts +0 -120
- package/Framework/Resolvers/AuthResolver.ts +0 -23
- package/Framework/Resolvers/EntityResolver.ts +0 -41
- package/Framework/Resolvers/FormResolver.ts +0 -37
- package/Framework/RootDir.ts +0 -1
- package/Framework/index.ts +0 -8
- package/Frontend/Angular/index.ts +0 -24
- package/Frontend/Websockets/index.ts +0 -86
- package/Mail/MailAddress.ts +0 -4
- package/Mail/MailTransport.ts +0 -6
- package/Mail/Mailable.ts +0 -16
- package/Mail/Mailer.ts +0 -27
- package/Mail/PendingMail.ts +0 -68
- package/Mail/SentMessage.ts +0 -20
- package/Mail/Transports/MemoryTransport.ts +0 -13
- package/Mail/Transports/SendGridTransport.ts +0 -95
- package/Mail/index.ts +0 -3
- package/Models/Model.ts +0 -41
- package/Models/index.ts +0 -54
- package/Router/BaseController.ts +0 -7
- package/Router/Decorators.ts +0 -224
- package/Router/Guard.ts +0 -10
- package/Router/Http/Contracts.ts +0 -4
- package/Router/Http/ErrorHandler.ts +0 -45
- package/Router/Http/ErrorHandlerInterface.ts +0 -6
- package/Router/Http/Errors/HttpError.ts +0 -15
- package/Router/Http/Handler.ts +0 -183
- package/Router/Http/HttpRoute.ts +0 -110
- package/Router/Http/Middleware.ts +0 -7
- package/Router/Http/Request.ts +0 -225
- package/Router/Http/Response.ts +0 -35
- package/Router/Http/index.ts +0 -85
- package/Router/Metadata.ts +0 -34
- package/Router/Middleware.ts +0 -16
- package/Router/Request.ts +0 -65
- package/Router/Route.ts +0 -16
- package/Router/RouteNotFoundError.ts +0 -5
- package/Router/Router.ts +0 -35
- package/Router/Servers/index.ts +0 -6
- package/Router/Servers/node.ts +0 -49
- package/Router/Servers/uNetworking.ts +0 -151
- package/Router/Websockets/Handler.ts +0 -82
- package/Router/Websockets/Middleware.ts +0 -7
- package/Router/Websockets/Request.ts +0 -3
- package/Router/Websockets/WebsocketRoute.ts +0 -61
- package/Router/Websockets/index.ts +0 -57
- package/Router/Websockets/types.ts +0 -23
- package/Router/index.ts +0 -6
- package/Storage/File.ts +0 -30
- package/Storage/Image.ts +0 -19
- package/Storage/InvalidImage.ts +0 -3
- package/Storage/Storage.ts +0 -98
- package/Storage/index.ts +0 -4
- package/Storage/utils.ts +0 -18
- package/Support/Array.ts +0 -184
- package/Support/Math.ts +0 -12
- package/Support/Metadata.ts +0 -31
- package/Support/String.ts +0 -38
- package/Support/index.ts +0 -19
- package/Support/utils.ts +0 -7
- package/Testing/TestCase.ts +0 -193
- package/Validation/Rule.ts +0 -9
- package/Validation/RuleInterface.ts +0 -10
- package/Validation/Rules/Email.ts +0 -20
- package/Validation/Rules/FileExtension.ts +0 -21
- package/Validation/Rules/MaxLength.ts +0 -17
- package/Validation/Rules/MinLength.ts +0 -18
- package/Validation/Rules/Optional.ts +0 -18
- package/Validation/Rules/Required.ts +0 -29
- package/Validation/Validator.ts +0 -7
- package/Validation/index.ts +0 -12
- package/benchmark-index.js +0 -20
- package/benchmark.ts +0 -47
- package/tests/Cache/DatabaseStoreTest.ts +0 -110
- package/tests/Cache/FileStoreTest.ts +0 -93
- package/tests/Cache/MemoryStoreTest.ts +0 -92
- package/tests/Container/ContainerTest.ts +0 -336
- package/tests/Database/Drivers/MySQL/AlterTest.ts +0 -100
- package/tests/Database/Drivers/MySQL/CreateTest.ts +0 -39
- package/tests/Database/Drivers/MysqlDriverTest.ts +0 -140
- package/tests/Database/Drivers/SqliteDriverTest.ts +0 -126
- package/tests/Database/Entities/Article.ts +0 -21
- package/tests/Database/Entities/Profile.ts +0 -21
- package/tests/Database/Entities/Role.ts +0 -15
- package/tests/Database/Entities/User.ts +0 -35
- package/tests/Database/EntityRelationshipsTest.ts +0 -475
- package/tests/Database/EntityTest.ts +0 -202
- package/tests/Database/Migrations/RunnerTest.ts +0 -96
- package/tests/Database/Migrations/migrations/1.createUserTable.ts +0 -12
- package/tests/Database/Migrations/migrations/2.createArticlesTable.ts +0 -12
- package/tests/Database/QueryTest.ts +0 -573
- package/tests/Database/SchemaTest.ts +0 -32
- package/tests/Database/Seeders/RunnerTest.ts +0 -30
- package/tests/Database/Seeders/seeders/RandomSeeder.ts +0 -10
- package/tests/Database/utils.ts +0 -16
- package/tests/Forms/FormsTest.ts +0 -59
- package/tests/Framework/Middleware/StaticAssetsMiddlewareTest.ts +0 -129
- package/tests/Framework/Resolvers/EntityResolverTest.ts +0 -48
- package/tests/Framework/Router/RouterTest.ts +0 -33
- package/tests/Mail/MailerTest.ts +0 -76
- package/tests/Model/ModelTest.ts +0 -183
- package/tests/Router/HttpHandlerTest.ts +0 -72
- package/tests/Router/RequestTest.ts +0 -77
- package/tests/Router/WebSocketsHandlerTest.ts +0 -51
- package/tests/Storage/StorageTest.ts +0 -97
- package/tests/Support/ArrayTest.ts +0 -167
- package/tests/Support/StringTest.ts +0 -18
- package/tests/Validation/RulesTest.ts +0 -54
- package/types.d.ts +0 -8
package/Router/Decorators.ts
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
import { App } from '../Framework'
|
|
2
|
-
import { Abstract, Constructor, Type } from '../Support'
|
|
3
|
-
import { GlobalMiddleware } from './Middleware'
|
|
4
|
-
import { ActionMetadata, ControllerMetadata, ControllerOptions, MethodMetadata, RouteMetadata } from './Metadata'
|
|
5
|
-
import { Guard } from './Guard'
|
|
6
|
-
import { Handler as HttpHandler, Http, Request as HttpRequest } from './Http'
|
|
7
|
-
import { Request } from './Request'
|
|
8
|
-
import { Handler as WebsocketsHandler } from './Websockets'
|
|
9
|
-
import { WebsocketRoute } from './Websockets/WebsocketRoute'
|
|
10
|
-
import { Container } from '@Typetron/Container'
|
|
11
|
-
|
|
12
|
-
export function Controller(path = '', options?: ControllerOptions) {
|
|
13
|
-
return (target: object) => {
|
|
14
|
-
const metadata = ControllerMetadata.get(target)
|
|
15
|
-
const prefix = options?.prefix || path ? path + '.' : ''
|
|
16
|
-
|
|
17
|
-
const httpHandler = Container.getInstance().get(HttpHandler)
|
|
18
|
-
const websocketHandler = Container.getInstance().get(WebsocketsHandler)
|
|
19
|
-
|
|
20
|
-
Object.keys(metadata.routes).forEach(action => {
|
|
21
|
-
const routeMetadata = metadata.routes[action]
|
|
22
|
-
const route = httpHandler.addRoute(
|
|
23
|
-
path + (path && routeMetadata.path ? '/' : '') + routeMetadata.path,
|
|
24
|
-
routeMetadata.method,
|
|
25
|
-
target as Constructor,
|
|
26
|
-
action,
|
|
27
|
-
prefix + (routeMetadata.name || action),
|
|
28
|
-
routeMetadata.parametersTypes,
|
|
29
|
-
metadata.middleware.concat(routeMetadata.middleware)
|
|
30
|
-
)
|
|
31
|
-
route.guards = routeMetadata.guards
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
Object.keys(metadata.actions).forEach(actionName => {
|
|
35
|
-
const actionMetadata = metadata.actions[actionName]
|
|
36
|
-
const name = prefix + (actionMetadata.name || actionName)
|
|
37
|
-
const action = websocketHandler.addAction(
|
|
38
|
-
name,
|
|
39
|
-
target as Constructor,
|
|
40
|
-
actionName,
|
|
41
|
-
actionMetadata.parametersTypes,
|
|
42
|
-
metadata.middleware.concat(actionMetadata.middleware)
|
|
43
|
-
)
|
|
44
|
-
action.guards = actionMetadata.guards
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function addAction(controller: Constructor, methodName: string, name: string) {
|
|
50
|
-
const metadata = ControllerMetadata.get(controller)
|
|
51
|
-
|
|
52
|
-
const methodMetadata = metadata.methods[methodName]
|
|
53
|
-
const action = new ActionMetadata()
|
|
54
|
-
Object.assign(action, methodMetadata)
|
|
55
|
-
|
|
56
|
-
action.parametersTypes = Reflect.getMetadata('design:paramtypes', controller.prototype, methodName)
|
|
57
|
-
action.name = name
|
|
58
|
-
|
|
59
|
-
metadata.actions[methodName] = action
|
|
60
|
-
|
|
61
|
-
ControllerMetadata.set(metadata, controller)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function addRoute(controller: Constructor, methodName: string, method: Http.Method, path: string, name: string) {
|
|
65
|
-
const metadata = ControllerMetadata.get(controller)
|
|
66
|
-
|
|
67
|
-
const methodMetadata = metadata.methods[methodName]
|
|
68
|
-
const route = new RouteMetadata()
|
|
69
|
-
Object.assign(route, methodMetadata)
|
|
70
|
-
|
|
71
|
-
route.parametersTypes = Reflect.getMetadata('design:paramtypes', controller.prototype, methodName)
|
|
72
|
-
route.path = path
|
|
73
|
-
route.name = name
|
|
74
|
-
route.method = method
|
|
75
|
-
|
|
76
|
-
metadata.routes[methodName] = route
|
|
77
|
-
|
|
78
|
-
ControllerMetadata.set(metadata, controller)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export function Action(name = '') {
|
|
82
|
-
return (target: object, action: string) => {
|
|
83
|
-
addAction(target.constructor as Constructor, action, name)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function OnOpen(target: object, action: string) {
|
|
88
|
-
const websocketHandler = App.get(WebsocketsHandler)
|
|
89
|
-
|
|
90
|
-
websocketHandler.onOpen = new WebsocketRoute(
|
|
91
|
-
'',
|
|
92
|
-
target.constructor as Constructor,
|
|
93
|
-
action,
|
|
94
|
-
Reflect.getMetadata('design:paramtypes', target, action),
|
|
95
|
-
)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function OnClose(target: object, action: string) {
|
|
99
|
-
const websocketHandler = App.get(WebsocketsHandler)
|
|
100
|
-
|
|
101
|
-
websocketHandler.onClose = new WebsocketRoute(
|
|
102
|
-
'',
|
|
103
|
-
target.constructor as Constructor,
|
|
104
|
-
action,
|
|
105
|
-
Reflect.getMetadata('design:paramtypes', target, action),
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function Arg(name: string) {
|
|
110
|
-
return function(target: object, action: string, parameterIndex: number) {
|
|
111
|
-
// addAction(target.constructor as Constructor, action, name)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function Get(path = '', name = '') {
|
|
116
|
-
return (target: object, action: string) => {
|
|
117
|
-
addRoute(target.constructor as Constructor, action, Http.Method.GET, path, name)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function Post(path: string = '', name = '') {
|
|
122
|
-
return (target: object, action: string) => {
|
|
123
|
-
addRoute(target.constructor as Constructor, action, Http.Method.POST, path, name)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function Put(path: string = '', name = '') {
|
|
128
|
-
return (target: object, action: string) => {
|
|
129
|
-
addRoute(target.constructor as Constructor, action, Http.Method.PUT, path, name)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function Patch(path: string = '', name = '') {
|
|
134
|
-
return (target: object, action: string) => {
|
|
135
|
-
addRoute(target.constructor as Constructor, action, Http.Method.PATCH, path, name)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function Delete(path: string = '', name = '') {
|
|
140
|
-
return (target: object, action: string) => {
|
|
141
|
-
addRoute(target.constructor as Constructor, action, Http.Method.DELETE, path, name)
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export function Middleware(...middleware: Abstract<GlobalMiddleware>[]) {
|
|
146
|
-
return (target: object, action?: string) => {
|
|
147
|
-
if (action) {
|
|
148
|
-
target = target.constructor
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const metadata = ControllerMetadata.get(target)
|
|
152
|
-
|
|
153
|
-
if (action) {
|
|
154
|
-
const route = metadata.methods[action] || new MethodMetadata()
|
|
155
|
-
route.middleware = route.middleware.concat(middleware)
|
|
156
|
-
metadata.methods[action] = route
|
|
157
|
-
} else {
|
|
158
|
-
metadata.middleware = metadata.middleware.concat(middleware)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
ControllerMetadata.set(metadata, target)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export function AllowIf(...guards: Type<Guard>[]) {
|
|
166
|
-
return function(target: object, action: string) {
|
|
167
|
-
if (action) {
|
|
168
|
-
target = target.constructor
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const metadata = ControllerMetadata.get(target)
|
|
172
|
-
|
|
173
|
-
if (action) {
|
|
174
|
-
const route = metadata.methods[action] || new MethodMetadata()
|
|
175
|
-
route.guards = route.guards.concat(guards)
|
|
176
|
-
metadata.methods[action] = route
|
|
177
|
-
} else {
|
|
178
|
-
metadata.guards = metadata.guards.concat(guards)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
ControllerMetadata.set(metadata, target)
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function Query(name: string) {
|
|
186
|
-
return function(target: object, action: string, parameterIndex: number) {
|
|
187
|
-
const metadata = ControllerMetadata.get(target.constructor)
|
|
188
|
-
const parametersTypes = Reflect.getMetadata('design:paramtypes', target, action)
|
|
189
|
-
|
|
190
|
-
const route = metadata.methods[action] || new MethodMetadata()
|
|
191
|
-
route.parametersOverrides[parameterIndex] = function(container: Container) {
|
|
192
|
-
const request = container.get(HttpRequest)
|
|
193
|
-
const value = request.query[name]
|
|
194
|
-
|
|
195
|
-
if (parametersTypes[parameterIndex].name === 'Number') {
|
|
196
|
-
return value === undefined || value === 'undefined' ? undefined : Number(value)
|
|
197
|
-
}
|
|
198
|
-
return value
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
metadata.methods[action] = route
|
|
202
|
-
ControllerMetadata.set(metadata, target.constructor)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export function Body() {
|
|
207
|
-
return function(target: object, action: string, parameterIndex: number) {
|
|
208
|
-
const metadata = ControllerMetadata.get(target.constructor)
|
|
209
|
-
const route = metadata.methods[action] || new MethodMetadata()
|
|
210
|
-
route.parametersOverrides[parameterIndex] = function(container: Container) {
|
|
211
|
-
const request = container.get(Request)
|
|
212
|
-
|
|
213
|
-
// TODO: should the framework throw error or return undefined?
|
|
214
|
-
// if (!request.body) {
|
|
215
|
-
// throw new Error(`There is no data in the 'body' of the request`)
|
|
216
|
-
// }
|
|
217
|
-
|
|
218
|
-
return request.body
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
metadata.methods[action] = route
|
|
222
|
-
ControllerMetadata.set(metadata, target.constructor)
|
|
223
|
-
}
|
|
224
|
-
}
|
package/Router/Guard.ts
DELETED
package/Router/Http/Contracts.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { Response } from './Response'
|
|
2
|
-
import { ErrorHandlerInterface } from './ErrorHandlerInterface'
|
|
3
|
-
import { HttpError } from './Errors/HttpError'
|
|
4
|
-
import { Http } from './index'
|
|
5
|
-
import { Request } from './Request'
|
|
6
|
-
import { Inject } from '../../Container'
|
|
7
|
-
import { AppConfig } from '../../Framework/Config'
|
|
8
|
-
|
|
9
|
-
export class ErrorHandler implements ErrorHandlerInterface {
|
|
10
|
-
|
|
11
|
-
@Inject()
|
|
12
|
-
appConfig: AppConfig
|
|
13
|
-
|
|
14
|
-
handle(error: Error, request?: Request) {
|
|
15
|
-
if (this.appConfig.debug) {
|
|
16
|
-
return this.handleDevelopmentError(error, request)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (error instanceof HttpError) {
|
|
20
|
-
return new Response(error.content, error.status)
|
|
21
|
-
}
|
|
22
|
-
return new Response(error.message, Http.Status.BAD_REQUEST)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
private handleDevelopmentError(error: Error, request?: Request) {
|
|
26
|
-
let code = Http.Status.BAD_REQUEST, message: string | object | number = '', stack: string[]
|
|
27
|
-
|
|
28
|
-
stack = error.stack ? error.stack.replace(/\n|\s{2,}/g, '').split('at ') : []
|
|
29
|
-
if (error instanceof HttpError) {
|
|
30
|
-
code = error.status
|
|
31
|
-
message = error.content
|
|
32
|
-
if (request) {
|
|
33
|
-
stack.unshift(`Route: ${request.method} ${request.uri}`)
|
|
34
|
-
}
|
|
35
|
-
} else {
|
|
36
|
-
message = error.message
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const errorInfo: {message: string | object | number, stack?: string[]} = {
|
|
40
|
-
message, stack
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return new Response(errorInfo, code)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Http } from '../index'
|
|
2
|
-
|
|
3
|
-
export class HttpError extends Error {
|
|
4
|
-
|
|
5
|
-
constructor(
|
|
6
|
-
public content: string | object,
|
|
7
|
-
public status: Http.Status = Http.Status.BAD_REQUEST
|
|
8
|
-
) {
|
|
9
|
-
super(typeof content === 'string' ? content : 'HTTP Error')
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
getMessage() {
|
|
13
|
-
return this.content
|
|
14
|
-
}
|
|
15
|
-
}
|
package/Router/Http/Handler.ts
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import { Container, Inject } from '../../Container'
|
|
2
|
-
import { RequestHandler, RouteNotFoundError, Router } from '../'
|
|
3
|
-
import { ErrorHandlerInterface, Http, Response } from './'
|
|
4
|
-
import { Request } from './Request'
|
|
5
|
-
import { HttpRoute as Route } from './HttpRoute'
|
|
6
|
-
import { AppConfig } from '../../Framework'
|
|
7
|
-
import { Request as BaseRequest } from '../Request'
|
|
8
|
-
import { Abstract, Constructor, Type } from '@Typetron/Support'
|
|
9
|
-
import { AppServer, nodeServer, uNetworkingServer } from '@Typetron/Router/Servers'
|
|
10
|
-
import { HttpMiddleware } from '@Typetron/Router/Http/Middleware'
|
|
11
|
-
|
|
12
|
-
const httpServers: Record<AppConfig['server'], AppServer> = {
|
|
13
|
-
node: nodeServer,
|
|
14
|
-
uNetworking: uNetworkingServer
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class Handler {
|
|
18
|
-
@Inject()
|
|
19
|
-
router: Router
|
|
20
|
-
|
|
21
|
-
@Inject()
|
|
22
|
-
errorHandler: ErrorHandlerInterface
|
|
23
|
-
|
|
24
|
-
cachedRoutes: Record<string, [Route, Record<string, string>]> = {}
|
|
25
|
-
|
|
26
|
-
addRoute(
|
|
27
|
-
uri: string,
|
|
28
|
-
method: Http.Method,
|
|
29
|
-
controller: Constructor,
|
|
30
|
-
action: string,
|
|
31
|
-
name: string,
|
|
32
|
-
parametersTypes: (Type<(...args: any[]) => any> | FunctionConstructor)[] = [],
|
|
33
|
-
middleware: Abstract<HttpMiddleware>[] = []
|
|
34
|
-
): Route {
|
|
35
|
-
uri = this.prepareUri(uri)
|
|
36
|
-
const route = new Route(uri, method, name, controller, action, parametersTypes, middleware)
|
|
37
|
-
if (this.router.routes.find(item => item.uri === uri && item.method === method)) {
|
|
38
|
-
throw new Error(`There is already a route with the same url: [${method}] '${uri}'`)
|
|
39
|
-
}
|
|
40
|
-
this.router.routes.push(route)
|
|
41
|
-
return route
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// async handle(app: Application, request: Request) {
|
|
45
|
-
// try {
|
|
46
|
-
// return await this.handle(app, request)
|
|
47
|
-
// } catch (error) {
|
|
48
|
-
// return this.errorHandler.handle(error, request)
|
|
49
|
-
// }
|
|
50
|
-
// }
|
|
51
|
-
|
|
52
|
-
startServer(app: Container): void {
|
|
53
|
-
const config = app.get(AppConfig)
|
|
54
|
-
const startServer = httpServers[config.server]
|
|
55
|
-
|
|
56
|
-
startServer(config.port, async (request) => {
|
|
57
|
-
try {
|
|
58
|
-
return await this.handle(app, request)
|
|
59
|
-
} catch (error) {
|
|
60
|
-
return this.errorHandler.handle(error as Error)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async handle(app: Container, request: Request): Promise<Response> {
|
|
66
|
-
const container = app.createChildContainer()
|
|
67
|
-
|
|
68
|
-
container.set(BaseRequest, request)
|
|
69
|
-
container.set(Request, request)
|
|
70
|
-
|
|
71
|
-
let stack: RequestHandler = async () => {
|
|
72
|
-
const [route, parameters] = this.cachedRoutes[`${request.method} ${request.uri}`]
|
|
73
|
-
?? this.findRouteIndex(request.uri ?? '', request.method)
|
|
74
|
-
|
|
75
|
-
container.set(Route, route)
|
|
76
|
-
request.parameters = parameters
|
|
77
|
-
|
|
78
|
-
let routeStack: RequestHandler = async () => {
|
|
79
|
-
|
|
80
|
-
const content = await route.run(container, request.parameters)
|
|
81
|
-
|
|
82
|
-
if (content instanceof Response) {
|
|
83
|
-
return content
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return Response.ok(content)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
route.middleware.forEach(middlewareClass => {
|
|
90
|
-
const middleware = container.get(middlewareClass)
|
|
91
|
-
routeStack = middleware.handle.bind(middleware, request, routeStack)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
return routeStack(request)
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
this.router.middleware.global?.forEach(middlewareClass => {
|
|
98
|
-
const middleware = container.get(middlewareClass)
|
|
99
|
-
stack = middleware.handle.bind(middleware, request, stack)
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
this.router.middleware.http?.forEach(middlewareClass => {
|
|
103
|
-
const middleware = container.get(middlewareClass)
|
|
104
|
-
stack = middleware.handle.bind(middleware, request, stack)
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
return stack(request)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
matches(uri: string, route: Route) {
|
|
111
|
-
const uriParts = uri.split('/') // ex: ['users', '1', 'posts'];
|
|
112
|
-
let part
|
|
113
|
-
let parameterTypeIndex = 0
|
|
114
|
-
const parameters: Record<string, string> = {}
|
|
115
|
-
for (part = 0; part < uriParts.length; part++) {
|
|
116
|
-
if (!route.uriParts[part]) {
|
|
117
|
-
return false
|
|
118
|
-
}
|
|
119
|
-
if (route.uriParts[part].type === 'parameter' && route.hasCorrectPrimitiveType(parameterTypeIndex, uriParts[part])) {
|
|
120
|
-
parameterTypeIndex++
|
|
121
|
-
parameters[route.uriParts[part].name] = uriParts[part]
|
|
122
|
-
continue
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (route.uriParts[part].name !== uriParts[part]) {
|
|
126
|
-
return false
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (part !== route.uriParts.length) {
|
|
131
|
-
return false
|
|
132
|
-
}
|
|
133
|
-
return parameters
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
private findRouteIndex(uri: string, method: string): [Route, Record<string, string> | undefined] {
|
|
137
|
-
const preparedUri = this.prepareUri(uri)
|
|
138
|
-
|
|
139
|
-
for (const route of this.router.routes) {
|
|
140
|
-
if (route.method.toLowerCase() === method.toLowerCase()) {
|
|
141
|
-
const parameters = this.matches(preparedUri, route)
|
|
142
|
-
|
|
143
|
-
if (parameters) {
|
|
144
|
-
this.cachedRoutes[`${method} ${uri}`] = [route, parameters]
|
|
145
|
-
return [route, parameters]
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
throw new RouteNotFoundError(`[${method}] ${uri}`)
|
|
151
|
-
// return this.routes
|
|
152
|
-
// .where('uri', uri)
|
|
153
|
-
// .findWhere('method', method) || this.routeNotFound(uri);
|
|
154
|
-
|
|
155
|
-
// const uriParts = uri.split('/'); // ['users', '1', 'posts'];
|
|
156
|
-
//
|
|
157
|
-
// let currentRoute: string | undefined;
|
|
158
|
-
//
|
|
159
|
-
// let routesGroup = this.routesMap;
|
|
160
|
-
// uriParts.forEach(part => {
|
|
161
|
-
// if (routesGroup[part]) {
|
|
162
|
-
// return routesGroup = routesGroup[part];
|
|
163
|
-
// }
|
|
164
|
-
// if (routesGroup['*']) {
|
|
165
|
-
// return routesGroup = routesGroup['*'];
|
|
166
|
-
// }
|
|
167
|
-
//
|
|
168
|
-
// throw new Error(`Route for '${uri}' not found`);
|
|
169
|
-
// });
|
|
170
|
-
|
|
171
|
-
// this.routes;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
private prepareUri(uri: string) {
|
|
175
|
-
if (uri[0] === '/') {
|
|
176
|
-
uri = uri.substr(1)
|
|
177
|
-
}
|
|
178
|
-
if (uri[uri.length - 1] === '/') {
|
|
179
|
-
uri = uri.substring(0, uri.length - 1)
|
|
180
|
-
}
|
|
181
|
-
return uri
|
|
182
|
-
}
|
|
183
|
-
}
|
package/Router/Http/HttpRoute.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { Container } from '../../Container'
|
|
2
|
-
import { Abstract, Constructor, Type } from '../../Support'
|
|
3
|
-
import { ControllerMetadata } from './../Metadata'
|
|
4
|
-
import { Route } from '@Typetron/Router'
|
|
5
|
-
import { AnyFunction } from '@Typetron/Support'
|
|
6
|
-
import { HttpMiddleware } from '@Typetron/Router/Http/Middleware'
|
|
7
|
-
|
|
8
|
-
export class HttpRoute extends Route {
|
|
9
|
-
|
|
10
|
-
public readonly uriParts: {name: string, type: 'part' | 'parameter'}[] = []
|
|
11
|
-
|
|
12
|
-
constructor(
|
|
13
|
-
public uri: string,
|
|
14
|
-
public method: string,
|
|
15
|
-
public name = '',
|
|
16
|
-
public controller: Constructor,
|
|
17
|
-
public controllerMethod: string,
|
|
18
|
-
public parametersTypes: (Type<AnyFunction> | FunctionConstructor)[] = [],
|
|
19
|
-
public middleware: Abstract<HttpMiddleware>[] = []
|
|
20
|
-
) {
|
|
21
|
-
super(name, controller, controllerMethod, parametersTypes, middleware)
|
|
22
|
-
this.splitUriParts()
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async run(container: Container, requestParameters: Record<string, string | number>): Promise<object | string> {
|
|
26
|
-
const controller = await container.get(this.controller)
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const metadata = ControllerMetadata.get(this.controller).routes[this.controllerMethod]
|
|
30
|
-
const parameters = await this.resolveParameters(
|
|
31
|
-
requestParameters,
|
|
32
|
-
metadata.parametersTypes,
|
|
33
|
-
metadata.parametersOverrides,
|
|
34
|
-
container
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
for await (const guardClass of this.guards) {
|
|
38
|
-
const guard = container.get(guardClass)
|
|
39
|
-
if (!await guard.condition(...parameters)) {
|
|
40
|
-
guard.onFail()
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
return (controller[this.controllerMethod as keyof Constructor] as AnyFunction<object | string>).apply(controller, parameters)
|
|
45
|
-
} catch (unknownError) {
|
|
46
|
-
const error = unknownError as Error
|
|
47
|
-
error.stack = `Controller: ${controller.constructor.name}.${this.controllerMethod} \n at ` + error.stack
|
|
48
|
-
throw error
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
splitUriParts() {
|
|
53
|
-
this.uri.split('/').forEach(uriPart => {
|
|
54
|
-
const matches = uriPart.match(/:(\w+)/)
|
|
55
|
-
if (matches) {
|
|
56
|
-
this.uriParts.push({
|
|
57
|
-
name: matches[1],
|
|
58
|
-
type: 'parameter'
|
|
59
|
-
})
|
|
60
|
-
} else {
|
|
61
|
-
this.uriParts.push({
|
|
62
|
-
name: uriPart,
|
|
63
|
-
type: 'part'
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
getUrl(parameters: Record<string, string>): string {
|
|
70
|
-
return this.uriParts.map(part => {
|
|
71
|
-
if (part.type === 'parameter') {
|
|
72
|
-
return parameters[part.name]
|
|
73
|
-
}
|
|
74
|
-
return part.name
|
|
75
|
-
}).filter(Boolean).join('/')
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
hasCorrectPrimitiveType(parameterTypeIndex: number, uriPart: string) {
|
|
79
|
-
const parameterType = this.parametersTypes[parameterTypeIndex]
|
|
80
|
-
return (primitiveTypes[parameterType.name] || (value => value))(uriPart)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
private async resolveParameters(
|
|
84
|
-
requestParameters: Record<string, string | number>,
|
|
85
|
-
parameters: (Type<(...args: any[]) => any> | FunctionConstructor)[],
|
|
86
|
-
overrides: ((container: Container) => unknown)[],
|
|
87
|
-
container: Container
|
|
88
|
-
) {
|
|
89
|
-
let parameterIndex = 0
|
|
90
|
-
const routeParameters = Object.values(requestParameters)
|
|
91
|
-
return parameters.mapAsync(async (parameter, index) => {
|
|
92
|
-
const newValueFunction = overrides[index]
|
|
93
|
-
if (newValueFunction) {
|
|
94
|
-
return await newValueFunction.call(undefined, container)
|
|
95
|
-
}
|
|
96
|
-
if (parameter.name === 'String') {
|
|
97
|
-
return routeParameters[parameterIndex++]
|
|
98
|
-
}
|
|
99
|
-
if (parameter.name === 'Number') {
|
|
100
|
-
const value = routeParameters[parameterIndex++]
|
|
101
|
-
return value === undefined || value === 'undefined' ? undefined : Number(value)
|
|
102
|
-
}
|
|
103
|
-
return container.get(parameter)
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const primitiveTypes: Record<string, (value: string) => boolean> = {
|
|
109
|
-
Number: (value: string) => !isNaN(Number(value)),
|
|
110
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { Request } from '@Typetron/Router/Request'
|
|
2
|
-
import { Response } from '.'
|
|
3
|
-
import { GlobalMiddleware, RequestHandler } from '..'
|
|
4
|
-
|
|
5
|
-
export abstract class HttpMiddleware extends GlobalMiddleware {
|
|
6
|
-
abstract handle(request: Request, next: RequestHandler): Promise<Response>
|
|
7
|
-
}
|