@veloxts/router 0.4.2 → 0.4.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/dist/discovery/errors.d.ts +65 -0
- package/dist/discovery/errors.d.ts.map +1 -0
- package/dist/discovery/errors.js +131 -0
- package/dist/discovery/errors.js.map +1 -0
- package/dist/discovery/index.d.ts +35 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +34 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/loader.d.ts +58 -0
- package/dist/discovery/loader.d.ts.map +1 -0
- package/dist/discovery/loader.js +377 -0
- package/dist/discovery/loader.js.map +1 -0
- package/dist/discovery/types.d.ts +102 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +25 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Errors
|
|
3
|
+
*
|
|
4
|
+
* Error classes and factory functions for the discovery system.
|
|
5
|
+
* Uses E40xx error code range.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/errors
|
|
8
|
+
*/
|
|
9
|
+
import { DiscoveryErrorCode } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown during procedure discovery operations
|
|
12
|
+
*/
|
|
13
|
+
export declare class DiscoveryError extends Error {
|
|
14
|
+
/** Error code identifier */
|
|
15
|
+
readonly code: DiscoveryErrorCode;
|
|
16
|
+
/** Optional file path where the error occurred */
|
|
17
|
+
readonly filePath?: string;
|
|
18
|
+
/** Suggested fix for the error */
|
|
19
|
+
readonly fix?: string;
|
|
20
|
+
/** Additional error details */
|
|
21
|
+
readonly details?: Record<string, unknown>;
|
|
22
|
+
constructor(code: DiscoveryErrorCode, message: string, options?: {
|
|
23
|
+
readonly filePath?: string;
|
|
24
|
+
readonly fix?: string;
|
|
25
|
+
readonly details?: Record<string, unknown>;
|
|
26
|
+
readonly cause?: Error;
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Format the error for display
|
|
30
|
+
*/
|
|
31
|
+
format(): string;
|
|
32
|
+
/**
|
|
33
|
+
* Convert to JSON for serialization
|
|
34
|
+
*/
|
|
35
|
+
toJSON(): Record<string, unknown>;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Type guard to check if an error is a DiscoveryError
|
|
39
|
+
*/
|
|
40
|
+
export declare function isDiscoveryError(error: unknown): error is DiscoveryError;
|
|
41
|
+
/**
|
|
42
|
+
* Create error for directory not found
|
|
43
|
+
*/
|
|
44
|
+
export declare function directoryNotFound(path: string): DiscoveryError;
|
|
45
|
+
/**
|
|
46
|
+
* Create error for no procedures found
|
|
47
|
+
*/
|
|
48
|
+
export declare function noProceduresFound(path: string, scannedCount: number): DiscoveryError;
|
|
49
|
+
/**
|
|
50
|
+
* Create error for invalid export
|
|
51
|
+
*/
|
|
52
|
+
export declare function invalidExport(filePath: string, exportName: string, reason: string): DiscoveryError;
|
|
53
|
+
/**
|
|
54
|
+
* Create error for file load failure
|
|
55
|
+
*/
|
|
56
|
+
export declare function fileLoadError(filePath: string, cause: Error): DiscoveryError;
|
|
57
|
+
/**
|
|
58
|
+
* Create error for permission denied
|
|
59
|
+
*/
|
|
60
|
+
export declare function permissionDenied(path: string): DiscoveryError;
|
|
61
|
+
/**
|
|
62
|
+
* Create error for invalid file type
|
|
63
|
+
*/
|
|
64
|
+
export declare function invalidFileType(filePath: string, extension: string): DiscoveryError;
|
|
65
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/discovery/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMhD;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,4BAA4B;IAC5B,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IAEzC,kDAAkD;IAClD,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElC,kCAAkC;IAClC,SAAgB,GAAG,CAAC,EAAE,MAAM,CAAC;IAE7B,+BAA+B;IAC/B,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGhD,IAAI,EAAE,kBAAkB,EACxB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;KACxB;IAUH;;OAEG;IACH,MAAM,IAAI,MAAM;IAchB;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CASlC;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAExE;AAMD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAapF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,cAAc,CAUhB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,cAAc,CAU5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAS7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,cAAc,CAUnF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Errors
|
|
3
|
+
*
|
|
4
|
+
* Error classes and factory functions for the discovery system.
|
|
5
|
+
* Uses E40xx error code range.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/errors
|
|
8
|
+
*/
|
|
9
|
+
import { DiscoveryErrorCode } from './types.js';
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Error Class
|
|
12
|
+
// ============================================================================
|
|
13
|
+
/**
|
|
14
|
+
* Error thrown during procedure discovery operations
|
|
15
|
+
*/
|
|
16
|
+
export class DiscoveryError extends Error {
|
|
17
|
+
/** Error code identifier */
|
|
18
|
+
code;
|
|
19
|
+
/** Optional file path where the error occurred */
|
|
20
|
+
filePath;
|
|
21
|
+
/** Suggested fix for the error */
|
|
22
|
+
fix;
|
|
23
|
+
/** Additional error details */
|
|
24
|
+
details;
|
|
25
|
+
constructor(code, message, options) {
|
|
26
|
+
super(message, { cause: options?.cause });
|
|
27
|
+
this.name = 'DiscoveryError';
|
|
28
|
+
this.code = code;
|
|
29
|
+
this.filePath = options?.filePath;
|
|
30
|
+
this.fix = options?.fix;
|
|
31
|
+
this.details = options?.details;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Format the error for display
|
|
35
|
+
*/
|
|
36
|
+
format() {
|
|
37
|
+
let output = `DiscoveryError[${this.code}]: ${this.message}`;
|
|
38
|
+
if (this.filePath) {
|
|
39
|
+
output += `\n\n File: ${this.filePath}`;
|
|
40
|
+
}
|
|
41
|
+
if (this.fix) {
|
|
42
|
+
output += `\n\n Fix: ${this.fix}`;
|
|
43
|
+
}
|
|
44
|
+
return output;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert to JSON for serialization
|
|
48
|
+
*/
|
|
49
|
+
toJSON() {
|
|
50
|
+
return {
|
|
51
|
+
code: this.code,
|
|
52
|
+
message: this.message,
|
|
53
|
+
filePath: this.filePath,
|
|
54
|
+
fix: this.fix,
|
|
55
|
+
details: this.details,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// Type Guard
|
|
61
|
+
// ============================================================================
|
|
62
|
+
/**
|
|
63
|
+
* Type guard to check if an error is a DiscoveryError
|
|
64
|
+
*/
|
|
65
|
+
export function isDiscoveryError(error) {
|
|
66
|
+
return error instanceof DiscoveryError;
|
|
67
|
+
}
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// Error Factory Functions
|
|
70
|
+
// ============================================================================
|
|
71
|
+
/**
|
|
72
|
+
* Create error for directory not found
|
|
73
|
+
*/
|
|
74
|
+
export function directoryNotFound(path) {
|
|
75
|
+
return new DiscoveryError(DiscoveryErrorCode.DIRECTORY_NOT_FOUND, `Procedures directory not found: ${path}`, {
|
|
76
|
+
filePath: path,
|
|
77
|
+
fix: 'Create the procedures directory or check the path. Expected structure: src/procedures/*.ts',
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create error for no procedures found
|
|
82
|
+
*/
|
|
83
|
+
export function noProceduresFound(path, scannedCount) {
|
|
84
|
+
return new DiscoveryError(DiscoveryErrorCode.NO_PROCEDURES_FOUND, `No procedure collections found in ${path}`, {
|
|
85
|
+
filePath: path,
|
|
86
|
+
details: { scannedFiles: scannedCount },
|
|
87
|
+
fix: scannedCount === 0
|
|
88
|
+
? 'Create procedure files using: velox generate procedure <name>'
|
|
89
|
+
: 'Ensure files export ProcedureCollection objects using defineProcedures()',
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create error for invalid export
|
|
94
|
+
*/
|
|
95
|
+
export function invalidExport(filePath, exportName, reason) {
|
|
96
|
+
return new DiscoveryError(DiscoveryErrorCode.INVALID_EXPORT, `Invalid export '${exportName}' in ${filePath}: ${reason}`, {
|
|
97
|
+
filePath,
|
|
98
|
+
details: { exportName, reason },
|
|
99
|
+
fix: 'Export must be a ProcedureCollection created with defineProcedures(namespace, procedures)',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Create error for file load failure
|
|
104
|
+
*/
|
|
105
|
+
export function fileLoadError(filePath, cause) {
|
|
106
|
+
return new DiscoveryError(DiscoveryErrorCode.FILE_LOAD_ERROR, `Failed to load procedure file: ${filePath} - ${cause.message}`, {
|
|
107
|
+
filePath,
|
|
108
|
+
cause,
|
|
109
|
+
fix: 'Check for syntax errors or missing dependencies in the file',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Create error for permission denied
|
|
114
|
+
*/
|
|
115
|
+
export function permissionDenied(path) {
|
|
116
|
+
return new DiscoveryError(DiscoveryErrorCode.PERMISSION_DENIED, `Permission denied accessing: ${path}`, {
|
|
117
|
+
filePath: path,
|
|
118
|
+
fix: 'Check file permissions and ensure the process has read access',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create error for invalid file type
|
|
123
|
+
*/
|
|
124
|
+
export function invalidFileType(filePath, extension) {
|
|
125
|
+
return new DiscoveryError(DiscoveryErrorCode.INVALID_FILE_TYPE, `Unsupported file type: ${extension}`, {
|
|
126
|
+
filePath,
|
|
127
|
+
details: { extension },
|
|
128
|
+
fix: 'Procedure files must be .ts, .js, .mts, or .mjs',
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/discovery/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Module
|
|
3
|
+
*
|
|
4
|
+
* Auto-scan and register procedures from the filesystem.
|
|
5
|
+
*
|
|
6
|
+
* @module discovery
|
|
7
|
+
*
|
|
8
|
+
* @example Basic usage
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { discoverProcedures, rest } from '@veloxts/router';
|
|
11
|
+
*
|
|
12
|
+
* const collections = await discoverProcedures('./src/procedures');
|
|
13
|
+
* await app.register(rest(collections), { prefix: '/api' });
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @example With options
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const collections = await discoverProcedures('./src/procedures', {
|
|
19
|
+
* recursive: true,
|
|
20
|
+
* onInvalidExport: 'warn',
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Verbose mode for tooling
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const result = await discoverProceduresVerbose('./src/procedures');
|
|
27
|
+
* console.log(`Found ${result.collections.length} collections`);
|
|
28
|
+
* console.log(`Scanned ${result.scannedFiles.length} files`);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export { DiscoveryError, directoryNotFound, fileLoadError, invalidExport, invalidFileType, isDiscoveryError, noProceduresFound, permissionDenied, } from './errors.js';
|
|
32
|
+
export { discoverProcedures, discoverProceduresVerbose } from './loader.js';
|
|
33
|
+
export type { DiscoveryOptions, DiscoveryResult, DiscoveryWarning } from './types.js';
|
|
34
|
+
export { DiscoveryErrorCode } from './types.js';
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC5E,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Module
|
|
3
|
+
*
|
|
4
|
+
* Auto-scan and register procedures from the filesystem.
|
|
5
|
+
*
|
|
6
|
+
* @module discovery
|
|
7
|
+
*
|
|
8
|
+
* @example Basic usage
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { discoverProcedures, rest } from '@veloxts/router';
|
|
11
|
+
*
|
|
12
|
+
* const collections = await discoverProcedures('./src/procedures');
|
|
13
|
+
* await app.register(rest(collections), { prefix: '/api' });
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @example With options
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const collections = await discoverProcedures('./src/procedures', {
|
|
19
|
+
* recursive: true,
|
|
20
|
+
* onInvalidExport: 'warn',
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @example Verbose mode for tooling
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const result = await discoverProceduresVerbose('./src/procedures');
|
|
27
|
+
* console.log(`Found ${result.collections.length} collections`);
|
|
28
|
+
* console.log(`Scanned ${result.scannedFiles.length} files`);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export { DiscoveryError, directoryNotFound, fileLoadError, invalidExport, invalidFileType, isDiscoveryError, noProceduresFound, permissionDenied, } from './errors.js';
|
|
32
|
+
export { discoverProcedures, discoverProceduresVerbose } from './loader.js';
|
|
33
|
+
export { DiscoveryErrorCode } from './types.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/discovery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Loader
|
|
3
|
+
*
|
|
4
|
+
* Core logic for scanning the filesystem and loading procedure collections.
|
|
5
|
+
* Uses dynamic imports with ESM-compatible file URLs.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/loader
|
|
8
|
+
*/
|
|
9
|
+
import type { ProcedureCollection } from '../types.js';
|
|
10
|
+
import { type DiscoveryOptions, type DiscoveryResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Discover procedure collections from the filesystem
|
|
13
|
+
*
|
|
14
|
+
* Scans a directory for files exporting ProcedureCollection objects,
|
|
15
|
+
* validates them at runtime, and returns type-safe results.
|
|
16
|
+
*
|
|
17
|
+
* @param searchPath - Absolute or relative path to procedures directory
|
|
18
|
+
* @param options - Discovery configuration
|
|
19
|
+
* @returns Promise resolving to discovered procedure collections
|
|
20
|
+
*
|
|
21
|
+
* @example Basic usage
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const collections = await discoverProcedures('./src/procedures');
|
|
24
|
+
* await app.register(rest(collections), { prefix: '/api' });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example With options
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const collections = await discoverProcedures('./src/procedures', {
|
|
30
|
+
* recursive: true,
|
|
31
|
+
* cwd: process.cwd(),
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare function discoverProcedures(searchPath: string, options?: DiscoveryOptions): Promise<ProcedureCollection[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Discover procedure collections with detailed results
|
|
38
|
+
*
|
|
39
|
+
* Same as discoverProcedures but returns additional metadata about
|
|
40
|
+
* scanned files, loaded files, and any warnings.
|
|
41
|
+
*
|
|
42
|
+
* @param searchPath - Absolute or relative path to procedures directory
|
|
43
|
+
* @param options - Discovery configuration
|
|
44
|
+
* @returns Promise resolving to detailed discovery results
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* const result = await discoverProceduresVerbose('./src/procedures', {
|
|
49
|
+
* onInvalidExport: 'warn',
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* console.log(`Found ${result.collections.length} collections`);
|
|
53
|
+
* console.log(`Scanned ${result.scannedFiles.length} files`);
|
|
54
|
+
* result.warnings.forEach(w => console.warn(w.message));
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function discoverProceduresVerbose(searchPath: string, options?: DiscoveryOptions): Promise<DiscoveryResult>;
|
|
58
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/discovery/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AASvD,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAIrB,MAAM,YAAY,CAAC;AAcpB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAGhC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAyE1B"}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Loader
|
|
3
|
+
*
|
|
4
|
+
* Core logic for scanning the filesystem and loading procedure collections.
|
|
5
|
+
* Uses dynamic imports with ESM-compatible file URLs.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/loader
|
|
8
|
+
*/
|
|
9
|
+
import fs from 'node:fs/promises';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { pathToFileURL } from 'node:url';
|
|
12
|
+
import { isProcedureCollection } from '../procedure/builder.js';
|
|
13
|
+
import { directoryNotFound, fileLoadError, invalidExport, noProceduresFound, permissionDenied, } from './errors.js';
|
|
14
|
+
import { DiscoveryErrorCode, } from './types.js';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Constants
|
|
17
|
+
// ============================================================================
|
|
18
|
+
const DEFAULT_EXTENSIONS = ['.ts', '.js', '.mts', '.mjs'];
|
|
19
|
+
const DEFAULT_EXCLUDE_PATTERNS = ['*.test.*', '*.spec.*', 'index.*', '*.d.ts'];
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Main Discovery Functions
|
|
22
|
+
// ============================================================================
|
|
23
|
+
/**
|
|
24
|
+
* Discover procedure collections from the filesystem
|
|
25
|
+
*
|
|
26
|
+
* Scans a directory for files exporting ProcedureCollection objects,
|
|
27
|
+
* validates them at runtime, and returns type-safe results.
|
|
28
|
+
*
|
|
29
|
+
* @param searchPath - Absolute or relative path to procedures directory
|
|
30
|
+
* @param options - Discovery configuration
|
|
31
|
+
* @returns Promise resolving to discovered procedure collections
|
|
32
|
+
*
|
|
33
|
+
* @example Basic usage
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const collections = await discoverProcedures('./src/procedures');
|
|
36
|
+
* await app.register(rest(collections), { prefix: '/api' });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example With options
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const collections = await discoverProcedures('./src/procedures', {
|
|
42
|
+
* recursive: true,
|
|
43
|
+
* cwd: process.cwd(),
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export async function discoverProcedures(searchPath, options = {}) {
|
|
48
|
+
const result = await discoverProceduresVerbose(searchPath, options);
|
|
49
|
+
return result.collections;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Discover procedure collections with detailed results
|
|
53
|
+
*
|
|
54
|
+
* Same as discoverProcedures but returns additional metadata about
|
|
55
|
+
* scanned files, loaded files, and any warnings.
|
|
56
|
+
*
|
|
57
|
+
* @param searchPath - Absolute or relative path to procedures directory
|
|
58
|
+
* @param options - Discovery configuration
|
|
59
|
+
* @returns Promise resolving to detailed discovery results
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```typescript
|
|
63
|
+
* const result = await discoverProceduresVerbose('./src/procedures', {
|
|
64
|
+
* onInvalidExport: 'warn',
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* console.log(`Found ${result.collections.length} collections`);
|
|
68
|
+
* console.log(`Scanned ${result.scannedFiles.length} files`);
|
|
69
|
+
* result.warnings.forEach(w => console.warn(w.message));
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export async function discoverProceduresVerbose(searchPath, options = {}) {
|
|
73
|
+
const { cwd = process.cwd(), recursive = false, extensions = DEFAULT_EXTENSIONS, exclude = DEFAULT_EXCLUDE_PATTERNS, onInvalidExport = 'throw', } = options;
|
|
74
|
+
// Resolve to absolute path
|
|
75
|
+
const absolutePath = path.isAbsolute(searchPath) ? searchPath : path.resolve(cwd, searchPath);
|
|
76
|
+
// Verify directory exists
|
|
77
|
+
const dirExists = await directoryExists(absolutePath);
|
|
78
|
+
if (!dirExists) {
|
|
79
|
+
throw directoryNotFound(absolutePath);
|
|
80
|
+
}
|
|
81
|
+
// Scan for procedure files
|
|
82
|
+
const files = await scanForProcedureFiles(absolutePath, {
|
|
83
|
+
recursive,
|
|
84
|
+
extensions,
|
|
85
|
+
exclude,
|
|
86
|
+
});
|
|
87
|
+
// Load all files in parallel, preserving file context with each result
|
|
88
|
+
const loadResultsWithFiles = await Promise.all(files.map(async (file) => ({
|
|
89
|
+
file,
|
|
90
|
+
result: await loadProcedureFile(file),
|
|
91
|
+
})));
|
|
92
|
+
// Aggregate results
|
|
93
|
+
const collections = [];
|
|
94
|
+
const loadedFiles = [];
|
|
95
|
+
const warnings = [];
|
|
96
|
+
for (const { file, result } of loadResultsWithFiles) {
|
|
97
|
+
if (result.success) {
|
|
98
|
+
collections.push(...result.collections);
|
|
99
|
+
if (result.collections.length > 0) {
|
|
100
|
+
loadedFiles.push(file);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (onInvalidExport === 'throw') {
|
|
104
|
+
// Re-throw as DiscoveryError
|
|
105
|
+
throw createDiscoveryError(file, result.code, result.message);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Add to warnings
|
|
109
|
+
warnings.push({
|
|
110
|
+
filePath: file,
|
|
111
|
+
message: result.message,
|
|
112
|
+
code: result.code,
|
|
113
|
+
});
|
|
114
|
+
// Log warning if mode is 'warn'
|
|
115
|
+
if (onInvalidExport === 'warn') {
|
|
116
|
+
console.warn(`[Discovery Warning] ${file}: ${result.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Error if no procedures found
|
|
121
|
+
if (collections.length === 0) {
|
|
122
|
+
throw noProceduresFound(absolutePath, files.length);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
collections,
|
|
126
|
+
scannedFiles: files,
|
|
127
|
+
loadedFiles,
|
|
128
|
+
warnings,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// File Scanning
|
|
133
|
+
// ============================================================================
|
|
134
|
+
/**
|
|
135
|
+
* Scan directory for procedure files
|
|
136
|
+
*
|
|
137
|
+
* Uses a visited set to detect and prevent circular symlinks from causing infinite loops.
|
|
138
|
+
*/
|
|
139
|
+
async function scanForProcedureFiles(dirPath, options, visited = new Set()) {
|
|
140
|
+
const { recursive, extensions, exclude } = options;
|
|
141
|
+
const files = [];
|
|
142
|
+
// Resolve real path to detect circular symlinks
|
|
143
|
+
let realPath;
|
|
144
|
+
try {
|
|
145
|
+
realPath = await fs.realpath(dirPath);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Can't resolve real path (broken symlink?) - skip this directory
|
|
149
|
+
return files;
|
|
150
|
+
}
|
|
151
|
+
// Check for circular symlink
|
|
152
|
+
if (visited.has(realPath)) {
|
|
153
|
+
return files; // Already visited this directory via another path
|
|
154
|
+
}
|
|
155
|
+
visited.add(realPath);
|
|
156
|
+
let entries;
|
|
157
|
+
try {
|
|
158
|
+
entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
// Can't read directory (permissions?) - skip
|
|
162
|
+
return files;
|
|
163
|
+
}
|
|
164
|
+
for (const entry of entries) {
|
|
165
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
166
|
+
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
167
|
+
// For symlinks, check if they point to a directory
|
|
168
|
+
if (entry.isSymbolicLink()) {
|
|
169
|
+
try {
|
|
170
|
+
const stat = await fs.stat(fullPath);
|
|
171
|
+
if (!stat.isDirectory()) {
|
|
172
|
+
// Symlink to file - process as file
|
|
173
|
+
if (stat.isFile()) {
|
|
174
|
+
const ext = path.extname(entry.name);
|
|
175
|
+
if (extensions.includes(ext) && !shouldExclude(entry.name, exclude)) {
|
|
176
|
+
files.push(fullPath);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// Broken symlink - skip
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Skip excluded directories
|
|
188
|
+
if (shouldExcludeDirectory(entry.name)) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (recursive) {
|
|
192
|
+
// Recursively scan subdirectories (pass visited set for circular detection)
|
|
193
|
+
const subFiles = await scanForProcedureFiles(fullPath, options, visited);
|
|
194
|
+
files.push(...subFiles);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else if (entry.isFile()) {
|
|
198
|
+
// Check extension
|
|
199
|
+
const ext = path.extname(entry.name);
|
|
200
|
+
if (!extensions.includes(ext))
|
|
201
|
+
continue;
|
|
202
|
+
// Check exclusion patterns
|
|
203
|
+
if (shouldExclude(entry.name, exclude))
|
|
204
|
+
continue;
|
|
205
|
+
files.push(fullPath);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Sort for consistent ordering
|
|
209
|
+
return files.sort();
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Check if a filename matches any exclusion pattern
|
|
213
|
+
*/
|
|
214
|
+
function shouldExclude(filename, patterns) {
|
|
215
|
+
for (const pattern of patterns) {
|
|
216
|
+
if (matchSimplePattern(filename, pattern)) {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Check if a directory should be excluded
|
|
224
|
+
*/
|
|
225
|
+
function shouldExcludeDirectory(dirname) {
|
|
226
|
+
const excludedDirs = ['__tests__', '__mocks__', 'node_modules', '.git'];
|
|
227
|
+
return excludedDirs.includes(dirname);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Simple pattern matching (supports * wildcard)
|
|
231
|
+
*/
|
|
232
|
+
function matchSimplePattern(filename, pattern) {
|
|
233
|
+
// Convert glob pattern to regex
|
|
234
|
+
const regexPattern = pattern
|
|
235
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except *
|
|
236
|
+
.replace(/\*/g, '.*'); // Convert * to .*
|
|
237
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
238
|
+
return regex.test(filename);
|
|
239
|
+
}
|
|
240
|
+
// ============================================================================
|
|
241
|
+
// File Loading
|
|
242
|
+
// ============================================================================
|
|
243
|
+
/**
|
|
244
|
+
* Type guard for Node.js errno exceptions
|
|
245
|
+
*
|
|
246
|
+
* Safely checks if an error is a Node.js system error with an error code.
|
|
247
|
+
* This eliminates unsafe type assertions when handling filesystem errors.
|
|
248
|
+
*/
|
|
249
|
+
function isErrnoException(error) {
|
|
250
|
+
return (error instanceof Error &&
|
|
251
|
+
'code' in error &&
|
|
252
|
+
typeof error.code === 'string');
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Load a single procedure file and extract collections
|
|
256
|
+
*/
|
|
257
|
+
async function loadProcedureFile(filePath) {
|
|
258
|
+
// Dynamic import using file URL for ESM compatibility
|
|
259
|
+
let module;
|
|
260
|
+
try {
|
|
261
|
+
const fileUrl = pathToFileURL(filePath).href;
|
|
262
|
+
module = (await import(fileUrl));
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
266
|
+
// Check for specific error codes using type guard
|
|
267
|
+
if (isErrnoException(error)) {
|
|
268
|
+
if (error.code === 'EACCES' || error.code === 'EPERM') {
|
|
269
|
+
return {
|
|
270
|
+
success: false,
|
|
271
|
+
code: DiscoveryErrorCode.PERMISSION_DENIED,
|
|
272
|
+
message: `Permission denied: Cannot read file ${filePath}`,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
if (error.code === 'ENOENT') {
|
|
276
|
+
return {
|
|
277
|
+
success: false,
|
|
278
|
+
code: DiscoveryErrorCode.FILE_LOAD_ERROR,
|
|
279
|
+
message: `File not found (possibly broken symlink): ${filePath}`,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
success: false,
|
|
285
|
+
code: DiscoveryErrorCode.FILE_LOAD_ERROR,
|
|
286
|
+
message: `Failed to load file: ${err.message}`,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// Extract procedure collections from exports
|
|
290
|
+
const collections = [];
|
|
291
|
+
const invalidExports = [];
|
|
292
|
+
for (const [exportName, exportValue] of Object.entries(module)) {
|
|
293
|
+
// Skip non-objects
|
|
294
|
+
if (exportValue === null || typeof exportValue !== 'object') {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
// Check if it's a valid procedure collection
|
|
298
|
+
if (isProcedureCollection(exportValue)) {
|
|
299
|
+
collections.push(exportValue);
|
|
300
|
+
}
|
|
301
|
+
else if (looksLikeProcedureCollection(exportValue)) {
|
|
302
|
+
// It has the shape but failed validation - track for error
|
|
303
|
+
invalidExports.push({
|
|
304
|
+
name: exportName,
|
|
305
|
+
reason: 'Object has namespace and procedures but procedures are not valid CompiledProcedures',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
// Other objects are silently ignored (utilities, constants, etc.)
|
|
309
|
+
}
|
|
310
|
+
// If we found invalid exports and no valid ones, report the error
|
|
311
|
+
if (collections.length === 0 && invalidExports.length > 0) {
|
|
312
|
+
const first = invalidExports[0];
|
|
313
|
+
return {
|
|
314
|
+
success: false,
|
|
315
|
+
code: DiscoveryErrorCode.INVALID_EXPORT,
|
|
316
|
+
message: `Invalid export '${first.name}': ${first.reason}`,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
return { success: true, collections };
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Check if a value looks like a procedure collection but might not be valid
|
|
323
|
+
*
|
|
324
|
+
* Used to provide better error messages for almost-correct exports.
|
|
325
|
+
* This heuristic intentionally returns `true` for objects where `procedures` is `null`,
|
|
326
|
+
* because `typeof null === 'object'`. This allows us to distinguish between:
|
|
327
|
+
*
|
|
328
|
+
* 1. "Not a procedure collection" - objects that don't have the shape at all
|
|
329
|
+
* 2. "Invalid procedure collection" - objects that have the shape but fail validation
|
|
330
|
+
*
|
|
331
|
+
* Objects in category 2 get reported as INVALID_EXPORT errors with helpful messages,
|
|
332
|
+
* while objects in category 1 are silently ignored (they might be utility functions, etc.)
|
|
333
|
+
*
|
|
334
|
+
* Note: `isProcedureCollection` has an explicit `procedures !== null` check, so objects
|
|
335
|
+
* with `procedures: null` will pass this heuristic but fail actual validation.
|
|
336
|
+
*/
|
|
337
|
+
function looksLikeProcedureCollection(value) {
|
|
338
|
+
if (typeof value !== 'object' || value === null)
|
|
339
|
+
return false;
|
|
340
|
+
const obj = value;
|
|
341
|
+
return typeof obj.namespace === 'string' && typeof obj.procedures === 'object';
|
|
342
|
+
}
|
|
343
|
+
// ============================================================================
|
|
344
|
+
// Utility Functions
|
|
345
|
+
// ============================================================================
|
|
346
|
+
/**
|
|
347
|
+
* Check if a directory exists
|
|
348
|
+
*/
|
|
349
|
+
async function directoryExists(dirPath) {
|
|
350
|
+
try {
|
|
351
|
+
const stat = await fs.stat(dirPath);
|
|
352
|
+
return stat.isDirectory();
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Create a DiscoveryError from load result
|
|
360
|
+
*/
|
|
361
|
+
function createDiscoveryError(filePath, code, message) {
|
|
362
|
+
if (code === DiscoveryErrorCode.PERMISSION_DENIED) {
|
|
363
|
+
return permissionDenied(filePath);
|
|
364
|
+
}
|
|
365
|
+
if (code === DiscoveryErrorCode.FILE_LOAD_ERROR) {
|
|
366
|
+
return fileLoadError(filePath, new Error(message));
|
|
367
|
+
}
|
|
368
|
+
if (code === DiscoveryErrorCode.INVALID_EXPORT) {
|
|
369
|
+
// Parse export name from message
|
|
370
|
+
const match = /Invalid export '([^']+)'/.exec(message);
|
|
371
|
+
const exportName = match ? match[1] : 'unknown';
|
|
372
|
+
return invalidExport(filePath, exportName, message);
|
|
373
|
+
}
|
|
374
|
+
// Fallback - shouldn't happen
|
|
375
|
+
return fileLoadError(filePath, new Error(message));
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/discovery/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the procedure discovery system that auto-scans
|
|
5
|
+
* and registers procedures from the filesystem.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/types
|
|
8
|
+
*/
|
|
9
|
+
import type { ProcedureCollection } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Error codes for discovery operations
|
|
12
|
+
*
|
|
13
|
+
* Range: E40xx (discovery domain)
|
|
14
|
+
*/
|
|
15
|
+
export declare const DiscoveryErrorCode: {
|
|
16
|
+
readonly DIRECTORY_NOT_FOUND: "E4001";
|
|
17
|
+
readonly NO_PROCEDURES_FOUND: "E4002";
|
|
18
|
+
readonly INVALID_EXPORT: "E4003";
|
|
19
|
+
readonly FILE_LOAD_ERROR: "E4004";
|
|
20
|
+
readonly PERMISSION_DENIED: "E4005";
|
|
21
|
+
readonly INVALID_FILE_TYPE: "E4006";
|
|
22
|
+
};
|
|
23
|
+
export type DiscoveryErrorCode = (typeof DiscoveryErrorCode)[keyof typeof DiscoveryErrorCode];
|
|
24
|
+
/**
|
|
25
|
+
* Configuration options for procedure discovery
|
|
26
|
+
*/
|
|
27
|
+
export interface DiscoveryOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Current working directory for resolving relative paths
|
|
30
|
+
* @default process.cwd()
|
|
31
|
+
*/
|
|
32
|
+
readonly cwd?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Recursively scan subdirectories
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
readonly recursive?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* File extensions to include
|
|
40
|
+
* @default ['.ts', '.js', '.mts', '.mjs']
|
|
41
|
+
*/
|
|
42
|
+
readonly extensions?: readonly string[];
|
|
43
|
+
/**
|
|
44
|
+
* Patterns to exclude (simple glob patterns)
|
|
45
|
+
* @default ['*.test.*', '*.spec.*', 'index.*', '*.d.ts']
|
|
46
|
+
*/
|
|
47
|
+
readonly exclude?: readonly string[];
|
|
48
|
+
/**
|
|
49
|
+
* Error handling mode:
|
|
50
|
+
* - 'throw': Throw on first invalid file (default)
|
|
51
|
+
* - 'warn': Log warnings but continue
|
|
52
|
+
* - 'silent': Skip invalid files silently
|
|
53
|
+
* @default 'throw'
|
|
54
|
+
*/
|
|
55
|
+
readonly onInvalidExport?: 'throw' | 'warn' | 'silent';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Warning generated during discovery
|
|
59
|
+
*/
|
|
60
|
+
export interface DiscoveryWarning {
|
|
61
|
+
/** Path to the file that caused the warning */
|
|
62
|
+
readonly filePath: string;
|
|
63
|
+
/** Warning message */
|
|
64
|
+
readonly message: string;
|
|
65
|
+
/** Error code for the warning */
|
|
66
|
+
readonly code: DiscoveryErrorCode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Detailed result from verbose discovery
|
|
70
|
+
*/
|
|
71
|
+
export interface DiscoveryResult {
|
|
72
|
+
/** Successfully loaded procedure collections */
|
|
73
|
+
readonly collections: ProcedureCollection[];
|
|
74
|
+
/** All files that were scanned */
|
|
75
|
+
readonly scannedFiles: readonly string[];
|
|
76
|
+
/** Files that contained valid procedure exports */
|
|
77
|
+
readonly loadedFiles: readonly string[];
|
|
78
|
+
/** Warnings for files that had issues (when onInvalidExport !== 'throw') */
|
|
79
|
+
readonly warnings: readonly DiscoveryWarning[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Result of loading a single file
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
85
|
+
export type LoadResult = {
|
|
86
|
+
readonly success: true;
|
|
87
|
+
readonly collections: ProcedureCollection[];
|
|
88
|
+
} | {
|
|
89
|
+
readonly success: false;
|
|
90
|
+
readonly code: DiscoveryErrorCode;
|
|
91
|
+
readonly message: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Options for file scanning
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
export interface ScanOptions {
|
|
98
|
+
readonly recursive: boolean;
|
|
99
|
+
readonly extensions: readonly string[];
|
|
100
|
+
readonly exclude: readonly string[];
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAMvD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;CAOrB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAM9F;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAErC;;;;;;OAMG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;CACxD;AAMD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gDAAgD;IAChD,QAAQ,CAAC,WAAW,EAAE,mBAAmB,EAAE,CAAC;IAE5C,kCAAkC;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAEzC,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAExC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAChD;AAMD;;;GAGG;AACH,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,EAAE,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7F;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Procedure Discovery Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the procedure discovery system that auto-scans
|
|
5
|
+
* and registers procedures from the filesystem.
|
|
6
|
+
*
|
|
7
|
+
* @module discovery/types
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Error Codes
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Error codes for discovery operations
|
|
14
|
+
*
|
|
15
|
+
* Range: E40xx (discovery domain)
|
|
16
|
+
*/
|
|
17
|
+
export const DiscoveryErrorCode = {
|
|
18
|
+
DIRECTORY_NOT_FOUND: 'E4001',
|
|
19
|
+
NO_PROCEDURES_FOUND: 'E4002',
|
|
20
|
+
INVALID_EXPORT: 'E4003',
|
|
21
|
+
FILE_LOAD_ERROR: 'E4004',
|
|
22
|
+
PERMISSION_DENIED: 'E4005',
|
|
23
|
+
INVALID_FILE_TYPE: 'E4006',
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,+EAA+E;AAC/E,cAAc;AACd,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,mBAAmB,EAAE,OAAO;IAC5B,mBAAmB,EAAE,OAAO;IAC5B,cAAc,EAAE,OAAO;IACvB,eAAe,EAAE,OAAO;IACxB,iBAAiB,EAAE,OAAO;IAC1B,iBAAiB,EAAE,OAAO;CAClB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -49,4 +49,6 @@ export type { RestAdapterOptions, RestMapping, RestRoute } from './rest/index.js
|
|
|
49
49
|
export { buildNestedRestPath, buildRestPath, createRoutesRegistrar, followsNamingConvention, generateRestRoutes, getRouteSummary, inferResourceName, parseNamingConvention, registerRestRoutes, rest, } from './rest/index.js';
|
|
50
50
|
export type { AnyRouter, InferAppRouter, TRPCInstance, TRPCPluginOptions, } from './trpc/index.js';
|
|
51
51
|
export { buildTRPCRouter, createAppRouter, createTRPC, createTRPCContextFactory, registerTRPCPlugin, veloxErrorToTRPCError, } from './trpc/index.js';
|
|
52
|
+
export type { DiscoveryOptions, DiscoveryResult, DiscoveryWarning } from './discovery/index.js';
|
|
53
|
+
export { DiscoveryError, DiscoveryErrorCode, directoryNotFound, discoverProcedures, discoverProceduresVerbose, fileLoadError, invalidExport, invalidFileType, isDiscoveryError, noProceduresFound, permissionDenied, } from './discovery/index.js';
|
|
52
54
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH,6BAA6B;AAC7B,eAAO,MAAM,cAAc,EAAE,MAA+C,CAAC;AAO7E,YAAY,EAEV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EAEf,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EAEnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAEhB,oBAAoB,EAEpB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAMpB,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAEV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAS9B,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAEL,mBAAmB,EACnB,aAAa,EAEb,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAElB,IAAI,GACL,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAEV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAQH,6BAA6B;AAC7B,eAAO,MAAM,cAAc,EAAE,MAA+C,CAAC;AAO7E,YAAY,EAEV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EAEf,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EAEnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,gBAAgB,EAEhB,oBAAoB,EAEpB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAMpB,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMvD,OAAO,EAEL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAEV,mBAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAS9B,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAEL,mBAAmB,EACnB,aAAa,EAEb,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAElB,IAAI,GACL,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAEV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAEL,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAMzB,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACb,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -63,4 +63,5 @@ rest, } from './rest/index.js';
|
|
|
63
63
|
export {
|
|
64
64
|
// tRPC utilities
|
|
65
65
|
buildTRPCRouter, createAppRouter, createTRPC, createTRPCContextFactory, registerTRPCPlugin, veloxErrorToTRPCError, } from './trpc/index.js';
|
|
66
|
+
export { DiscoveryError, DiscoveryErrorCode, directoryNotFound, discoverProcedures, discoverProceduresVerbose, fileLoadError, invalidExport, invalidFileType, isDiscoveryError, noProceduresFound, permissionDenied, } from './discovery/index.js';
|
|
66
67
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,6CAA6C;AAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,6BAA6B;AAC7B,MAAM,CAAC,MAAM,cAAc,GAAW,WAAW,CAAC,OAAO,IAAI,eAAe,CAAC;AAmC7E,OAAO;AACL,YAAY;AACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,OAAO;AACL,oBAAoB;AACpB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAoBhC,OAAO;AACL,qBAAqB;AACrB,mBAAmB,EACnB,aAAa;AACb,0BAA0B;AAC1B,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB;AAClB,2BAA2B;AAC3B,IAAI,GACL,MAAM,iBAAiB,CAAC;AAazB,OAAO;AACL,iBAAiB;AACjB,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,6CAA6C;AAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;AAEtE,6BAA6B;AAC7B,MAAM,CAAC,MAAM,cAAc,GAAW,WAAW,CAAC,OAAO,IAAI,eAAe,CAAC;AAmC7E,OAAO;AACL,YAAY;AACZ,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAOpB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEvD,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,OAAO;AACL,oBAAoB;AACpB,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,GACV,MAAM,wBAAwB,CAAC;AAoBhC,OAAO;AACL,qBAAqB;AACrB,mBAAmB,EACnB,aAAa;AACb,0BAA0B;AAC1B,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB;AAClB,2BAA2B;AAC3B,IAAI,GACL,MAAM,iBAAiB,CAAC;AAazB,OAAO;AACL,iBAAiB;AACjB,eAAe,EACf,eAAe,EACf,UAAU,EACV,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAOzB,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,yBAAyB,EACzB,aAAa,EACb,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veloxts/router",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Procedure definitions with tRPC and REST routing for VeloxTS framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@trpc/server": "11.7.2",
|
|
29
29
|
"fastify": "5.6.2",
|
|
30
|
-
"@veloxts/core": "0.4.
|
|
31
|
-
"@veloxts/validation": "0.4.
|
|
30
|
+
"@veloxts/core": "0.4.3",
|
|
31
|
+
"@veloxts/validation": "0.4.3"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@vitest/coverage-v8": "4.0.15",
|