vector-framework 1.0.0 → 1.2.0
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 +87 -634
- package/dist/auth/protected.d.ts.map +1 -1
- package/dist/auth/protected.js.map +1 -1
- package/dist/cache/manager.d.ts +5 -2
- package/dist/cache/manager.d.ts.map +1 -1
- package/dist/cache/manager.js +21 -12
- package/dist/cache/manager.js.map +1 -1
- package/dist/cli/index.js +60 -126
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/option-resolution.d.ts +4 -0
- package/dist/cli/option-resolution.d.ts.map +1 -0
- package/dist/cli/option-resolution.js +28 -0
- package/dist/cli/option-resolution.js.map +1 -0
- package/dist/cli.js +2774 -599
- package/dist/constants/index.d.ts +3 -0
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +6 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/core/config-loader.d.ts +2 -2
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +18 -18
- package/dist/core/config-loader.js.map +1 -1
- package/dist/core/router.d.ts +41 -15
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +465 -150
- package/dist/core/router.js.map +1 -1
- package/dist/core/server.d.ts +17 -3
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +274 -33
- package/dist/core/server.js.map +1 -1
- package/dist/core/vector.d.ts +9 -8
- package/dist/core/vector.d.ts.map +1 -1
- package/dist/core/vector.js +40 -32
- package/dist/core/vector.js.map +1 -1
- package/dist/dev/route-generator.d.ts.map +1 -1
- package/dist/dev/route-generator.js.map +1 -1
- package/dist/dev/route-scanner.d.ts +1 -1
- package/dist/dev/route-scanner.d.ts.map +1 -1
- package/dist/dev/route-scanner.js +37 -43
- package/dist/dev/route-scanner.js.map +1 -1
- package/dist/http.d.ts +14 -14
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +84 -84
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1314 -8
- package/dist/index.mjs +1314 -8
- package/dist/middleware/manager.d.ts +1 -1
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +4 -0
- package/dist/middleware/manager.js.map +1 -1
- package/dist/openapi/docs-ui.d.ts +2 -0
- package/dist/openapi/docs-ui.d.ts.map +1 -0
- package/dist/openapi/docs-ui.js +1313 -0
- package/dist/openapi/docs-ui.js.map +1 -0
- package/dist/openapi/generator.d.ts +12 -0
- package/dist/openapi/generator.d.ts.map +1 -0
- package/dist/openapi/generator.js +273 -0
- package/dist/openapi/generator.js.map +1 -0
- package/dist/types/index.d.ts +70 -11
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/standard-schema.d.ts +118 -0
- package/dist/types/standard-schema.d.ts.map +1 -0
- package/dist/types/standard-schema.js +2 -0
- package/dist/types/standard-schema.js.map +1 -0
- package/dist/utils/cors.d.ts +13 -0
- package/dist/utils/cors.d.ts.map +1 -0
- package/dist/utils/cors.js +89 -0
- package/dist/utils/cors.js.map +1 -0
- package/dist/utils/path.d.ts +7 -0
- package/dist/utils/path.d.ts.map +1 -1
- package/dist/utils/path.js +14 -3
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/schema-validation.d.ts +31 -0
- package/dist/utils/schema-validation.d.ts.map +1 -0
- package/dist/utils/schema-validation.js +77 -0
- package/dist/utils/schema-validation.js.map +1 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +1 -0
- package/dist/utils/validation.js.map +1 -1
- package/package.json +24 -19
- package/src/auth/protected.ts +3 -13
- package/src/cache/manager.ts +25 -30
- package/src/cli/index.ts +62 -141
- package/src/cli/option-resolution.ts +40 -0
- package/src/constants/index.ts +7 -0
- package/src/core/config-loader.ts +20 -22
- package/src/core/router.ts +535 -155
- package/src/core/server.ts +354 -45
- package/src/core/vector.ts +71 -61
- package/src/dev/route-generator.ts +1 -3
- package/src/dev/route-scanner.ts +38 -51
- package/src/http.ts +117 -187
- package/src/index.ts +3 -3
- package/src/middleware/manager.ts +8 -11
- package/src/openapi/assets/tailwindcdn.js +83 -0
- package/src/openapi/docs-ui.ts +1317 -0
- package/src/openapi/generator.ts +359 -0
- package/src/types/index.ts +104 -17
- package/src/types/standard-schema.ts +147 -0
- package/src/utils/cors.ts +101 -0
- package/src/utils/path.ts +19 -4
- package/src/utils/schema-validation.ts +123 -0
- package/src/utils/validation.ts +1 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
function getAllowedOrigin(origin, config) {
|
|
2
|
+
if (!origin) {
|
|
3
|
+
if (typeof config.origin === 'string') {
|
|
4
|
+
// Credentials cannot be combined with wildcard; only reflect concrete request origins.
|
|
5
|
+
if (config.origin === '*' && config.credentials)
|
|
6
|
+
return null;
|
|
7
|
+
return config.origin;
|
|
8
|
+
}
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
if (typeof config.origin === 'string') {
|
|
12
|
+
if (config.origin === '*') {
|
|
13
|
+
return config.credentials ? origin : '*';
|
|
14
|
+
}
|
|
15
|
+
return config.origin === origin ? origin : null;
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(config.origin)) {
|
|
18
|
+
return config.origin.includes(origin) ? origin : null;
|
|
19
|
+
}
|
|
20
|
+
if (typeof config.origin === 'function') {
|
|
21
|
+
return config.origin(origin) ? origin : null;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function shouldVaryByOrigin(config) {
|
|
26
|
+
return ((typeof config.origin === 'string' && config.origin === '*' && config.credentials) ||
|
|
27
|
+
Array.isArray(config.origin) ||
|
|
28
|
+
typeof config.origin === 'function');
|
|
29
|
+
}
|
|
30
|
+
function buildCorsHeaders(origin, config, varyByOrigin) {
|
|
31
|
+
const headers = {};
|
|
32
|
+
if (origin) {
|
|
33
|
+
headers['access-control-allow-origin'] = origin;
|
|
34
|
+
headers['access-control-allow-methods'] = config.allowMethods;
|
|
35
|
+
headers['access-control-allow-headers'] = config.allowHeaders;
|
|
36
|
+
headers['access-control-expose-headers'] = config.exposeHeaders;
|
|
37
|
+
headers['access-control-max-age'] = String(config.maxAge);
|
|
38
|
+
if (config.credentials) {
|
|
39
|
+
headers['access-control-allow-credentials'] = 'true';
|
|
40
|
+
}
|
|
41
|
+
if (varyByOrigin) {
|
|
42
|
+
headers.vary = 'Origin';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return headers;
|
|
46
|
+
}
|
|
47
|
+
function mergeVary(existing, nextValue) {
|
|
48
|
+
if (!existing)
|
|
49
|
+
return nextValue;
|
|
50
|
+
const parts = existing
|
|
51
|
+
.split(',')
|
|
52
|
+
.map((v) => v.trim())
|
|
53
|
+
.filter(Boolean);
|
|
54
|
+
const lower = parts.map((v) => v.toLowerCase());
|
|
55
|
+
if (!lower.includes(nextValue.toLowerCase())) {
|
|
56
|
+
parts.push(nextValue);
|
|
57
|
+
}
|
|
58
|
+
return parts.join(', ');
|
|
59
|
+
}
|
|
60
|
+
export function cors(config) {
|
|
61
|
+
return {
|
|
62
|
+
preflight(request) {
|
|
63
|
+
const origin = request.headers.get('origin') ?? undefined;
|
|
64
|
+
const allowed = getAllowedOrigin(origin, config);
|
|
65
|
+
const varyByOrigin = Boolean(origin && allowed && shouldVaryByOrigin(config));
|
|
66
|
+
return new Response(null, {
|
|
67
|
+
status: 204,
|
|
68
|
+
headers: buildCorsHeaders(allowed, config, varyByOrigin),
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
corsify(response, request) {
|
|
72
|
+
const origin = request.headers.get('origin') ?? undefined;
|
|
73
|
+
const allowed = getAllowedOrigin(origin, config);
|
|
74
|
+
if (!allowed)
|
|
75
|
+
return response;
|
|
76
|
+
const varyByOrigin = Boolean(origin && shouldVaryByOrigin(config));
|
|
77
|
+
const headers = buildCorsHeaders(allowed, config, varyByOrigin);
|
|
78
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
79
|
+
if (k === 'vary') {
|
|
80
|
+
response.headers.set('vary', mergeVary(response.headers.get('vary'), v));
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
response.headers.set(k, v);
|
|
84
|
+
}
|
|
85
|
+
return response;
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/utils/cors.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/path.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export declare function toFileUrl(path: string): string;
|
|
2
2
|
export declare function normalizePath(path: string): string;
|
|
3
|
+
export declare function buildRouteRegex(path: string): RegExp;
|
|
4
|
+
declare const _default: {
|
|
5
|
+
toFileUrl: typeof toFileUrl;
|
|
6
|
+
normalizePath: typeof normalizePath;
|
|
7
|
+
buildRouteRegex: typeof buildRouteRegex;
|
|
8
|
+
};
|
|
9
|
+
export default _default;
|
|
3
10
|
//# sourceMappingURL=path.d.ts.map
|
package/dist/utils/path.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASpD;;;;;;AAED,wBAIE"}
|
package/dist/utils/path.js
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
export function toFileUrl(path) {
|
|
2
|
-
return process.platform === 'win32'
|
|
3
|
-
? `file:///${path.replace(/\\/g, '/')}`
|
|
4
|
-
: path;
|
|
2
|
+
return process.platform === 'win32' ? `file:///${path.replace(/\\/g, '/')}` : path;
|
|
5
3
|
}
|
|
6
4
|
export function normalizePath(path) {
|
|
7
5
|
return path.replace(/\\/g, '/').replace(/\/+/g, '/');
|
|
8
6
|
}
|
|
7
|
+
export function buildRouteRegex(path) {
|
|
8
|
+
return RegExp(`^${path
|
|
9
|
+
.replace(/\/+(\/|$)/g, '$1')
|
|
10
|
+
.replace(/(\/?\.?):(\w+)\+/g, '($1(?<$2>[\\s\\S]+))')
|
|
11
|
+
.replace(/(\/?\.?):(\w+)/g, '($1(?<$2>[^$1/]+?))')
|
|
12
|
+
.replace(/\./g, '\\.')
|
|
13
|
+
.replace(/(\/?)\*/g, '($1.*)?')}/*$`);
|
|
14
|
+
}
|
|
15
|
+
export default {
|
|
16
|
+
toFileUrl,
|
|
17
|
+
normalizePath,
|
|
18
|
+
buildRouteRegex,
|
|
19
|
+
};
|
|
9
20
|
//# sourceMappingURL=path.js.map
|
package/dist/utils/path.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,MAAM,CACX,IAAI,IAAI;SACL,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC;SAC3B,OAAO,CAAC,mBAAmB,EAAE,sBAAsB,CAAC;SACpD,OAAO,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;SACjD,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,KAAK,CACvC,CAAC;AACJ,CAAC;AAED,eAAe;IACb,SAAS;IACT,aAAa;IACb,eAAe;CAChB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StandardRouteSchema } from '../types';
|
|
2
|
+
export interface NormalizedValidationIssue {
|
|
3
|
+
message: string;
|
|
4
|
+
path: Array<string | number>;
|
|
5
|
+
code?: string;
|
|
6
|
+
raw?: unknown;
|
|
7
|
+
}
|
|
8
|
+
interface StandardValidationSuccess {
|
|
9
|
+
success: true;
|
|
10
|
+
value: unknown;
|
|
11
|
+
}
|
|
12
|
+
interface StandardValidationFailure {
|
|
13
|
+
success: false;
|
|
14
|
+
issues: readonly unknown[];
|
|
15
|
+
}
|
|
16
|
+
export type StandardValidationResult = StandardValidationSuccess | StandardValidationFailure;
|
|
17
|
+
export declare function isStandardRouteSchema(schema: unknown): schema is StandardRouteSchema;
|
|
18
|
+
export declare function runStandardValidation(schema: StandardRouteSchema, value: unknown): Promise<StandardValidationResult>;
|
|
19
|
+
export declare function extractThrownIssues(error: unknown): readonly unknown[] | null;
|
|
20
|
+
export declare function normalizeValidationIssues(issues: readonly unknown[], includeRawIssues: boolean): NormalizedValidationIssue[];
|
|
21
|
+
export declare function createValidationErrorPayload(target: 'input' | 'output', issues: NormalizedValidationIssue[]): {
|
|
22
|
+
error: boolean;
|
|
23
|
+
message: string;
|
|
24
|
+
statusCode: number;
|
|
25
|
+
source: string;
|
|
26
|
+
target: "input" | "output";
|
|
27
|
+
issues: NormalizedValidationIssue[];
|
|
28
|
+
timestamp: string;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=schema-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-validation.d.ts","sourceRoot":"","sources":["../../src/utils/schema-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,UAAU,yBAAyB;IACjC,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,yBAAyB;IACjC,OAAO,EAAE,KAAK,CAAC;IACf,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,wBAAwB,GAAG,yBAAyB,GAAG,yBAAyB,CAAC;AAE7F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,mBAAmB,CAKpF;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,wBAAwB,CAAC,CASnC;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,OAAO,EAAE,GAAG,IAAI,CAc7E;AA2BD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,gBAAgB,EAAE,OAAO,GACxB,yBAAyB,EAAE,CAwB7B;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,EAAE,MAAM,EAAE,yBAAyB,EAAE;;;;;;;;EAU3G"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export function isStandardRouteSchema(schema) {
|
|
2
|
+
const standard = schema?.['~standard'];
|
|
3
|
+
return (!!standard && typeof standard === 'object' && typeof standard.validate === 'function' && standard.version === 1);
|
|
4
|
+
}
|
|
5
|
+
export async function runStandardValidation(schema, value) {
|
|
6
|
+
const result = await schema['~standard'].validate(value);
|
|
7
|
+
const issues = result?.issues;
|
|
8
|
+
if (Array.isArray(issues) && issues.length > 0) {
|
|
9
|
+
return { success: false, issues };
|
|
10
|
+
}
|
|
11
|
+
return { success: true, value: result?.value };
|
|
12
|
+
}
|
|
13
|
+
export function extractThrownIssues(error) {
|
|
14
|
+
if (Array.isArray(error)) {
|
|
15
|
+
return error;
|
|
16
|
+
}
|
|
17
|
+
if (error && typeof error === 'object' && Array.isArray(error.issues)) {
|
|
18
|
+
return error.issues;
|
|
19
|
+
}
|
|
20
|
+
if (error && typeof error === 'object' && error.cause && Array.isArray(error.cause.issues)) {
|
|
21
|
+
return error.cause.issues;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
function normalizePath(path) {
|
|
26
|
+
if (!Array.isArray(path))
|
|
27
|
+
return [];
|
|
28
|
+
const normalized = [];
|
|
29
|
+
for (let i = 0; i < path.length; i++) {
|
|
30
|
+
const segment = path[i];
|
|
31
|
+
let value = segment;
|
|
32
|
+
if (segment && typeof segment === 'object' && 'key' in segment) {
|
|
33
|
+
value = segment.key;
|
|
34
|
+
}
|
|
35
|
+
if (typeof value === 'string' || typeof value === 'number') {
|
|
36
|
+
normalized.push(value);
|
|
37
|
+
}
|
|
38
|
+
else if (typeof value === 'symbol') {
|
|
39
|
+
normalized.push(String(value));
|
|
40
|
+
}
|
|
41
|
+
else if (value !== undefined && value !== null) {
|
|
42
|
+
normalized.push(String(value));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return normalized;
|
|
46
|
+
}
|
|
47
|
+
export function normalizeValidationIssues(issues, includeRawIssues) {
|
|
48
|
+
const normalized = [];
|
|
49
|
+
for (let i = 0; i < issues.length; i++) {
|
|
50
|
+
const issue = issues[i];
|
|
51
|
+
const maybeIssue = issue;
|
|
52
|
+
const normalizedIssue = {
|
|
53
|
+
message: typeof maybeIssue?.message === 'string' && maybeIssue.message.length > 0 ? maybeIssue.message : 'Invalid value',
|
|
54
|
+
path: normalizePath(maybeIssue?.path),
|
|
55
|
+
};
|
|
56
|
+
if (typeof maybeIssue?.code === 'string') {
|
|
57
|
+
normalizedIssue.code = maybeIssue.code;
|
|
58
|
+
}
|
|
59
|
+
if (includeRawIssues) {
|
|
60
|
+
normalizedIssue.raw = issue;
|
|
61
|
+
}
|
|
62
|
+
normalized.push(normalizedIssue);
|
|
63
|
+
}
|
|
64
|
+
return normalized;
|
|
65
|
+
}
|
|
66
|
+
export function createValidationErrorPayload(target, issues) {
|
|
67
|
+
return {
|
|
68
|
+
error: true,
|
|
69
|
+
message: 'Validation failed',
|
|
70
|
+
statusCode: 422,
|
|
71
|
+
source: 'validation',
|
|
72
|
+
target,
|
|
73
|
+
issues,
|
|
74
|
+
timestamp: new Date().toISOString(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=schema-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-validation.js","sourceRoot":"","sources":["../../src/utils/schema-validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAejE;AAiCD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
package/dist/utils/validation.js
CHANGED
|
@@ -7,6 +7,7 @@ export function validateConfig(config) {
|
|
|
7
7
|
development: config.development || false,
|
|
8
8
|
routesDir: config.routesDir || DEFAULT_CONFIG.ROUTES_DIR,
|
|
9
9
|
autoDiscover: config.autoDiscover !== false,
|
|
10
|
+
defaults: config.defaults,
|
|
10
11
|
cors: config.cors ? validateCorsOptions(config.cors) : undefined,
|
|
11
12
|
before: config.before || [],
|
|
12
13
|
finally: config.finally || [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,eAAe,GAAiB;QACpC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ;QACpD,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,KAAK;QACrC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK;QACxC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC,UAAU;QACxD,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,KAAK;QAC3C,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAChE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;KAC9B,CAAC;IAEF,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,IAAa;IACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,cAAc,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,qCAAqC,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,IAA2B;IACtD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;YAC/C,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;YAClE,aAAa,EAAE,CAAC,eAAe,CAAC;YAChC,MAAM,EAAE,cAAc,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAClF,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC"}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,UAAU,cAAc,CAAC,MAAoB;IACjD,MAAM,eAAe,GAAiB;QACpC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ;QACpD,SAAS,EAAE,MAAM,CAAC,SAAS,KAAK,KAAK;QACrC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,KAAK;QACxC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC,UAAU;QACxD,YAAY,EAAE,MAAM,CAAC,YAAY,KAAK,KAAK;QAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QAChE,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;KAC9B,CAAC;IAEF,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,SAAS,YAAY,CAAC,IAAa;IACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,cAAc,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,qCAAqC,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,mBAAmB,CAAC,IAA2B;IACtD,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,IAAI;YACjB,YAAY,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;YAC/C,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;YAClE,aAAa,EAAE,CAAC,eAAe,CAAC;YAChC,MAAM,EAAE,cAAc,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAClF,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AACrD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vector-framework",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"author": "webhie-com",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,13 +8,14 @@
|
|
|
8
8
|
},
|
|
9
9
|
"main": "./dist/index.js",
|
|
10
10
|
"module": "./dist/index.mjs",
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"itty-router": "^5.0.0"
|
|
13
|
-
},
|
|
11
|
+
"dependencies": {},
|
|
14
12
|
"devDependencies": {
|
|
13
|
+
"@biomejs/biome": "^2.4.6",
|
|
14
|
+
"@biomejs/cli-darwin-arm64": "^2.4.6",
|
|
15
15
|
"@types/bun": "latest",
|
|
16
16
|
"oxlint": "^1.15.0",
|
|
17
|
-
"typescript": "^5.0.0"
|
|
17
|
+
"typescript": "^5.0.0",
|
|
18
|
+
"zod": "^4.3.6"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
20
21
|
"bun": ">=1.0.0"
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
"bugs": {
|
|
48
49
|
"url": "https://github.com/webhie-com/vector/issues"
|
|
49
50
|
},
|
|
50
|
-
"description": "A modern TypeScript API framework built with Bun
|
|
51
|
+
"description": "A modern TypeScript API framework built with Bun",
|
|
51
52
|
"engines": {
|
|
52
53
|
"bun": ">=1.0.0"
|
|
53
54
|
},
|
|
@@ -63,7 +64,6 @@
|
|
|
63
64
|
"api",
|
|
64
65
|
"framework",
|
|
65
66
|
"bun",
|
|
66
|
-
"itty-router",
|
|
67
67
|
"typescript",
|
|
68
68
|
"rest",
|
|
69
69
|
"http",
|
|
@@ -75,32 +75,37 @@
|
|
|
75
75
|
"scripts": {
|
|
76
76
|
"dev": "bun run src/cli/index.ts dev",
|
|
77
77
|
"start": "bun run src/cli/index.ts start",
|
|
78
|
-
"build": "bun run
|
|
79
|
-
"build:app": "bun run src/cli/index.ts build",
|
|
78
|
+
"build": "bun run build:lib",
|
|
80
79
|
"build:lib": "bun run build:clean && bun run build:ts && bun run build:bundle && bun run build:cli",
|
|
81
80
|
"build:clean": "rm -rf dist",
|
|
82
81
|
"build:ts": "tsc",
|
|
83
82
|
"build:bundle": "bun build src/index.ts --format esm --minify --outfile dist/index.mjs && bun build src/index.ts --format cjs --minify --outfile dist/index.js",
|
|
84
83
|
"build:cli": "bun build src/cli/index.ts --target bun --outfile dist/cli.js",
|
|
85
|
-
"
|
|
84
|
+
"local:cli:build": "bun run build:lib",
|
|
85
|
+
"local:cli:dev": "bun run dist/cli.js dev --config ./vector.config.ts",
|
|
86
|
+
"local:cli:start": "bun run dist/cli.js start --config ./vector.config.ts",
|
|
87
|
+
"test": "bun test ./tests/*.test.ts",
|
|
86
88
|
"test:unit": "bun test tests/*.test.ts",
|
|
87
89
|
"test:watch": "bun test --watch tests/*.test.ts",
|
|
88
90
|
"test:coverage": "bun test --coverage tests/*.test.ts",
|
|
89
|
-
"test:e2e": "bun test tests/e2e/e2e.test.ts",
|
|
91
|
+
"test:e2e": "bun test --max-concurrency 1 tests/e2e/e2e.test.ts tests/e2e/zod-io.e2e.test.ts",
|
|
90
92
|
"test:load": "bun run tests/e2e/load.test.ts",
|
|
91
93
|
"test:soak": "bun run tests/e2e/soak.test.ts",
|
|
92
94
|
"test:benchmark": "bun run tests/e2e/benchmark.test.ts",
|
|
93
|
-
"test:
|
|
95
|
+
"test:benchmark:io-schema": "bun run tests/e2e/concurrency-io-schema-benchmark.ts",
|
|
96
|
+
"test:all": "bun test ./tests/**/*.test.ts",
|
|
94
97
|
"test:perf": "bun run test:load && bun run test:soak && bun run test:benchmark",
|
|
95
98
|
"docker:build": "docker build -t vector:latest .",
|
|
96
99
|
"docker:build:test": "docker build -t vector:test --target test .",
|
|
97
|
-
"docker:run": "docker
|
|
98
|
-
"docker:run:dev": "docker
|
|
99
|
-
"docker:test": "docker
|
|
100
|
-
"docker:test:unit": "docker
|
|
101
|
-
"docker:test:e2e": "docker
|
|
102
|
-
"docker:test:load": "docker
|
|
103
|
-
"docker:test:benchmark": "docker
|
|
100
|
+
"docker:run": "docker compose up",
|
|
101
|
+
"docker:run:dev": "docker compose --profile dev up",
|
|
102
|
+
"docker:test": "docker compose -f docker-compose.test.yml run test-all",
|
|
103
|
+
"docker:test:unit": "docker compose -f docker-compose.test.yml run test-unit",
|
|
104
|
+
"docker:test:e2e": "docker compose -f docker-compose.test.yml run test-e2e",
|
|
105
|
+
"docker:test:load": "docker compose -f docker-compose.test.yml run test-load",
|
|
106
|
+
"docker:test:benchmark": "docker compose -f docker-compose.test.yml run test-benchmark",
|
|
107
|
+
"format": "biome format --write .",
|
|
108
|
+
"format:check": "biome format .",
|
|
104
109
|
"lint": "oxlint .",
|
|
105
110
|
"lint:fix": "oxlint . --fix",
|
|
106
111
|
"typecheck": "tsc --noEmit",
|
package/src/auth/protected.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
DefaultVectorTypes,
|
|
3
|
-
GetAuthType,
|
|
4
|
-
ProtectedHandler,
|
|
5
|
-
VectorRequest,
|
|
6
|
-
VectorTypes,
|
|
7
|
-
} from '../types';
|
|
1
|
+
import type { DefaultVectorTypes, GetAuthType, ProtectedHandler, VectorRequest, VectorTypes } from '../types';
|
|
8
2
|
|
|
9
3
|
export class AuthManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
10
4
|
private protectedHandler: ProtectedHandler<TTypes> | null = null;
|
|
@@ -15,9 +9,7 @@ export class AuthManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
15
9
|
|
|
16
10
|
async authenticate(request: VectorRequest<TTypes>): Promise<GetAuthType<TTypes> | null> {
|
|
17
11
|
if (!this.protectedHandler) {
|
|
18
|
-
throw new Error(
|
|
19
|
-
'Protected handler not configured. Use vector.protected() to set authentication handler.'
|
|
20
|
-
);
|
|
12
|
+
throw new Error('Protected handler not configured. Use vector.protected() to set authentication handler.');
|
|
21
13
|
}
|
|
22
14
|
|
|
23
15
|
try {
|
|
@@ -25,9 +17,7 @@ export class AuthManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
25
17
|
request.authUser = authUser;
|
|
26
18
|
return authUser;
|
|
27
19
|
} catch (error) {
|
|
28
|
-
throw new Error(
|
|
29
|
-
`Authentication failed: ${error instanceof Error ? error.message : String(error)}`
|
|
30
|
-
);
|
|
20
|
+
throw new Error(`Authentication failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
31
21
|
}
|
|
32
22
|
}
|
|
33
23
|
|
package/src/cache/manager.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import { DEFAULT_CONFIG } from
|
|
2
|
-
import type {
|
|
3
|
-
CacheHandler,
|
|
4
|
-
DefaultVectorTypes,
|
|
5
|
-
GetCacheType,
|
|
6
|
-
VectorTypes,
|
|
7
|
-
} from "../types";
|
|
1
|
+
import { DEFAULT_CONFIG } from '../constants';
|
|
2
|
+
import type { CacheHandler, DefaultVectorTypes, GetCacheType, VectorTypes } from '../types';
|
|
8
3
|
|
|
9
4
|
interface CacheEntry<T = any> {
|
|
10
5
|
value: T;
|
|
@@ -15,6 +10,7 @@ export class CacheManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
15
10
|
private cacheHandler: CacheHandler | null = null;
|
|
16
11
|
private memoryCache: Map<string, CacheEntry> = new Map();
|
|
17
12
|
private cleanupInterval: Timer | null = null;
|
|
13
|
+
private inflight: Map<string, Promise<any>> = new Map();
|
|
18
14
|
|
|
19
15
|
setCacheHandler(handler: CacheHandler) {
|
|
20
16
|
this.cacheHandler = handler;
|
|
@@ -36,11 +32,7 @@ export class CacheManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
36
32
|
return this.getFromMemoryCache(key, factory, ttl);
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
private async getFromMemoryCache<T>(
|
|
40
|
-
key: string,
|
|
41
|
-
factory: () => Promise<T>,
|
|
42
|
-
ttl: number
|
|
43
|
-
): Promise<T> {
|
|
35
|
+
private async getFromMemoryCache<T>(key: string, factory: () => Promise<T>, ttl: number): Promise<T> {
|
|
44
36
|
const now = Date.now();
|
|
45
37
|
const cached = this.memoryCache.get(key);
|
|
46
38
|
|
|
@@ -48,10 +40,23 @@ export class CacheManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
48
40
|
return cached!.value as T;
|
|
49
41
|
}
|
|
50
42
|
|
|
51
|
-
|
|
52
|
-
this.
|
|
43
|
+
// Deduplicate concurrent requests for the same key (cache stampede prevention)
|
|
44
|
+
if (this.inflight.has(key)) {
|
|
45
|
+
return (await this.inflight.get(key)!) as T;
|
|
46
|
+
}
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
const promise = (async () => {
|
|
49
|
+
const value = await factory();
|
|
50
|
+
this.setInMemoryCache(key, value, ttl);
|
|
51
|
+
return value;
|
|
52
|
+
})();
|
|
53
|
+
|
|
54
|
+
this.inflight.set(key, promise);
|
|
55
|
+
try {
|
|
56
|
+
return await promise;
|
|
57
|
+
} finally {
|
|
58
|
+
this.inflight.delete(key);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
private isCacheValid(entry: CacheEntry | undefined, now: number): boolean {
|
|
@@ -95,11 +100,7 @@ export class CacheManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
async set<T = GetCacheType<TTypes>>(
|
|
99
|
-
key: string,
|
|
100
|
-
value: T,
|
|
101
|
-
ttl: number = DEFAULT_CONFIG.CACHE_TTL
|
|
102
|
-
): Promise<void> {
|
|
103
|
+
async set<T = GetCacheType<TTypes>>(key: string, value: T, ttl: number = DEFAULT_CONFIG.CACHE_TTL): Promise<void> {
|
|
103
104
|
if (ttl <= 0) {
|
|
104
105
|
return;
|
|
105
106
|
}
|
|
@@ -129,15 +130,9 @@ export class CacheManager<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
129
130
|
return true;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
|
-
generateKey(request: Request, options?: { authUser?: any }): string {
|
|
133
|
-
const url = new URL(request.url);
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
url.pathname,
|
|
137
|
-
url.search,
|
|
138
|
-
options?.authUser?.id || "anonymous",
|
|
139
|
-
];
|
|
140
|
-
|
|
141
|
-
return parts.join(":");
|
|
133
|
+
generateKey(request: Request & { _parsedUrl?: URL }, options?: { authUser?: any }): string {
|
|
134
|
+
const url = request._parsedUrl ?? new URL(request.url);
|
|
135
|
+
const userId = options?.authUser?.id != null ? String(options.authUser.id) : 'anonymous';
|
|
136
|
+
return `${request.method}:${url.pathname}:${url.search}:${userId}`;
|
|
142
137
|
}
|
|
143
138
|
}
|