@stacksjs/router 0.61.19 → 0.61.21
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/dist/index.js +107426 -162
- package/package.json +3 -3
- package/src/request.ts +3 -3
- package/src/router.ts +11 -13
- package/src/server.ts +41 -8
- package/src/utils.ts +53 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/router",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.61.
|
|
4
|
+
"version": "0.61.21",
|
|
5
5
|
"description": "The Stacks framework router.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"license": "MIT",
|
|
@@ -49,13 +49,13 @@
|
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@stacksjs/config": "latest",
|
|
52
|
-
"unplugin-vue-router": "^0.
|
|
52
|
+
"unplugin-vue-router": "^0.9.0",
|
|
53
53
|
"vue-router": "^4.3.2"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@stacksjs/config": "latest",
|
|
57
57
|
"@stacksjs/logging": "latest",
|
|
58
|
-
"unplugin-vue-router": "^0.
|
|
58
|
+
"unplugin-vue-router": "^0.9.0",
|
|
59
59
|
"vue-router": "^4.3.2"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
package/src/request.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RouteParam } from
|
|
1
|
+
import type { RequestInstance, RouteParam } from "@stacksjs/types"
|
|
2
2
|
|
|
3
3
|
interface RequestData {
|
|
4
4
|
[key: string]: string
|
|
@@ -6,7 +6,7 @@ interface RequestData {
|
|
|
6
6
|
|
|
7
7
|
type RouteParams = { [key: string]: string } | null
|
|
8
8
|
|
|
9
|
-
export class Request {
|
|
9
|
+
export class Request implements RequestInstance{
|
|
10
10
|
private static instance: Request
|
|
11
11
|
private query: RequestData = {}
|
|
12
12
|
private params: RouteParams = null
|
|
@@ -62,6 +62,6 @@ export class Request {
|
|
|
62
62
|
const value = this.params ? this.params[key] || null : null
|
|
63
63
|
return value ? Number.parseInt(value) : null
|
|
64
64
|
}
|
|
65
|
-
}
|
|
65
|
+
}
|
|
66
66
|
|
|
67
67
|
export const request = new Request()
|
package/src/router.ts
CHANGED
|
@@ -3,8 +3,11 @@ import { log } from '@stacksjs/logging'
|
|
|
3
3
|
import { path as p, projectStoragePath, routesPath } from '@stacksjs/path'
|
|
4
4
|
import { kebabCase, pascalCase } from '@stacksjs/strings'
|
|
5
5
|
import type { Job } from '@stacksjs/types'
|
|
6
|
+
import { request } from '@stacksjs/router'
|
|
6
7
|
import type { RedirectCode, Route, RouteGroupOptions, RouterInterface, StatusCode } from '@stacksjs/types'
|
|
7
8
|
|
|
9
|
+
import { extractModelRequest } from './utils'
|
|
10
|
+
|
|
8
11
|
type ActionPath = string // TODO: narrow this by automating its generation
|
|
9
12
|
|
|
10
13
|
export class Router implements RouterInterface {
|
|
@@ -93,6 +96,8 @@ export class Router implements RouterInterface {
|
|
|
93
96
|
}
|
|
94
97
|
|
|
95
98
|
public async action(path: ActionPath | Route['path']): Promise<this> {
|
|
99
|
+
if (!path) return this
|
|
100
|
+
|
|
96
101
|
// check if action is a file anywhere in ./app/Actions/**/*.ts
|
|
97
102
|
if (path?.endsWith('.ts')) {
|
|
98
103
|
// given it ends with .ts, we treat it as an Actions path
|
|
@@ -102,22 +107,15 @@ export class Router implements RouterInterface {
|
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
path = pascalCase(path) // actions are PascalCase
|
|
105
|
-
const userActionsPath = p.userActionsPath(`${path}.ts`)
|
|
106
110
|
|
|
107
111
|
try {
|
|
108
|
-
const action = (await import(userActionsPath)).default as Action
|
|
112
|
+
const action = (await import(p.userActionsPath(`${path}.ts`))).default as Action
|
|
109
113
|
|
|
110
114
|
return this.addRoute(action.method ?? 'GET', this.prepareUri(path), action.handle, 200)
|
|
111
115
|
} catch (error) {
|
|
112
|
-
|
|
113
|
-
const action = (await import(p.userActionsPath(`${path}.ts`))).default as Action
|
|
114
|
-
|
|
115
|
-
return this.addRoute(action.method ?? 'GET', this.prepareUri(path), action.handle, 200)
|
|
116
|
-
} catch (error) {
|
|
117
|
-
log.error(`Could not find Action for path: ${path}`)
|
|
116
|
+
log.error(`Could not find Action for path: ${path}`)
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
}
|
|
118
|
+
return this
|
|
121
119
|
}
|
|
122
120
|
}
|
|
123
121
|
|
|
@@ -304,9 +302,9 @@ export class Router implements RouterInterface {
|
|
|
304
302
|
// if succeeds, run the handle
|
|
305
303
|
// if fails, return validation error
|
|
306
304
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
return await actionModule.default.handle(
|
|
305
|
+
const requestInstance = await extractModelRequest(modulePath)
|
|
306
|
+
|
|
307
|
+
return await actionModule.default.handle(requestInstance)
|
|
310
308
|
}
|
|
311
309
|
|
|
312
310
|
private normalizePath(path: string): string {
|
package/src/server.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import process from 'node:process'
|
|
2
2
|
import { log } from '@stacksjs/logging'
|
|
3
|
-
import { extname } from '@stacksjs/path'
|
|
4
|
-
import
|
|
3
|
+
import { extname, path } from '@stacksjs/path'
|
|
4
|
+
import { glob } from '@stacksjs/storage'
|
|
5
|
+
import type { Model, Route, RouteParam, StatusCode } from '@stacksjs/types'
|
|
5
6
|
import { route } from '.'
|
|
6
7
|
import { middlewares } from './middleware'
|
|
7
8
|
import { request as RequestParam } from './request'
|
|
9
|
+
import { getModelName } from '@stacksjs/orm'
|
|
10
|
+
import { lowercase } from '@stacksjs/strings'
|
|
8
11
|
|
|
9
12
|
interface ServeOptions {
|
|
10
13
|
host?: string
|
|
@@ -71,8 +74,8 @@ export async function serverResponse(req: Request) {
|
|
|
71
74
|
|
|
72
75
|
const routeParams = extractDynamicSegments(foundRoute.uri, url.pathname)
|
|
73
76
|
|
|
74
|
-
addRouteQuery(url)
|
|
75
|
-
addRouteParam(routeParams)
|
|
77
|
+
await addRouteQuery(url)
|
|
78
|
+
await addRouteParam(routeParams)
|
|
76
79
|
|
|
77
80
|
await executeMiddleware(foundRoute)
|
|
78
81
|
|
|
@@ -146,13 +149,43 @@ function noCache(response: Response) {
|
|
|
146
149
|
return response
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
function addRouteQuery(url: URL)
|
|
150
|
-
|
|
152
|
+
async function addRouteQuery(url: URL) {
|
|
153
|
+
const modelFiles = glob.sync(path.userModelsPath('*.ts'));
|
|
151
154
|
|
|
152
|
-
|
|
155
|
+
for (const modelFile of modelFiles) {
|
|
156
|
+
const model = (await import(modelFile)).default;
|
|
157
|
+
const modelName = getModelName(model, modelFile);
|
|
158
|
+
const modelNameLower = `${lowercase(modelName)}Request`;
|
|
159
|
+
const requestPath = path.projectStoragePath(`framework/requests/${modelName}Request.ts`);
|
|
160
|
+
const requestImport = await import(requestPath);
|
|
161
|
+
const requestInstance = requestImport[modelNameLower];
|
|
162
|
+
|
|
163
|
+
if (requestInstance && !isObjectNotEmpty(url.searchParams)) {
|
|
164
|
+
requestInstance.addQuery(url);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (!isObjectNotEmpty(url.searchParams)) {
|
|
169
|
+
RequestParam.addQuery(url);
|
|
170
|
+
}
|
|
153
171
|
}
|
|
154
172
|
|
|
155
|
-
function addRouteParam(param: RouteParam): void {
|
|
173
|
+
async function addRouteParam(param: RouteParam): Promise<void> {
|
|
174
|
+
const modelFiles = glob.sync(path.userModelsPath('*.ts'));
|
|
175
|
+
|
|
176
|
+
for (const modelFile of modelFiles) {
|
|
177
|
+
const model = (await import(modelFile)).default as Model;
|
|
178
|
+
const modelName = getModelName(model, modelFile);
|
|
179
|
+
const modelNameLower = `${lowercase(modelName)}Request`;
|
|
180
|
+
const requestPath = path.projectStoragePath(`framework/requests/${modelName}Request.ts`);
|
|
181
|
+
const requestImport = await import(requestPath);
|
|
182
|
+
const requestInstance = requestImport[modelNameLower];
|
|
183
|
+
|
|
184
|
+
if (requestInstance) {
|
|
185
|
+
requestInstance.addParam(param);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
156
189
|
RequestParam.addParam(param)
|
|
157
190
|
}
|
|
158
191
|
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import { ok } from '@stacksjs/error-handling'
|
|
1
2
|
import { route } from './router'
|
|
3
|
+
import { path } from '@stacksjs/path'
|
|
4
|
+
|
|
5
|
+
import { lowercase } from '@stacksjs/strings'
|
|
2
6
|
|
|
3
7
|
export async function listRoutes() {
|
|
4
8
|
const routeLists = await route.getRoutes()
|
|
@@ -7,3 +11,52 @@ export async function listRoutes() {
|
|
|
7
11
|
|
|
8
12
|
return ok('Successfully listed routes!')
|
|
9
13
|
}
|
|
14
|
+
|
|
15
|
+
export function extractModelFromAction(action: string): string {
|
|
16
|
+
let model = ''
|
|
17
|
+
|
|
18
|
+
if (action.includes("StoreOrmAction")) {
|
|
19
|
+
const match = action.match(/\/([A-Z][a-z]+)StoreOrmAction/);
|
|
20
|
+
|
|
21
|
+
const modelString = match ? match[1] : '';
|
|
22
|
+
|
|
23
|
+
model = modelString as string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (action.includes("ShowOrmAction")) {
|
|
27
|
+
const match = action.match(/\/([A-Z][a-z]+)ShowOrmAction/);
|
|
28
|
+
const modelString = match ? match[1] : '';
|
|
29
|
+
|
|
30
|
+
model = modelString as string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (action.includes("UpdateOrmAction")) {
|
|
34
|
+
const match = action.match(/\/([A-Z][a-z]+)UpdateOrmAction/);
|
|
35
|
+
const modelString = match ? match[1] : '';
|
|
36
|
+
|
|
37
|
+
model = modelString as string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (action.includes("DestroyOrmAction")) {
|
|
41
|
+
const match = action.match(/\/([A-Z][a-z]+)DestroyOrmAction/);
|
|
42
|
+
const modelString = match ? match[1] : '';
|
|
43
|
+
|
|
44
|
+
model = modelString as string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return model
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function extractModelRequest(action: string) {
|
|
51
|
+
const extractedModel = extractModelFromAction(action)
|
|
52
|
+
|
|
53
|
+
const lowerCaseModel = lowercase(extractedModel)
|
|
54
|
+
|
|
55
|
+
const requestPath = path.projectStoragePath(`framework/requests/${extractedModel}Request.ts`)
|
|
56
|
+
|
|
57
|
+
const requestInstance = await import(requestPath)
|
|
58
|
+
|
|
59
|
+
const requestIndex = `${lowerCaseModel}Request`
|
|
60
|
+
|
|
61
|
+
return requestInstance[requestIndex]
|
|
62
|
+
}
|