vector-framework 0.9.8 → 0.9.9
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/README.md +33 -2
- package/dist/cli/index.js +63 -64
- package/dist/cli/index.js.map +1 -1
- package/dist/cli.js +166 -129
- package/dist/core/vector.d.ts.map +1 -1
- package/dist/core/vector.js +8 -4
- package/dist/core/vector.js.map +1 -1
- package/dist/dev/route-scanner.d.ts +5 -2
- package/dist/dev/route-scanner.d.ts.map +1 -1
- package/dist/dev/route-scanner.js +63 -16
- package/dist/dev/route-scanner.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.mjs +4 -4
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +8 -1
- package/dist/middleware/manager.js.map +1 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +78 -78
- package/src/core/vector.ts +9 -4
- package/src/dev/route-scanner.ts +76 -18
- package/src/middleware/manager.ts +7 -1
- package/src/types/index.ts +2 -0
package/dist/cli.js
CHANGED
|
@@ -117,94 +117,128 @@ __export(exports_route_scanner, {
|
|
|
117
117
|
});
|
|
118
118
|
import { existsSync, promises as fs2 } from "fs";
|
|
119
119
|
import { join, relative as relative2, resolve, sep } from "path";
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
120
|
+
var RouteScanner;
|
|
121
|
+
var init_route_scanner = __esm(() => {
|
|
122
|
+
RouteScanner = class RouteScanner {
|
|
123
|
+
routesDir;
|
|
124
|
+
excludePatterns;
|
|
125
|
+
static DEFAULT_EXCLUDE_PATTERNS = [
|
|
126
|
+
"*.test.ts",
|
|
127
|
+
"*.test.js",
|
|
128
|
+
"*.test.tsx",
|
|
129
|
+
"*.test.jsx",
|
|
130
|
+
"*.spec.ts",
|
|
131
|
+
"*.spec.js",
|
|
132
|
+
"*.spec.tsx",
|
|
133
|
+
"*.spec.jsx",
|
|
134
|
+
"*.tests.ts",
|
|
135
|
+
"*.tests.js",
|
|
136
|
+
"**/__tests__/**",
|
|
137
|
+
"*.interface.ts",
|
|
138
|
+
"*.type.ts",
|
|
139
|
+
"*.d.ts"
|
|
140
|
+
];
|
|
141
|
+
constructor(routesDir = "./routes", excludePatterns) {
|
|
142
|
+
this.routesDir = resolve(process.cwd(), routesDir);
|
|
143
|
+
this.excludePatterns = excludePatterns || RouteScanner.DEFAULT_EXCLUDE_PATTERNS;
|
|
130
144
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (error.code === "ENOENT") {
|
|
135
|
-
console.warn(` \u2717 Routes directory not accessible: ${this.routesDir}`);
|
|
145
|
+
async scan() {
|
|
146
|
+
const routes = [];
|
|
147
|
+
if (!existsSync(this.routesDir)) {
|
|
136
148
|
return [];
|
|
137
149
|
}
|
|
138
|
-
|
|
150
|
+
try {
|
|
151
|
+
await this.scanDirectory(this.routesDir, routes);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
if (error.code === "ENOENT") {
|
|
154
|
+
console.warn(` \u2717 Routes directory not accessible: ${this.routesDir}`);
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
return routes;
|
|
139
160
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
expose: true
|
|
164
|
-
}
|
|
165
|
-
});
|
|
161
|
+
isExcluded(filePath) {
|
|
162
|
+
const relativePath = relative2(this.routesDir, filePath);
|
|
163
|
+
for (const pattern of this.excludePatterns) {
|
|
164
|
+
const regexPattern = pattern.replace(/\./g, "\\.").replace(/\*/g, "[^/]*").replace(/\*\*/g, ".*").replace(/\?/g, ".");
|
|
165
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
166
|
+
const filename = relativePath.split(sep).pop() || "";
|
|
167
|
+
if (regex.test(relativePath) || regex.test(filename)) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
async scanDirectory(dir, routes, basePath = "") {
|
|
174
|
+
const entries = await fs2.readdir(dir);
|
|
175
|
+
for (const entry of entries) {
|
|
176
|
+
const fullPath = join(dir, entry);
|
|
177
|
+
const stats = await fs2.stat(fullPath);
|
|
178
|
+
if (stats.isDirectory()) {
|
|
179
|
+
const newBasePath = basePath ? `${basePath}/${entry}` : entry;
|
|
180
|
+
await this.scanDirectory(fullPath, routes, newBasePath);
|
|
181
|
+
} else if (entry.endsWith(".ts") || entry.endsWith(".js")) {
|
|
182
|
+
if (this.isExcluded(fullPath)) {
|
|
183
|
+
continue;
|
|
166
184
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
routes.push({
|
|
173
|
-
name,
|
|
174
|
-
path: fullPath,
|
|
175
|
-
method: routeDef.options.method,
|
|
176
|
-
options: routeDef.options
|
|
177
|
-
});
|
|
178
|
-
} else if (Array.isArray(value) && value.length >= 4) {
|
|
179
|
-
const [method, , , path] = value;
|
|
185
|
+
const routePath = relative2(this.routesDir, fullPath).replace(/\.(ts|js)$/, "").split(sep).join("/");
|
|
186
|
+
try {
|
|
187
|
+
const importPath = process.platform === "win32" ? `file:///${fullPath.replace(/\\/g, "/")}` : fullPath;
|
|
188
|
+
const module = await import(importPath);
|
|
189
|
+
if (module.default && typeof module.default === "function") {
|
|
180
190
|
routes.push({
|
|
181
|
-
name,
|
|
191
|
+
name: "default",
|
|
182
192
|
path: fullPath,
|
|
183
|
-
method,
|
|
193
|
+
method: "GET",
|
|
184
194
|
options: {
|
|
185
|
-
method,
|
|
186
|
-
path
|
|
195
|
+
method: "GET",
|
|
196
|
+
path: `/${routePath}`,
|
|
187
197
|
expose: true
|
|
188
198
|
}
|
|
189
199
|
});
|
|
190
200
|
}
|
|
201
|
+
for (const [name, value] of Object.entries(module)) {
|
|
202
|
+
if (name === "default")
|
|
203
|
+
continue;
|
|
204
|
+
if (value && typeof value === "object" && "entry" in value && "options" in value && "handler" in value) {
|
|
205
|
+
const routeDef = value;
|
|
206
|
+
routes.push({
|
|
207
|
+
name,
|
|
208
|
+
path: fullPath,
|
|
209
|
+
method: routeDef.options.method,
|
|
210
|
+
options: routeDef.options
|
|
211
|
+
});
|
|
212
|
+
} else if (Array.isArray(value) && value.length >= 4) {
|
|
213
|
+
const [method, , , path] = value;
|
|
214
|
+
routes.push({
|
|
215
|
+
name,
|
|
216
|
+
path: fullPath,
|
|
217
|
+
method,
|
|
218
|
+
options: {
|
|
219
|
+
method,
|
|
220
|
+
path,
|
|
221
|
+
expose: true
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error(`Failed to load route from ${fullPath}:`, error);
|
|
191
228
|
}
|
|
192
|
-
} catch (error) {
|
|
193
|
-
console.error(`Failed to load route from ${fullPath}:`, error);
|
|
194
229
|
}
|
|
195
230
|
}
|
|
196
231
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
232
|
+
enableWatch(callback) {
|
|
233
|
+
if (typeof Bun !== "undefined" && Bun.env.NODE_ENV === "development") {
|
|
234
|
+
console.log(`Watching for route changes in ${this.routesDir}`);
|
|
235
|
+
setInterval(async () => {
|
|
236
|
+
await callback();
|
|
237
|
+
}, 1000);
|
|
238
|
+
}
|
|
204
239
|
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
var init_route_scanner = () => {};
|
|
240
|
+
};
|
|
241
|
+
});
|
|
208
242
|
|
|
209
243
|
// src/cli/index.ts
|
|
210
244
|
import { watch } from "fs";
|
|
@@ -436,7 +470,11 @@ class MiddlewareManager {
|
|
|
436
470
|
async executeFinally(response, request) {
|
|
437
471
|
let currentResponse = response;
|
|
438
472
|
for (const handler of this.finallyHandlers) {
|
|
439
|
-
|
|
473
|
+
try {
|
|
474
|
+
currentResponse = await handler(currentResponse, request);
|
|
475
|
+
} catch (error) {
|
|
476
|
+
console.error("After middleware error:", error);
|
|
477
|
+
}
|
|
440
478
|
}
|
|
441
479
|
return currentResponse;
|
|
442
480
|
}
|
|
@@ -934,6 +972,9 @@ class Vector {
|
|
|
934
972
|
async startServer(config) {
|
|
935
973
|
this.config = { ...this.config, ...config };
|
|
936
974
|
this.middlewareManager.clear();
|
|
975
|
+
if (this.config.autoDiscover !== false) {
|
|
976
|
+
this.router.clearRoutes();
|
|
977
|
+
}
|
|
937
978
|
if (config?.before) {
|
|
938
979
|
this.middlewareManager.addBefore(...config.before);
|
|
939
980
|
}
|
|
@@ -949,7 +990,8 @@ class Vector {
|
|
|
949
990
|
}
|
|
950
991
|
async discoverRoutes() {
|
|
951
992
|
const routesDir = this.config.routesDir || "./routes";
|
|
952
|
-
|
|
993
|
+
const excludePatterns = this.config.routeExcludePatterns;
|
|
994
|
+
this.routeScanner = new RouteScanner(routesDir, excludePatterns);
|
|
953
995
|
if (!this.routeGenerator) {
|
|
954
996
|
this.routeGenerator = new RouteGenerator;
|
|
955
997
|
}
|
|
@@ -1018,7 +1060,6 @@ class Vector {
|
|
|
1018
1060
|
this.server.stop();
|
|
1019
1061
|
this.server = null;
|
|
1020
1062
|
}
|
|
1021
|
-
this.router.clearRoutes();
|
|
1022
1063
|
}
|
|
1023
1064
|
getServer() {
|
|
1024
1065
|
return this.server;
|
|
@@ -1169,56 +1210,52 @@ async function runDev() {
|
|
|
1169
1210
|
}, 1e4);
|
|
1170
1211
|
});
|
|
1171
1212
|
const serverStartPromise = (async () => {
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
console.log(` ${gray}Mode${reset} ${config.development ? "Development" : "Production"}
|
|
1213
|
+
const configLoader = new ConfigLoader(values.config);
|
|
1214
|
+
const config = await configLoader.load();
|
|
1215
|
+
const configSource = configLoader.getConfigSource();
|
|
1216
|
+
config.port = config.port ?? Number.parseInt(values.port);
|
|
1217
|
+
config.hostname = config.hostname ?? values.host;
|
|
1218
|
+
config.routesDir = config.routesDir ?? values.routes;
|
|
1219
|
+
config.development = config.development ?? isDev;
|
|
1220
|
+
config.autoDiscover = true;
|
|
1221
|
+
if (config.cors === undefined && values.cors) {
|
|
1222
|
+
config.cors = {
|
|
1223
|
+
origin: "*",
|
|
1224
|
+
credentials: true,
|
|
1225
|
+
allowHeaders: "Content-Type, Authorization",
|
|
1226
|
+
allowMethods: "GET, POST, PUT, PATCH, DELETE, OPTIONS",
|
|
1227
|
+
exposeHeaders: "Authorization",
|
|
1228
|
+
maxAge: 86400
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
vector = getVectorInstance();
|
|
1232
|
+
const authHandler = await configLoader.loadAuthHandler();
|
|
1233
|
+
if (authHandler) {
|
|
1234
|
+
vector.setProtectedHandler(authHandler);
|
|
1235
|
+
}
|
|
1236
|
+
const cacheHandler = await configLoader.loadCacheHandler();
|
|
1237
|
+
if (cacheHandler) {
|
|
1238
|
+
vector.setCacheHandler(cacheHandler);
|
|
1239
|
+
}
|
|
1240
|
+
server = await vector.startServer(config);
|
|
1241
|
+
if (!server || !server.port) {
|
|
1242
|
+
throw new Error("Server started but is not responding correctly");
|
|
1243
|
+
}
|
|
1244
|
+
const gray = "\x1B[90m";
|
|
1245
|
+
const reset = "\x1B[0m";
|
|
1246
|
+
const cyan = "\x1B[36m";
|
|
1247
|
+
const green = "\x1B[32m";
|
|
1248
|
+
console.log(` ${gray}Config${reset} ${configSource === "user" ? "User config loaded" : "Using defaults"}`);
|
|
1249
|
+
console.log(` ${gray}Routes${reset} ${config.routesDir}`);
|
|
1250
|
+
if (isDev && values.watch) {
|
|
1251
|
+
console.log(` ${gray}Watching${reset} All project files`);
|
|
1252
|
+
}
|
|
1253
|
+
console.log(` ${gray}CORS${reset} ${config.cors ? "Enabled" : "Disabled"}`);
|
|
1254
|
+
console.log(` ${gray}Mode${reset} ${config.development ? "Development" : "Production"}
|
|
1215
1255
|
`);
|
|
1216
|
-
|
|
1256
|
+
console.log(` ${green}Ready${reset} \u2192 ${cyan}http://${config.hostname}:${config.port}${reset}
|
|
1217
1257
|
`);
|
|
1218
|
-
|
|
1219
|
-
} catch (error) {
|
|
1220
|
-
throw error;
|
|
1221
|
-
}
|
|
1258
|
+
return { server, vector, config };
|
|
1222
1259
|
})();
|
|
1223
1260
|
return await Promise.race([serverStartPromise, timeoutPromise]);
|
|
1224
1261
|
}
|
|
@@ -1250,9 +1287,11 @@ async function runDev() {
|
|
|
1250
1287
|
vector.stop();
|
|
1251
1288
|
}
|
|
1252
1289
|
await new Promise((resolve3) => setTimeout(resolve3, 100));
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1290
|
+
if (__require.cache) {
|
|
1291
|
+
for (const key in __require.cache) {
|
|
1292
|
+
if (!key.includes("node_modules")) {
|
|
1293
|
+
delete __require.cache[key];
|
|
1294
|
+
}
|
|
1256
1295
|
}
|
|
1257
1296
|
}
|
|
1258
1297
|
try {
|
|
@@ -1263,14 +1302,12 @@ async function runDev() {
|
|
|
1263
1302
|
console.error(`
|
|
1264
1303
|
[Reload Error]`, error.message || error);
|
|
1265
1304
|
} finally {
|
|
1266
|
-
|
|
1267
|
-
isReloading = false;
|
|
1268
|
-
}, 2000);
|
|
1305
|
+
isReloading = false;
|
|
1269
1306
|
}
|
|
1270
1307
|
}, 500);
|
|
1271
1308
|
}
|
|
1272
1309
|
});
|
|
1273
|
-
} catch
|
|
1310
|
+
} catch {
|
|
1274
1311
|
console.warn(" \u26A0\uFE0F File watching not available");
|
|
1275
1312
|
}
|
|
1276
1313
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector.d.ts","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKhD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,qBAAa,MAAM,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IACrC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO;IAYP,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,WAAW,GAAG,kBAAkB,KAAK,MAAM,CAAC,CAAC,CAAC;IAQ3E,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC;IAKrD,mBAAmB,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;IAKtD,eAAe,CAAC,OAAO,EAAE,YAAY;IAKrC,eAAe,IAAI,YAAY,GAAG,IAAI;IAKtC,QAAQ,CACN,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,EAC7B,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,GAC5B,UAAU;IAKP,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"vector.d.ts","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAKhD,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,WAAW,EACZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGxC,qBAAa,MAAM,CAAC,MAAM,SAAS,WAAW,GAAG,kBAAkB;IACjE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IACrC,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAqC;IACnD,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO;IAYP,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,WAAW,GAAG,kBAAkB,KAAK,MAAM,CAAC,CAAC,CAAC;IAQ3E,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC;IAKrD,mBAAmB,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG,IAAI;IAKtD,eAAe,CAAC,OAAO,EAAE,YAAY;IAKrC,eAAe,IAAI,YAAY,GAAG,IAAI;IAKtC,QAAQ,CACN,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,EAC7B,OAAO,EAAE,YAAY,CAAC,MAAM,CAAC,GAC5B,UAAU;IAKP,WAAW,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;YA6BnD,cAAc;IAgEtB,SAAS,CAAC,WAAW,EAAE,GAAG;IAkBhC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,cAAc;IAItB,IAAI,IAAI,IAAI;IASZ,SAAS,IAAI,YAAY,CAAC,MAAM,CAAC,GAAG,IAAI;IAIxC,SAAS,IAAI,YAAY,CAAC,MAAM,CAAC;IAIjC,eAAe,IAAI,YAAY,CAAC,MAAM,CAAC;IAIvC,cAAc,IAAI,WAAW,CAAC,MAAM,CAAC;IAKrC,MAAM,CAAC,aAAa,IAAI,IAAI;CAG7B;AAGD,eAAO,MAAM,iBAAiB,2BAAqB,CAAC"}
|
package/dist/core/vector.js
CHANGED
|
@@ -57,6 +57,10 @@ export class Vector {
|
|
|
57
57
|
this.config = { ...this.config, ...config };
|
|
58
58
|
// Clear previous middleware to avoid accumulation across multiple starts
|
|
59
59
|
this.middlewareManager.clear();
|
|
60
|
+
// Only clear routes if we're doing auto-discovery
|
|
61
|
+
if (this.config.autoDiscover !== false) {
|
|
62
|
+
this.router.clearRoutes();
|
|
63
|
+
}
|
|
60
64
|
if (config?.before) {
|
|
61
65
|
this.middlewareManager.addBefore(...config.before);
|
|
62
66
|
}
|
|
@@ -72,9 +76,10 @@ export class Vector {
|
|
|
72
76
|
}
|
|
73
77
|
async discoverRoutes() {
|
|
74
78
|
const routesDir = this.config.routesDir || "./routes";
|
|
79
|
+
const excludePatterns = this.config.routeExcludePatterns;
|
|
75
80
|
// Always create a new RouteScanner with the current config's routesDir
|
|
76
81
|
// to ensure we're using the correct path from the user's config
|
|
77
|
-
this.routeScanner = new RouteScanner(routesDir);
|
|
82
|
+
this.routeScanner = new RouteScanner(routesDir, excludePatterns);
|
|
78
83
|
if (!this.routeGenerator) {
|
|
79
84
|
this.routeGenerator = new RouteGenerator();
|
|
80
85
|
}
|
|
@@ -158,9 +163,8 @@ export class Vector {
|
|
|
158
163
|
this.server.stop();
|
|
159
164
|
this.server = null;
|
|
160
165
|
}
|
|
161
|
-
// Don't reset managers - they
|
|
162
|
-
//
|
|
163
|
-
this.router.clearRoutes();
|
|
166
|
+
// Don't reset managers or routes - they persist for the singleton
|
|
167
|
+
// Routes will be cleared on next startServer() call
|
|
164
168
|
}
|
|
165
169
|
getServer() {
|
|
166
170
|
return this.server;
|
package/dist/core/vector.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"vector.js","sourceRoot":"","sources":["../../src/core/vector.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import type { GeneratedRoute } from
|
|
1
|
+
import type { GeneratedRoute } from "../types";
|
|
2
2
|
export declare class RouteScanner {
|
|
3
3
|
private routesDir;
|
|
4
|
-
|
|
4
|
+
private excludePatterns;
|
|
5
|
+
private static readonly DEFAULT_EXCLUDE_PATTERNS;
|
|
6
|
+
constructor(routesDir?: string, excludePatterns?: string[]);
|
|
5
7
|
scan(): Promise<GeneratedRoute[]>;
|
|
8
|
+
private isExcluded;
|
|
6
9
|
private scanDirectory;
|
|
7
10
|
enableWatch(callback: () => void): void;
|
|
8
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-scanner.d.ts","sourceRoot":"","sources":["../../src/dev/route-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAS;
|
|
1
|
+
{"version":3,"file":"route-scanner.d.ts","sourceRoot":"","sources":["../../src/dev/route-scanner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAe9C;gBAEU,SAAS,SAAa,EAAE,eAAe,CAAC,EAAE,MAAM,EAAE;IAOxD,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAqBvC,OAAO,CAAC,UAAU;YAuBJ,aAAa;IAuF3B,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI;CASjC"}
|
|
@@ -1,10 +1,29 @@
|
|
|
1
|
-
import { existsSync, promises as fs } from
|
|
2
|
-
import { join, relative, resolve, sep } from
|
|
1
|
+
import { existsSync, promises as fs } from "node:fs";
|
|
2
|
+
import { join, relative, resolve, sep } from "node:path";
|
|
3
3
|
export class RouteScanner {
|
|
4
4
|
routesDir;
|
|
5
|
-
|
|
5
|
+
excludePatterns;
|
|
6
|
+
static DEFAULT_EXCLUDE_PATTERNS = [
|
|
7
|
+
"*.test.ts",
|
|
8
|
+
"*.test.js",
|
|
9
|
+
"*.test.tsx",
|
|
10
|
+
"*.test.jsx",
|
|
11
|
+
"*.spec.ts",
|
|
12
|
+
"*.spec.js",
|
|
13
|
+
"*.spec.tsx",
|
|
14
|
+
"*.spec.jsx",
|
|
15
|
+
"*.tests.ts",
|
|
16
|
+
"*.tests.js",
|
|
17
|
+
"**/__tests__/**",
|
|
18
|
+
"*.interface.ts",
|
|
19
|
+
"*.type.ts",
|
|
20
|
+
"*.d.ts",
|
|
21
|
+
];
|
|
22
|
+
constructor(routesDir = "./routes", excludePatterns) {
|
|
6
23
|
// Always resolve from the current working directory (user's project)
|
|
7
24
|
this.routesDir = resolve(process.cwd(), routesDir);
|
|
25
|
+
this.excludePatterns =
|
|
26
|
+
excludePatterns || RouteScanner.DEFAULT_EXCLUDE_PATTERNS;
|
|
8
27
|
}
|
|
9
28
|
async scan() {
|
|
10
29
|
const routes = [];
|
|
@@ -16,7 +35,7 @@ export class RouteScanner {
|
|
|
16
35
|
await this.scanDirectory(this.routesDir, routes);
|
|
17
36
|
}
|
|
18
37
|
catch (error) {
|
|
19
|
-
if (error.code ===
|
|
38
|
+
if (error.code === "ENOENT") {
|
|
20
39
|
console.warn(` ✗ Routes directory not accessible: ${this.routesDir}`);
|
|
21
40
|
return [];
|
|
22
41
|
}
|
|
@@ -24,7 +43,25 @@ export class RouteScanner {
|
|
|
24
43
|
}
|
|
25
44
|
return routes;
|
|
26
45
|
}
|
|
27
|
-
|
|
46
|
+
isExcluded(filePath) {
|
|
47
|
+
const relativePath = relative(this.routesDir, filePath);
|
|
48
|
+
for (const pattern of this.excludePatterns) {
|
|
49
|
+
// Convert glob pattern to regex
|
|
50
|
+
const regexPattern = pattern
|
|
51
|
+
.replace(/\./g, "\\.") // Escape dots
|
|
52
|
+
.replace(/\*/g, "[^/]*") // * matches anything except /
|
|
53
|
+
.replace(/\*\*/g, ".*") // ** matches anything including /
|
|
54
|
+
.replace(/\?/g, "."); // ? matches single character
|
|
55
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
56
|
+
// Check both the full relative path and just the filename
|
|
57
|
+
const filename = relativePath.split(sep).pop() || "";
|
|
58
|
+
if (regex.test(relativePath) || regex.test(filename)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
async scanDirectory(dir, routes, basePath = "") {
|
|
28
65
|
const entries = await fs.readdir(dir);
|
|
29
66
|
for (const entry of entries) {
|
|
30
67
|
const fullPath = join(dir, entry);
|
|
@@ -33,32 +70,42 @@ export class RouteScanner {
|
|
|
33
70
|
const newBasePath = basePath ? `${basePath}/${entry}` : entry;
|
|
34
71
|
await this.scanDirectory(fullPath, routes, newBasePath);
|
|
35
72
|
}
|
|
36
|
-
else if (entry.endsWith(
|
|
73
|
+
else if (entry.endsWith(".ts") || entry.endsWith(".js")) {
|
|
74
|
+
// Skip excluded files (test files, etc.)
|
|
75
|
+
if (this.isExcluded(fullPath)) {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
37
78
|
const routePath = relative(this.routesDir, fullPath)
|
|
38
|
-
.replace(/\.(ts|js)$/,
|
|
79
|
+
.replace(/\.(ts|js)$/, "")
|
|
39
80
|
.split(sep)
|
|
40
|
-
.join(
|
|
81
|
+
.join("/");
|
|
41
82
|
try {
|
|
42
83
|
// Convert Windows paths to URLs for import
|
|
43
|
-
const importPath = process.platform ===
|
|
84
|
+
const importPath = process.platform === "win32"
|
|
85
|
+
? `file:///${fullPath.replace(/\\/g, "/")}`
|
|
86
|
+
: fullPath;
|
|
44
87
|
const module = await import(importPath);
|
|
45
|
-
if (module.default && typeof module.default ===
|
|
88
|
+
if (module.default && typeof module.default === "function") {
|
|
46
89
|
routes.push({
|
|
47
|
-
name:
|
|
90
|
+
name: "default",
|
|
48
91
|
path: fullPath,
|
|
49
|
-
method:
|
|
92
|
+
method: "GET",
|
|
50
93
|
options: {
|
|
51
|
-
method:
|
|
94
|
+
method: "GET",
|
|
52
95
|
path: `/${routePath}`,
|
|
53
96
|
expose: true,
|
|
54
97
|
},
|
|
55
98
|
});
|
|
56
99
|
}
|
|
57
100
|
for (const [name, value] of Object.entries(module)) {
|
|
58
|
-
if (name ===
|
|
101
|
+
if (name === "default")
|
|
59
102
|
continue;
|
|
60
103
|
// Check for new RouteDefinition format
|
|
61
|
-
if (value &&
|
|
104
|
+
if (value &&
|
|
105
|
+
typeof value === "object" &&
|
|
106
|
+
"entry" in value &&
|
|
107
|
+
"options" in value &&
|
|
108
|
+
"handler" in value) {
|
|
62
109
|
const routeDef = value;
|
|
63
110
|
routes.push({
|
|
64
111
|
name,
|
|
@@ -90,7 +137,7 @@ export class RouteScanner {
|
|
|
90
137
|
}
|
|
91
138
|
}
|
|
92
139
|
enableWatch(callback) {
|
|
93
|
-
if (typeof Bun !==
|
|
140
|
+
if (typeof Bun !== "undefined" && Bun.env.NODE_ENV === "development") {
|
|
94
141
|
console.log(`Watching for route changes in ${this.routesDir}`);
|
|
95
142
|
setInterval(async () => {
|
|
96
143
|
await callback();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-scanner.js","sourceRoot":"","sources":["../../src/dev/route-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGzD,MAAM,OAAO,YAAY;IACf,SAAS,CAAS;
|
|
1
|
+
{"version":3,"file":"route-scanner.js","sourceRoot":"","sources":["../../src/dev/route-scanner.ts"],"names":[],"mappings":"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"}
|