vector-framework 1.2.1 → 1.2.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/README.md +18 -6
- package/dist/auth/protected.d.ts +4 -4
- package/dist/auth/protected.d.ts.map +1 -1
- package/dist/auth/protected.js +10 -7
- package/dist/auth/protected.js.map +1 -1
- package/dist/cache/manager.d.ts +2 -0
- package/dist/cache/manager.d.ts.map +1 -1
- package/dist/cache/manager.js +21 -4
- package/dist/cache/manager.js.map +1 -1
- package/dist/checkpoint/artifacts/compressor.d.ts +5 -0
- package/dist/checkpoint/artifacts/compressor.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/compressor.js +24 -0
- package/dist/checkpoint/artifacts/compressor.js.map +1 -0
- package/dist/checkpoint/artifacts/decompress-worker.d.ts +2 -0
- package/dist/checkpoint/artifacts/decompress-worker.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/decompress-worker.js +31 -0
- package/dist/checkpoint/artifacts/decompress-worker.js.map +1 -0
- package/dist/checkpoint/artifacts/hasher.d.ts +2 -0
- package/dist/checkpoint/artifacts/hasher.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/hasher.js +7 -0
- package/dist/checkpoint/artifacts/hasher.js.map +1 -0
- package/dist/checkpoint/artifacts/manifest.d.ts +6 -0
- package/dist/checkpoint/artifacts/manifest.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/manifest.js +55 -0
- package/dist/checkpoint/artifacts/manifest.js.map +1 -0
- package/dist/checkpoint/artifacts/materializer.d.ts +16 -0
- package/dist/checkpoint/artifacts/materializer.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/materializer.js +168 -0
- package/dist/checkpoint/artifacts/materializer.js.map +1 -0
- package/dist/checkpoint/artifacts/packager.d.ts +12 -0
- package/dist/checkpoint/artifacts/packager.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/packager.js +82 -0
- package/dist/checkpoint/artifacts/packager.js.map +1 -0
- package/dist/checkpoint/artifacts/repository.d.ts +11 -0
- package/dist/checkpoint/artifacts/repository.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/repository.js +29 -0
- package/dist/checkpoint/artifacts/repository.js.map +1 -0
- package/dist/checkpoint/artifacts/store.d.ts +13 -0
- package/dist/checkpoint/artifacts/store.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/store.js +85 -0
- package/dist/checkpoint/artifacts/store.js.map +1 -0
- package/dist/checkpoint/artifacts/types.d.ts +21 -0
- package/dist/checkpoint/artifacts/types.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/types.js +2 -0
- package/dist/checkpoint/artifacts/types.js.map +1 -0
- package/dist/checkpoint/artifacts/worker-decompressor.d.ts +17 -0
- package/dist/checkpoint/artifacts/worker-decompressor.d.ts.map +1 -0
- package/dist/checkpoint/artifacts/worker-decompressor.js +148 -0
- package/dist/checkpoint/artifacts/worker-decompressor.js.map +1 -0
- package/dist/checkpoint/asset-store.d.ts +10 -0
- package/dist/checkpoint/asset-store.d.ts.map +1 -0
- package/dist/checkpoint/asset-store.js +46 -0
- package/dist/checkpoint/asset-store.js.map +1 -0
- package/dist/checkpoint/bundler.d.ts +15 -0
- package/dist/checkpoint/bundler.d.ts.map +1 -0
- package/dist/checkpoint/bundler.js +45 -0
- package/dist/checkpoint/bundler.js.map +1 -0
- package/dist/checkpoint/cli.d.ts +2 -0
- package/dist/checkpoint/cli.d.ts.map +1 -0
- package/dist/checkpoint/cli.js +157 -0
- package/dist/checkpoint/cli.js.map +1 -0
- package/dist/checkpoint/entrypoint-generator.d.ts +17 -0
- package/dist/checkpoint/entrypoint-generator.d.ts.map +1 -0
- package/dist/checkpoint/entrypoint-generator.js +251 -0
- package/dist/checkpoint/entrypoint-generator.js.map +1 -0
- package/dist/checkpoint/forwarder.d.ts +6 -0
- package/dist/checkpoint/forwarder.d.ts.map +1 -0
- package/dist/checkpoint/forwarder.js +74 -0
- package/dist/checkpoint/forwarder.js.map +1 -0
- package/dist/checkpoint/gateway.d.ts +11 -0
- package/dist/checkpoint/gateway.d.ts.map +1 -0
- package/dist/checkpoint/gateway.js +30 -0
- package/dist/checkpoint/gateway.js.map +1 -0
- package/dist/checkpoint/ipc.d.ts +12 -0
- package/dist/checkpoint/ipc.d.ts.map +1 -0
- package/dist/checkpoint/ipc.js +96 -0
- package/dist/checkpoint/ipc.js.map +1 -0
- package/dist/checkpoint/manager.d.ts +20 -0
- package/dist/checkpoint/manager.d.ts.map +1 -0
- package/dist/checkpoint/manager.js +214 -0
- package/dist/checkpoint/manager.js.map +1 -0
- package/dist/checkpoint/process-manager.d.ts +35 -0
- package/dist/checkpoint/process-manager.d.ts.map +1 -0
- package/dist/checkpoint/process-manager.js +203 -0
- package/dist/checkpoint/process-manager.js.map +1 -0
- package/dist/checkpoint/resolver.d.ts +25 -0
- package/dist/checkpoint/resolver.d.ts.map +1 -0
- package/dist/checkpoint/resolver.js +95 -0
- package/dist/checkpoint/resolver.js.map +1 -0
- package/dist/checkpoint/socket-path.d.ts +2 -0
- package/dist/checkpoint/socket-path.d.ts.map +1 -0
- package/dist/checkpoint/socket-path.js +51 -0
- package/dist/checkpoint/socket-path.js.map +1 -0
- package/dist/checkpoint/types.d.ts +54 -0
- package/dist/checkpoint/types.d.ts.map +1 -0
- package/dist/checkpoint/types.js +2 -0
- package/dist/checkpoint/types.js.map +1 -0
- package/dist/cli/index.js +10 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/option-resolution.d.ts +1 -1
- package/dist/cli/option-resolution.d.ts.map +1 -1
- package/dist/cli/option-resolution.js.map +1 -1
- package/dist/cli.js +3817 -350
- package/dist/core/config-loader.d.ts +1 -0
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/config-loader.js +10 -2
- package/dist/core/config-loader.js.map +1 -1
- package/dist/core/router.d.ts +24 -3
- package/dist/core/router.d.ts.map +1 -1
- package/dist/core/router.js +398 -249
- package/dist/core/router.js.map +1 -1
- package/dist/core/server.d.ts +3 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +35 -10
- package/dist/core/server.js.map +1 -1
- package/dist/core/vector.d.ts +3 -0
- package/dist/core/vector.d.ts.map +1 -1
- package/dist/core/vector.js +51 -1
- package/dist/core/vector.js.map +1 -1
- package/dist/dev/route-scanner.d.ts.map +1 -1
- package/dist/dev/route-scanner.js +2 -1
- package/dist/dev/route-scanner.js.map +1 -1
- package/dist/errors/index.cjs +2 -0
- package/dist/http.d.ts +32 -7
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +144 -13
- package/dist/http.js.map +1 -1
- package/dist/index.cjs +2657 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -1433
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1301 -77
- package/dist/middleware/manager.d.ts +3 -3
- package/dist/middleware/manager.d.ts.map +1 -1
- package/dist/middleware/manager.js +9 -8
- package/dist/middleware/manager.js.map +1 -1
- package/dist/openapi/docs-ui.d.ts.map +1 -1
- package/dist/openapi/docs-ui.js +1097 -61
- package/dist/openapi/docs-ui.js.map +1 -1
- package/dist/openapi/generator.d.ts +2 -1
- package/dist/openapi/generator.d.ts.map +1 -1
- package/dist/openapi/generator.js +332 -16
- package/dist/openapi/generator.js.map +1 -1
- package/dist/types/index.d.ts +71 -28
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +24 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +3 -2
- package/dist/utils/validation.js.map +1 -1
- package/package.json +9 -14
- package/src/auth/protected.ts +11 -8
- package/src/cache/manager.ts +23 -4
- package/src/checkpoint/artifacts/compressor.ts +30 -0
- package/src/checkpoint/artifacts/decompress-worker.ts +49 -0
- package/src/checkpoint/artifacts/hasher.ts +6 -0
- package/src/checkpoint/artifacts/manifest.ts +72 -0
- package/src/checkpoint/artifacts/materializer.ts +211 -0
- package/src/checkpoint/artifacts/packager.ts +100 -0
- package/src/checkpoint/artifacts/repository.ts +36 -0
- package/src/checkpoint/artifacts/store.ts +102 -0
- package/src/checkpoint/artifacts/types.ts +24 -0
- package/src/checkpoint/artifacts/worker-decompressor.ts +192 -0
- package/src/checkpoint/asset-store.ts +61 -0
- package/src/checkpoint/bundler.ts +64 -0
- package/src/checkpoint/cli.ts +177 -0
- package/src/checkpoint/entrypoint-generator.ts +275 -0
- package/src/checkpoint/forwarder.ts +84 -0
- package/src/checkpoint/gateway.ts +40 -0
- package/src/checkpoint/ipc.ts +107 -0
- package/src/checkpoint/manager.ts +254 -0
- package/src/checkpoint/process-manager.ts +250 -0
- package/src/checkpoint/resolver.ts +124 -0
- package/src/checkpoint/socket-path.ts +61 -0
- package/src/checkpoint/types.ts +63 -0
- package/src/cli/index.ts +11 -2
- package/src/cli/option-resolution.ts +5 -1
- package/src/core/config-loader.ts +11 -2
- package/src/core/router.ts +505 -264
- package/src/core/server.ts +51 -11
- package/src/core/vector.ts +60 -1
- package/src/dev/route-scanner.ts +2 -1
- package/src/http.ts +219 -19
- package/src/index.ts +3 -2
- package/src/middleware/manager.ts +10 -10
- package/src/openapi/docs-ui.ts +1097 -61
- package/src/openapi/generator.ts +380 -13
- package/src/types/index.ts +83 -30
- package/src/utils/validation.ts +5 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { CheckpointManager } from './manager';
|
|
2
|
+
import type { CheckpointProcessManager } from './process-manager';
|
|
3
|
+
|
|
4
|
+
const DEFAULT_VERSION_HEADER = 'x-vector-checkpoint-version';
|
|
5
|
+
const FALLBACK_VERSION_HEADER = 'x-vector-checkpoint';
|
|
6
|
+
|
|
7
|
+
export interface CheckpointResolverOptions {
|
|
8
|
+
versionHeader?: string;
|
|
9
|
+
cacheKeyOverride?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class CheckpointResolver {
|
|
13
|
+
private manager: CheckpointManager;
|
|
14
|
+
private processManager: CheckpointProcessManager;
|
|
15
|
+
private versionHeader: string;
|
|
16
|
+
private cacheKeyOverride: boolean;
|
|
17
|
+
private allowFallbackVersionHeader: boolean;
|
|
18
|
+
private pendingVersionResolves: Map<string, Promise<string | null>> = new Map();
|
|
19
|
+
|
|
20
|
+
constructor(
|
|
21
|
+
manager: CheckpointManager,
|
|
22
|
+
processManager: CheckpointProcessManager,
|
|
23
|
+
options: CheckpointResolverOptions = {}
|
|
24
|
+
) {
|
|
25
|
+
this.manager = manager;
|
|
26
|
+
this.processManager = processManager;
|
|
27
|
+
this.versionHeader = normalizeHeaderName(options.versionHeader ?? DEFAULT_VERSION_HEADER);
|
|
28
|
+
this.cacheKeyOverride = options.cacheKeyOverride === true;
|
|
29
|
+
this.allowFallbackVersionHeader = options.versionHeader === undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async resolve(request: Request): Promise<string | null> {
|
|
33
|
+
const requestedVersion = this.getRequestedVersion(request);
|
|
34
|
+
if (!requestedVersion) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
return await this.resolveVersion(requestedVersion);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getRequestedVersion(request: Request): string | null {
|
|
41
|
+
return this.getRequestedHeader(request)?.value ?? null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
getCacheKeyOverrideValue(request: Request): string | null {
|
|
45
|
+
if (!this.cacheKeyOverride) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const requestedHeader = this.getRequestedHeader(request);
|
|
50
|
+
if (!requestedHeader) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return `${requestedHeader.name}:${requestedHeader.value}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private getRequestedHeader(request: Request): { name: string; value: string } | null {
|
|
58
|
+
const primary = request.headers.get(this.versionHeader);
|
|
59
|
+
if (primary && primary.trim().length > 0) {
|
|
60
|
+
return { name: this.versionHeader, value: primary.trim() };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (this.allowFallbackVersionHeader && this.versionHeader !== FALLBACK_VERSION_HEADER) {
|
|
64
|
+
const fallback = request.headers.get(FALLBACK_VERSION_HEADER);
|
|
65
|
+
if (fallback && fallback.trim().length > 0) {
|
|
66
|
+
return { name: FALLBACK_VERSION_HEADER, value: fallback.trim() };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
private async resolveVersion(version: string): Promise<string | null> {
|
|
74
|
+
let running = this.processManager.getRunning(version);
|
|
75
|
+
if (!running) {
|
|
76
|
+
const pending = this.pendingVersionResolves.get(version);
|
|
77
|
+
if (pending) {
|
|
78
|
+
const socketPath = await pending;
|
|
79
|
+
if (!socketPath) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
this.processManager.markUsed(version);
|
|
84
|
+
return socketPath;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const pendingResolve = (async (): Promise<string | null> => {
|
|
88
|
+
try {
|
|
89
|
+
const manifest = await this.manager.readManifest(version);
|
|
90
|
+
const spawned = await this.processManager.spawn(manifest, this.manager.getStorageDir());
|
|
91
|
+
return spawned.socketPath;
|
|
92
|
+
} catch {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
})();
|
|
96
|
+
|
|
97
|
+
this.pendingVersionResolves.set(version, pendingResolve);
|
|
98
|
+
const socketPath = await pendingResolve;
|
|
99
|
+
this.pendingVersionResolves.delete(version);
|
|
100
|
+
|
|
101
|
+
if (!socketPath) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
this.processManager.markUsed(version);
|
|
106
|
+
return socketPath;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
this.processManager.markUsed(version);
|
|
110
|
+
return running.socketPath;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Legacy no-op retained for compatibility with tests and existing integrations.
|
|
115
|
+
*/
|
|
116
|
+
invalidateCache(): void {
|
|
117
|
+
// No caching, so nothing to invalidate.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function normalizeHeaderName(value: string): string {
|
|
122
|
+
const normalized = value.trim().toLowerCase();
|
|
123
|
+
return normalized.length > 0 ? normalized : DEFAULT_VERSION_HEADER;
|
|
124
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { isAbsolute, join, resolve } from 'node:path';
|
|
4
|
+
|
|
5
|
+
const CHECKPOINT_SOCKET_FILE = 'run.sock';
|
|
6
|
+
const UNIX_SOCKET_PATH_MAX_BYTES = 103;
|
|
7
|
+
|
|
8
|
+
function toAbsolute(dir: string): string {
|
|
9
|
+
return isAbsolute(dir) ? dir : resolve(dir);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function unixSocketWithinLimit(path: string): boolean {
|
|
13
|
+
return Buffer.byteLength(path, 'utf8') <= UNIX_SOCKET_PATH_MAX_BYTES;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function socketFileName(storageDir: string, version: string): string {
|
|
17
|
+
const versionLabel = version
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
20
|
+
.replace(/(^-+|-+$)/g, '')
|
|
21
|
+
.slice(0, 12);
|
|
22
|
+
|
|
23
|
+
const digest = createHash('sha256').update(storageDir).update('\0').update(version).digest('hex').slice(0, 16);
|
|
24
|
+
const label = versionLabel.length > 0 ? `${versionLabel}-` : '';
|
|
25
|
+
return `vector-${label}${digest}.sock`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function candidateSocketRoots(): string[] {
|
|
29
|
+
const roots = new Set<string>();
|
|
30
|
+
const override = process.env.VECTOR_CHECKPOINT_SOCKET_DIR?.trim();
|
|
31
|
+
if (override) {
|
|
32
|
+
roots.add(toAbsolute(override));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Prefer short, stable roots before os.tmpdir(), especially on macOS where tmpdir can be long.
|
|
36
|
+
if (process.platform !== 'win32') {
|
|
37
|
+
roots.add('/tmp');
|
|
38
|
+
roots.add('/private/tmp');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
roots.add(toAbsolute(tmpdir()));
|
|
42
|
+
return [...roots];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function resolveCheckpointSocketPath(storageDir: string, version: string): string {
|
|
46
|
+
const defaultPath = join(storageDir, version, CHECKPOINT_SOCKET_FILE);
|
|
47
|
+
if (process.platform === 'win32' || unixSocketWithinLimit(defaultPath)) {
|
|
48
|
+
return defaultPath;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const fileName = socketFileName(storageDir, version);
|
|
52
|
+
for (const root of candidateSocketRoots()) {
|
|
53
|
+
const candidate = join(root, fileName);
|
|
54
|
+
if (unixSocketWithinLimit(candidate)) {
|
|
55
|
+
return candidate;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Last resort: retain deterministic socket naming even if the environment has unusually long temp paths.
|
|
60
|
+
return join('/tmp', fileName);
|
|
61
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const CHECKPOINT_FORMAT_VERSION = 1;
|
|
2
|
+
|
|
3
|
+
export type CheckpointCompressionCodec = 'none' | 'gzip';
|
|
4
|
+
|
|
5
|
+
export interface CheckpointManifest {
|
|
6
|
+
formatVersion: number;
|
|
7
|
+
version: string;
|
|
8
|
+
createdAt: string;
|
|
9
|
+
entrypoint: string;
|
|
10
|
+
routes: CheckpointRouteRecord[];
|
|
11
|
+
assets: CheckpointAssetRecord[];
|
|
12
|
+
bundleHash: string;
|
|
13
|
+
bundleSize: number;
|
|
14
|
+
checkpointArchivePath?: string;
|
|
15
|
+
checkpointArchiveHash?: string;
|
|
16
|
+
checkpointArchiveSize?: number;
|
|
17
|
+
checkpointArchiveCodec?: CheckpointCompressionCodec;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CheckpointRouteRecord {
|
|
21
|
+
method: string;
|
|
22
|
+
path: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface CheckpointAssetRecord {
|
|
27
|
+
type: 'embedded' | 'sidecar';
|
|
28
|
+
logicalPath: string;
|
|
29
|
+
// Legacy field kept for compatibility with existing tests/fixtures.
|
|
30
|
+
storedPath: string;
|
|
31
|
+
// Legacy field kept for compatibility with existing tests/fixtures.
|
|
32
|
+
hash: string;
|
|
33
|
+
// Legacy field kept for compatibility with existing tests/fixtures.
|
|
34
|
+
size: number;
|
|
35
|
+
contentHash?: string;
|
|
36
|
+
contentSize?: number;
|
|
37
|
+
blobHash?: string;
|
|
38
|
+
blobSize?: number;
|
|
39
|
+
blobPath?: string;
|
|
40
|
+
codec?: CheckpointCompressionCodec;
|
|
41
|
+
materializedPath?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface CheckpointConfig {
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
storageDir?: string;
|
|
47
|
+
maxCheckpoints?: number;
|
|
48
|
+
versionHeader?: string;
|
|
49
|
+
idleTimeoutMs?: number;
|
|
50
|
+
cacheKeyOverride?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface CheckpointPublishOptions {
|
|
54
|
+
version: string;
|
|
55
|
+
routesDir: string;
|
|
56
|
+
embeddedAssetPaths?: string[];
|
|
57
|
+
sidecarAssetPaths?: string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface ActivePointer {
|
|
61
|
+
version: string;
|
|
62
|
+
activatedAt: string;
|
|
63
|
+
}
|
package/src/cli/index.ts
CHANGED
|
@@ -10,6 +10,14 @@ import type { StartedVectorApp } from '../types';
|
|
|
10
10
|
// Compatibility layer for both Node and Bun
|
|
11
11
|
const args = typeof Bun !== 'undefined' ? Bun.argv.slice(2) : process.argv.slice(2);
|
|
12
12
|
|
|
13
|
+
// Handle checkpoint subcommand early — it has its own arg format
|
|
14
|
+
// and would conflict with the main parseArgs strict mode.
|
|
15
|
+
if (args[0] === 'checkpoint') {
|
|
16
|
+
const { runCheckpointCli } = await import('../checkpoint/cli');
|
|
17
|
+
await runCheckpointCli(args.slice(1));
|
|
18
|
+
process.exit(0);
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
const { values, positionals } = parseArgs({
|
|
14
22
|
args,
|
|
15
23
|
options: {
|
|
@@ -224,8 +232,9 @@ switch (command) {
|
|
|
224
232
|
Usage: vector [command] [options]
|
|
225
233
|
|
|
226
234
|
Commands:
|
|
227
|
-
dev
|
|
228
|
-
start
|
|
235
|
+
dev Start development server (default)
|
|
236
|
+
start Start production server
|
|
237
|
+
checkpoint Manage versioned checkpoints (publish, list, rollback, remove)
|
|
229
238
|
|
|
230
239
|
Options:
|
|
231
240
|
-p, --port <port> Port to listen on (default: 3000)
|
|
@@ -20,7 +20,11 @@ function parseAndValidatePort(value: unknown): number {
|
|
|
20
20
|
return parsed;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export function resolvePort(
|
|
23
|
+
export function resolvePort(
|
|
24
|
+
configPort: string | number | null | undefined,
|
|
25
|
+
hasPortOption: boolean,
|
|
26
|
+
cliPort: string
|
|
27
|
+
): number {
|
|
24
28
|
if (hasPortOption) {
|
|
25
29
|
return parseAndValidatePort(cliPort);
|
|
26
30
|
}
|
|
@@ -29,8 +29,9 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
29
29
|
if (existsSync(this.configPath)) {
|
|
30
30
|
try {
|
|
31
31
|
// Use explicit file:// URL to ensure correct resolution
|
|
32
|
+
// Append cache-busting query to force re-import on dev reload
|
|
32
33
|
const userConfigPath = toFileUrl(this.configPath);
|
|
33
|
-
const userConfig = await import(userConfigPath);
|
|
34
|
+
const userConfig = await import(`${userConfigPath}?t=${Date.now()}`);
|
|
34
35
|
this.config = userConfig.default || userConfig;
|
|
35
36
|
this.configSource = 'user';
|
|
36
37
|
} catch (error: any) {
|
|
@@ -57,7 +58,7 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
57
58
|
|
|
58
59
|
// Direct mapping - schemas are now the same (flat)
|
|
59
60
|
if (this.config) {
|
|
60
|
-
config.port = this.config.port;
|
|
61
|
+
config.port = this.normalizePort(this.config.port);
|
|
61
62
|
config.hostname = this.config.hostname;
|
|
62
63
|
config.reusePort = this.config.reusePort;
|
|
63
64
|
config.development = this.config.development;
|
|
@@ -68,6 +69,7 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
68
69
|
config.openapi = this.config.openapi;
|
|
69
70
|
config.startup = this.config.startup;
|
|
70
71
|
config.shutdown = this.config.shutdown;
|
|
72
|
+
config.checkpoint = this.config.checkpoint;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
// Always auto-discover routes
|
|
@@ -103,6 +105,13 @@ export class ConfigLoader<TTypes extends VectorTypes = DefaultVectorTypes> {
|
|
|
103
105
|
return config;
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
private normalizePort(port: number | string | undefined): number | undefined {
|
|
109
|
+
if (port === undefined) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
return Number(port);
|
|
113
|
+
}
|
|
114
|
+
|
|
106
115
|
async loadAuthHandler(): Promise<ProtectedHandler<TTypes> | null> {
|
|
107
116
|
return this.config?.auth || null;
|
|
108
117
|
}
|