@ya-modbus/driver-loader 0.6.0 → 0.7.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/CHANGELOG.md +6 -0
- package/dist/cjs/config-validator.d.ts.map +1 -0
- package/dist/cjs/config-validator.js.map +1 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/{errors.js → cjs/errors.js} +0 -2
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/loader.d.ts.map +1 -0
- package/dist/cjs/loader.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/testing/index.d.ts.map +1 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/testing.d.ts.map +1 -0
- package/dist/cjs/testing.js.map +1 -0
- package/dist/esm/config-validator.d.ts +53 -0
- package/dist/esm/config-validator.d.ts.map +1 -0
- package/dist/esm/config-validator.js +308 -0
- package/dist/esm/config-validator.js.map +1 -0
- package/dist/esm/errors.d.ts +69 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +81 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/loader.d.ts +122 -0
- package/dist/esm/loader.d.ts.map +1 -0
- package/dist/esm/loader.js +204 -0
- package/dist/esm/loader.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/testing/index.d.ts +21 -0
- package/dist/esm/testing/index.d.ts.map +1 -0
- package/dist/esm/testing/index.js +20 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing.d.ts +64 -0
- package/dist/esm/testing.d.ts.map +1 -0
- package/dist/esm/testing.js +70 -0
- package/dist/esm/testing.js.map +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/package.json +27 -10
- package/dist/config-validator.d.ts.map +0 -1
- package/dist/config-validator.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/loader.d.ts.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js.map +0 -1
- /package/dist/{config-validator.d.ts → cjs/config-validator.d.ts} +0 -0
- /package/dist/{config-validator.js → cjs/config-validator.js} +0 -0
- /package/dist/{errors.d.ts → cjs/errors.d.ts} +0 -0
- /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/dist/{index.js → cjs/index.js} +0 -0
- /package/dist/{loader.d.ts → cjs/loader.d.ts} +0 -0
- /package/dist/{loader.js → cjs/loader.js} +0 -0
- /package/dist/{testing → cjs/testing}/index.d.ts +0 -0
- /package/dist/{testing → cjs/testing}/index.js +0 -0
- /package/dist/{testing.d.ts → cjs/testing.d.ts} +0 -0
- /package/dist/{testing.js → cjs/testing.js} +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for driver-loader
|
|
3
|
+
*
|
|
4
|
+
* These error classes provide better error handling and type safety
|
|
5
|
+
* compared to string-based error detection.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Error thrown when driver configuration validation fails
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { loadDriver, ValidationError } from '@ya-modbus/driver-loader'
|
|
13
|
+
*
|
|
14
|
+
* try {
|
|
15
|
+
* await loadDriver({ driverPackage: 'my-driver' })
|
|
16
|
+
* } catch (error) {
|
|
17
|
+
* if (error instanceof ValidationError) {
|
|
18
|
+
* console.error(`Validation failed for field: ${error.field}`)
|
|
19
|
+
* console.error(`Message: ${error.message}`)
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class ValidationError extends Error {
|
|
25
|
+
constructor(message, field) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.field = field;
|
|
28
|
+
this.name = 'ValidationError';
|
|
29
|
+
Object.setPrototypeOf(this, ValidationError.prototype);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when a driver package cannot be found or loaded
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { loadDriver, DriverNotFoundError } from '@ya-modbus/driver-loader'
|
|
38
|
+
*
|
|
39
|
+
* try {
|
|
40
|
+
* await loadDriver({ driverPackage: 'missing-driver' })
|
|
41
|
+
* } catch (error) {
|
|
42
|
+
* if (error instanceof DriverNotFoundError) {
|
|
43
|
+
* console.error(`Package not found: ${error.packageName}`)
|
|
44
|
+
* console.error(`Install with: npm install ${error.packageName}`)
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export class DriverNotFoundError extends Error {
|
|
50
|
+
constructor(message, packageName) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.packageName = packageName;
|
|
53
|
+
this.name = 'DriverNotFoundError';
|
|
54
|
+
Object.setPrototypeOf(this, DriverNotFoundError.prototype);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Error thrown when package.json is not found or invalid
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* import { loadDriver, PackageJsonError } from '@ya-modbus/driver-loader'
|
|
63
|
+
*
|
|
64
|
+
* try {
|
|
65
|
+
* await loadDriver({}) // Auto-detect from current directory
|
|
66
|
+
* } catch (error) {
|
|
67
|
+
* if (error instanceof PackageJsonError) {
|
|
68
|
+
* console.error('package.json issue:', error.message)
|
|
69
|
+
* // Examples: missing file, invalid JSON, missing keywords
|
|
70
|
+
* }
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export class PackageJsonError extends Error {
|
|
75
|
+
constructor(message) {
|
|
76
|
+
super(message);
|
|
77
|
+
this.name = 'PackageJsonError';
|
|
78
|
+
Object.setPrototypeOf(this, PackageJsonError.prototype);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YACE,OAAe,EACC,KAAc;QAE9B,KAAK,CAAC,OAAO,CAAC,CAAA;QAFE,UAAK,GAAL,KAAK,CAAS;QAG9B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,SAAS,CAAC,CAAA;IACxD,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YACE,OAAe,EACC,WAAmB;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAA;QAFE,gBAAW,GAAX,WAAW,CAAQ;QAGnC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAC5D,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;QAC9B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { loadDriver, clearDriverCache, getDriverCacheStats } from './loader.js';
|
|
2
|
+
export type { LoadedDriver, LoadDriverOptions, SystemDependencies, DriverCacheStats, Logger, } from './loader.js';
|
|
3
|
+
export { validateDefaultConfig, validateSupportedConfig, validateDevices, crossValidateConfigs, } from './config-validator.js';
|
|
4
|
+
export { ValidationError, DriverNotFoundError, PackageJsonError } from './errors.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAC/E,YAAY,EACV,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,MAAM,GACP,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GACrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { loadDriver, clearDriverCache, getDriverCacheStats } from './loader.js';
|
|
2
|
+
export { validateDefaultConfig, validateSupportedConfig, validateDevices, crossValidateConfigs, } from './config-validator.js';
|
|
3
|
+
export { ValidationError, DriverNotFoundError, PackageJsonError } from './errors.js';
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAQ/E,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,oBAAoB,GACrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import type { CreateDriverFunction, DefaultConfig, DeviceRegistry, SupportedConfig } from '@ya-modbus/driver-types';
|
|
2
|
+
/**
|
|
3
|
+
* Loaded driver module with configuration metadata
|
|
4
|
+
*/
|
|
5
|
+
export interface LoadedDriver {
|
|
6
|
+
/** Driver factory function */
|
|
7
|
+
createDriver: CreateDriverFunction;
|
|
8
|
+
/** Registry of supported devices (for multi-device drivers) */
|
|
9
|
+
devices?: DeviceRegistry;
|
|
10
|
+
/** Factory-default device configuration (if provided by driver) */
|
|
11
|
+
defaultConfig?: DefaultConfig;
|
|
12
|
+
/** Supported configuration constraints (if provided by driver) */
|
|
13
|
+
supportedConfig?: SupportedConfig;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Logger interface for driver loading
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { loadDriver, type Logger } from '@ya-modbus/driver-loader'
|
|
21
|
+
*
|
|
22
|
+
* const logger: Logger = {
|
|
23
|
+
* warn: (msg) => console.warn('[DRIVER]', msg),
|
|
24
|
+
* debug: (msg) => console.debug('[DRIVER]', msg), // Optional
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* const driver = await loadDriver({ logger })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export interface Logger {
|
|
31
|
+
/** Log warning messages */
|
|
32
|
+
warn: (message: string) => void;
|
|
33
|
+
/** Log debug messages (optional) */
|
|
34
|
+
debug?: (message: string) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Driver loading options
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { loadDriver } from '@ya-modbus/driver-loader'
|
|
42
|
+
*
|
|
43
|
+
* // Auto-detect from current directory
|
|
44
|
+
* const driver1 = await loadDriver({})
|
|
45
|
+
*
|
|
46
|
+
* // Load specific package
|
|
47
|
+
* const driver2 = await loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })
|
|
48
|
+
*
|
|
49
|
+
* // With custom logger
|
|
50
|
+
* const driver3 = await loadDriver({
|
|
51
|
+
* driverPackage: 'my-driver',
|
|
52
|
+
* logger: {
|
|
53
|
+
* warn: (msg) => console.warn('[WARN]', msg),
|
|
54
|
+
* debug: (msg) => console.debug('[DEBUG]', msg),
|
|
55
|
+
* }
|
|
56
|
+
* })
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export interface LoadDriverOptions {
|
|
60
|
+
/**
|
|
61
|
+
* Explicit driver package name
|
|
62
|
+
* e.g., 'ya-modbus-driver-xymd1' or '@org/driver-pkg'
|
|
63
|
+
*/
|
|
64
|
+
driverPackage?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Custom logger for warnings and debug messages
|
|
67
|
+
* Defaults to console if not provided
|
|
68
|
+
*/
|
|
69
|
+
logger?: Logger;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* System dependencies for driver loading (for dependency injection)
|
|
73
|
+
*/
|
|
74
|
+
export interface SystemDependencies {
|
|
75
|
+
readFile: (path: string, encoding: 'utf-8') => Promise<string>;
|
|
76
|
+
importModule: (modulePath: string) => Promise<unknown>;
|
|
77
|
+
getCwd: () => string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Driver cache statistics
|
|
81
|
+
*/
|
|
82
|
+
export interface DriverCacheStats {
|
|
83
|
+
/** Number of cache hits */
|
|
84
|
+
hits: number;
|
|
85
|
+
/** Number of cache misses */
|
|
86
|
+
misses: number;
|
|
87
|
+
/** Number of cached drivers */
|
|
88
|
+
size: number;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Clear the driver cache
|
|
92
|
+
* Useful for testing or when you need to reload drivers
|
|
93
|
+
*/
|
|
94
|
+
export declare function clearDriverCache(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get cache statistics
|
|
97
|
+
* @returns Current cache statistics including hits, misses, and size
|
|
98
|
+
*/
|
|
99
|
+
export declare function getDriverCacheStats(): DriverCacheStats;
|
|
100
|
+
/**
|
|
101
|
+
* Load a driver package dynamically
|
|
102
|
+
*
|
|
103
|
+
* Supports two modes:
|
|
104
|
+
* 1. Explicit package: `loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })`
|
|
105
|
+
* 2. Auto-detect from cwd: `loadDriver({})` - reads package.json from current directory
|
|
106
|
+
*
|
|
107
|
+
* Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* // Auto-detect from current directory
|
|
111
|
+
* const driver = await loadDriver({})
|
|
112
|
+
*
|
|
113
|
+
* // Load explicit package
|
|
114
|
+
* const driver = await loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })
|
|
115
|
+
*
|
|
116
|
+
* @param options - Loading options (defaults to local package detection)
|
|
117
|
+
* @param deps - System dependencies (for testing, uses Node.js built-ins by default)
|
|
118
|
+
* @returns Loaded driver with createDriver function and optional configuration metadata
|
|
119
|
+
* @throws Error if driver cannot be loaded or is invalid
|
|
120
|
+
*/
|
|
121
|
+
export declare function loadDriver(options?: LoadDriverOptions, deps?: SystemDependencies): Promise<LoadedDriver>;
|
|
122
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,eAAe,EAChB,MAAM,yBAAyB,CAAA;AAWhC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,8BAA8B;IAC9B,YAAY,EAAE,oBAAoB,CAAA;IAElC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,cAAc,CAAA;IAExB,mEAAmE;IACnE,aAAa,CAAC,EAAE,aAAa,CAAA;IAE7B,kEAAkE;IAClE,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,MAAM;IACrB,2BAA2B;IAC3B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B,oCAAoC;IACpC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9D,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACtD,MAAM,EAAE,MAAM,MAAM,CAAA;CACrB;AAeD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAA;IACd,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAA;CACb;AAeD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,gBAAgB,CAMtD;AAwED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,iBAAsB,EAC/B,IAAI,GAAE,kBAAgC,GACrC,OAAO,CAAC,YAAY,CAAC,CAsHvB"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { crossValidateConfigs, outputConfigWarnings, validateDefaultConfig, validateDevices, validateSupportedConfig, } from './config-validator.js';
|
|
4
|
+
import { DriverNotFoundError, PackageJsonError, ValidationError } from './errors.js';
|
|
5
|
+
/**
|
|
6
|
+
* Default system dependencies using Node.js built-ins
|
|
7
|
+
*/
|
|
8
|
+
/* istanbul ignore next */
|
|
9
|
+
const defaultDeps = {
|
|
10
|
+
/* istanbul ignore next */
|
|
11
|
+
readFile: (path, encoding) => readFile(path, encoding),
|
|
12
|
+
/* istanbul ignore next */
|
|
13
|
+
importModule: (modulePath) => import(modulePath),
|
|
14
|
+
/* istanbul ignore next */
|
|
15
|
+
getCwd: () => process.cwd(),
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* LRU cache for loaded drivers
|
|
19
|
+
*/
|
|
20
|
+
const driverCache = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Cache statistics
|
|
23
|
+
*/
|
|
24
|
+
const cacheStats = {
|
|
25
|
+
hits: 0,
|
|
26
|
+
misses: 0,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Clear the driver cache
|
|
30
|
+
* Useful for testing or when you need to reload drivers
|
|
31
|
+
*/
|
|
32
|
+
export function clearDriverCache() {
|
|
33
|
+
driverCache.clear();
|
|
34
|
+
cacheStats.hits = 0;
|
|
35
|
+
cacheStats.misses = 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get cache statistics
|
|
39
|
+
* @returns Current cache statistics including hits, misses, and size
|
|
40
|
+
*/
|
|
41
|
+
export function getDriverCacheStats() {
|
|
42
|
+
return {
|
|
43
|
+
hits: cacheStats.hits,
|
|
44
|
+
misses: cacheStats.misses,
|
|
45
|
+
size: driverCache.size,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Auto-detect local driver package from package.json
|
|
50
|
+
*
|
|
51
|
+
* @param deps - System dependencies
|
|
52
|
+
* @returns Package name if valid driver package
|
|
53
|
+
* @throws Error if not a valid driver package
|
|
54
|
+
*/
|
|
55
|
+
async function detectLocalPackage(deps) {
|
|
56
|
+
try {
|
|
57
|
+
const packageJsonPath = join(deps.getCwd(), 'package.json');
|
|
58
|
+
const packageJsonContent = await deps.readFile(packageJsonPath, 'utf-8');
|
|
59
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
60
|
+
const keywords = packageJson.keywords ?? [];
|
|
61
|
+
if (!keywords.includes('ya-modbus-driver')) {
|
|
62
|
+
throw new PackageJsonError('Current package is not a ya-modbus driver. ' +
|
|
63
|
+
'Add "ya-modbus-driver" to keywords in package.json');
|
|
64
|
+
}
|
|
65
|
+
const name = packageJson.name;
|
|
66
|
+
if (!name) {
|
|
67
|
+
throw new PackageJsonError('package.json must have a "name" field');
|
|
68
|
+
}
|
|
69
|
+
return name;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error.code === 'ENOENT') {
|
|
73
|
+
throw new PackageJsonError('package.json not found in current directory. ' +
|
|
74
|
+
'Run this command from a driver package directory or specify --driver');
|
|
75
|
+
}
|
|
76
|
+
if (error instanceof SyntaxError) {
|
|
77
|
+
throw new PackageJsonError('Failed to parse package.json: invalid JSON');
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Try to import a module with multiple path attempts
|
|
84
|
+
*
|
|
85
|
+
* @param paths - Array of module paths to try
|
|
86
|
+
* @param deps - System dependencies
|
|
87
|
+
* @returns Imported module
|
|
88
|
+
* @throws Error if all paths fail
|
|
89
|
+
*/
|
|
90
|
+
async function tryImport(paths, deps) {
|
|
91
|
+
const errors = [];
|
|
92
|
+
for (const path of paths) {
|
|
93
|
+
try {
|
|
94
|
+
return await deps.importModule(path);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
errors.push(error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const lastError = errors[errors.length - 1];
|
|
101
|
+
throw new Error(`Failed to import module from any path. Tried: ${paths.join(', ')}\nLast error: ${lastError?.message}`, { cause: lastError });
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Load a driver package dynamically
|
|
105
|
+
*
|
|
106
|
+
* Supports two modes:
|
|
107
|
+
* 1. Explicit package: `loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })`
|
|
108
|
+
* 2. Auto-detect from cwd: `loadDriver({})` - reads package.json from current directory
|
|
109
|
+
*
|
|
110
|
+
* Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* // Auto-detect from current directory
|
|
114
|
+
* const driver = await loadDriver({})
|
|
115
|
+
*
|
|
116
|
+
* // Load explicit package
|
|
117
|
+
* const driver = await loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })
|
|
118
|
+
*
|
|
119
|
+
* @param options - Loading options (defaults to local package detection)
|
|
120
|
+
* @param deps - System dependencies (for testing, uses Node.js built-ins by default)
|
|
121
|
+
* @returns Loaded driver with createDriver function and optional configuration metadata
|
|
122
|
+
* @throws Error if driver cannot be loaded or is invalid
|
|
123
|
+
*/
|
|
124
|
+
export async function loadDriver(options = {}, deps = defaultDeps) {
|
|
125
|
+
const { driverPackage, logger = console } = options;
|
|
126
|
+
try {
|
|
127
|
+
let packageName;
|
|
128
|
+
let driverModule;
|
|
129
|
+
if (driverPackage) {
|
|
130
|
+
packageName = driverPackage;
|
|
131
|
+
const cached = driverCache.get(packageName);
|
|
132
|
+
if (cached) {
|
|
133
|
+
cacheStats.hits++;
|
|
134
|
+
return cached;
|
|
135
|
+
}
|
|
136
|
+
cacheStats.misses++;
|
|
137
|
+
try {
|
|
138
|
+
driverModule = await deps.importModule(driverPackage);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
throw new DriverNotFoundError(`Driver package not found: ${driverPackage}\nInstall it with: npm install ${driverPackage}`, driverPackage);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
packageName = await detectLocalPackage(deps);
|
|
146
|
+
const cached = driverCache.get(packageName);
|
|
147
|
+
if (cached) {
|
|
148
|
+
cacheStats.hits++;
|
|
149
|
+
return cached;
|
|
150
|
+
}
|
|
151
|
+
cacheStats.misses++;
|
|
152
|
+
const cwd = deps.getCwd();
|
|
153
|
+
const importPaths = [
|
|
154
|
+
join(cwd, 'src', 'index.js'),
|
|
155
|
+
join(cwd, 'src', 'index.ts'),
|
|
156
|
+
join(cwd, 'dist', 'index.js'),
|
|
157
|
+
packageName,
|
|
158
|
+
];
|
|
159
|
+
driverModule = await tryImport(importPaths, deps);
|
|
160
|
+
}
|
|
161
|
+
if (!driverModule || typeof driverModule !== 'object') {
|
|
162
|
+
throw new ValidationError('Driver package must export a createDriver function', 'createDriver');
|
|
163
|
+
}
|
|
164
|
+
const { createDriver, DEVICES, DEFAULT_CONFIG, SUPPORTED_CONFIG } = driverModule;
|
|
165
|
+
if (!createDriver) {
|
|
166
|
+
throw new ValidationError('Driver package must export a createDriver function', 'createDriver');
|
|
167
|
+
}
|
|
168
|
+
if (typeof createDriver !== 'function') {
|
|
169
|
+
throw new ValidationError('Driver package must export a createDriver function', 'createDriver');
|
|
170
|
+
}
|
|
171
|
+
const result = {
|
|
172
|
+
createDriver: createDriver,
|
|
173
|
+
};
|
|
174
|
+
if (DEVICES !== null && DEVICES !== undefined) {
|
|
175
|
+
result.devices = validateDevices(DEVICES, logger);
|
|
176
|
+
}
|
|
177
|
+
if (DEFAULT_CONFIG !== null && DEFAULT_CONFIG !== undefined) {
|
|
178
|
+
result.defaultConfig = validateDefaultConfig(DEFAULT_CONFIG);
|
|
179
|
+
}
|
|
180
|
+
if (SUPPORTED_CONFIG !== null && SUPPORTED_CONFIG !== undefined) {
|
|
181
|
+
result.supportedConfig = validateSupportedConfig(SUPPORTED_CONFIG);
|
|
182
|
+
}
|
|
183
|
+
if (result.defaultConfig && result.supportedConfig) {
|
|
184
|
+
const warnings = crossValidateConfigs(result.defaultConfig, result.supportedConfig);
|
|
185
|
+
if (warnings.length > 0) {
|
|
186
|
+
outputConfigWarnings('Driver DEFAULT_CONFIG', warnings, logger);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
driverCache.set(packageName, result);
|
|
190
|
+
return result;
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
if (error instanceof ValidationError ||
|
|
194
|
+
error instanceof DriverNotFoundError ||
|
|
195
|
+
error instanceof PackageJsonError) {
|
|
196
|
+
throw error;
|
|
197
|
+
}
|
|
198
|
+
if (error instanceof Error) {
|
|
199
|
+
throw new Error(`Failed to load driver: ${error.message}`, { cause: error });
|
|
200
|
+
}
|
|
201
|
+
throw new Error('Failed to load driver: Unknown error');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for @ya-modbus/driver-loader
|
|
3
|
+
*
|
|
4
|
+
* Import from '@ya-modbus/driver-loader/testing' in your tests
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createMockDriver, mockSystemDeps } from '@ya-modbus/driver-loader/testing'
|
|
9
|
+
*
|
|
10
|
+
* const mockDriver = createMockDriver({
|
|
11
|
+
* defaultConfig: { baudRate: 9600 }
|
|
12
|
+
* })
|
|
13
|
+
*
|
|
14
|
+
* const deps = mockSystemDeps({
|
|
15
|
+
* importModule: jest.fn().mockResolvedValue(mockDriver)
|
|
16
|
+
* })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { createMockDriver, mockSystemDeps } from '../testing.js';
|
|
20
|
+
export type { MockDriverOptions, MockSystemDepsOptions } from '../testing.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAChE,YAAY,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for @ya-modbus/driver-loader
|
|
3
|
+
*
|
|
4
|
+
* Import from '@ya-modbus/driver-loader/testing' in your tests
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createMockDriver, mockSystemDeps } from '@ya-modbus/driver-loader/testing'
|
|
9
|
+
*
|
|
10
|
+
* const mockDriver = createMockDriver({
|
|
11
|
+
* defaultConfig: { baudRate: 9600 }
|
|
12
|
+
* })
|
|
13
|
+
*
|
|
14
|
+
* const deps = mockSystemDeps({
|
|
15
|
+
* importModule: jest.fn().mockResolvedValue(mockDriver)
|
|
16
|
+
* })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export { createMockDriver, mockSystemDeps } from '../testing.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/testing/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for driver-loader
|
|
3
|
+
*
|
|
4
|
+
* Provides mock drivers and system dependencies for testing applications
|
|
5
|
+
* that use driver-loader.
|
|
6
|
+
*/
|
|
7
|
+
import type { CreateDriverFunction, DefaultConfig, DeviceRegistry, SupportedConfig } from '@ya-modbus/driver-types';
|
|
8
|
+
import type { LoadedDriver, SystemDependencies } from './loader.js';
|
|
9
|
+
/**
|
|
10
|
+
* Options for creating a mock driver
|
|
11
|
+
*/
|
|
12
|
+
export interface MockDriverOptions {
|
|
13
|
+
/** Custom createDriver implementation */
|
|
14
|
+
createDriver?: CreateDriverFunction;
|
|
15
|
+
/** Mock default configuration */
|
|
16
|
+
defaultConfig?: DefaultConfig;
|
|
17
|
+
/** Mock supported configuration */
|
|
18
|
+
supportedConfig?: SupportedConfig;
|
|
19
|
+
/** Mock device registry */
|
|
20
|
+
devices?: DeviceRegistry;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a mock driver for testing
|
|
24
|
+
*
|
|
25
|
+
* @param options - Mock driver options
|
|
26
|
+
* @returns Mock driver that can be used with loadDriver
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const mockDriver = createMockDriver({
|
|
31
|
+
* defaultConfig: { baudRate: 9600 },
|
|
32
|
+
* devices: { 'test': { manufacturer: 'Test', model: 'Model' } }
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function createMockDriver(options?: MockDriverOptions): LoadedDriver;
|
|
37
|
+
/**
|
|
38
|
+
* Options for creating mock system dependencies
|
|
39
|
+
*/
|
|
40
|
+
export interface MockSystemDepsOptions {
|
|
41
|
+
/** Custom readFile implementation */
|
|
42
|
+
readFile?: SystemDependencies['readFile'];
|
|
43
|
+
/** Custom importModule implementation */
|
|
44
|
+
importModule?: SystemDependencies['importModule'];
|
|
45
|
+
/** Custom getCwd implementation */
|
|
46
|
+
getCwd?: SystemDependencies['getCwd'];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Create mock system dependencies for testing
|
|
50
|
+
*
|
|
51
|
+
* @param options - Mock system dependencies options
|
|
52
|
+
* @returns Mock SystemDependencies that can be passed to loadDriver
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const deps = mockSystemDeps({
|
|
57
|
+
* importModule: jest.fn().mockResolvedValue(mockDriver)
|
|
58
|
+
* })
|
|
59
|
+
*
|
|
60
|
+
* const driver = await loadDriver({ driverPackage: 'test' }, deps)
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function mockSystemDeps(options?: MockSystemDepsOptions): SystemDependencies;
|
|
64
|
+
//# sourceMappingURL=testing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,eAAe,EAChB,MAAM,yBAAyB,CAAA;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEnE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,YAAY,CAAC,EAAE,oBAAoB,CAAA;IACnC,iCAAiC;IACjC,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,mCAAmC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,2BAA2B;IAC3B,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,CAyB9E;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qCAAqC;IACrC,QAAQ,CAAC,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAA;IACzC,yCAAyC;IACzC,YAAY,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAA;IACjD,mCAAmC;IACnC,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAA;CACtC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,kBAAkB,CAoBtF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for driver-loader
|
|
3
|
+
*
|
|
4
|
+
* Provides mock drivers and system dependencies for testing applications
|
|
5
|
+
* that use driver-loader.
|
|
6
|
+
*/
|
|
7
|
+
import { jest } from '@jest/globals';
|
|
8
|
+
/**
|
|
9
|
+
* Create a mock driver for testing
|
|
10
|
+
*
|
|
11
|
+
* @param options - Mock driver options
|
|
12
|
+
* @returns Mock driver that can be used with loadDriver
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const mockDriver = createMockDriver({
|
|
17
|
+
* defaultConfig: { baudRate: 9600 },
|
|
18
|
+
* devices: { 'test': { manufacturer: 'Test', model: 'Model' } }
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function createMockDriver(options = {}) {
|
|
23
|
+
const { createDriver = jest.fn().mockReturnValue({}), defaultConfig, supportedConfig, devices, } = options;
|
|
24
|
+
const result = {
|
|
25
|
+
createDriver,
|
|
26
|
+
};
|
|
27
|
+
if (defaultConfig) {
|
|
28
|
+
result.defaultConfig = defaultConfig;
|
|
29
|
+
}
|
|
30
|
+
if (supportedConfig) {
|
|
31
|
+
result.supportedConfig = supportedConfig;
|
|
32
|
+
}
|
|
33
|
+
if (devices) {
|
|
34
|
+
result.devices = devices;
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create mock system dependencies for testing
|
|
40
|
+
*
|
|
41
|
+
* @param options - Mock system dependencies options
|
|
42
|
+
* @returns Mock SystemDependencies that can be passed to loadDriver
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const deps = mockSystemDeps({
|
|
47
|
+
* importModule: jest.fn().mockResolvedValue(mockDriver)
|
|
48
|
+
* })
|
|
49
|
+
*
|
|
50
|
+
* const driver = await loadDriver({ driverPackage: 'test' }, deps)
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function mockSystemDeps(options = {}) {
|
|
54
|
+
const { readFile, importModule, getCwd } = options;
|
|
55
|
+
return {
|
|
56
|
+
readFile: readFile ??
|
|
57
|
+
jest
|
|
58
|
+
.fn()
|
|
59
|
+
.mockResolvedValue('{}'),
|
|
60
|
+
importModule: importModule ??
|
|
61
|
+
jest
|
|
62
|
+
.fn()
|
|
63
|
+
.mockResolvedValue(createMockDriver()),
|
|
64
|
+
getCwd: getCwd ??
|
|
65
|
+
jest
|
|
66
|
+
.fn()
|
|
67
|
+
.mockReturnValue('/mock/cwd'),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/testing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAwBpC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA6B,EAAE;IAC9D,MAAM,EACJ,YAAY,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,CAAoC,EAC/E,aAAa,EACb,eAAe,EACf,OAAO,GACR,GAAG,OAAO,CAAA;IAEX,MAAM,MAAM,GAAiB;QAC3B,YAAY;KACb,CAAA;IAED,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,CAAC,aAAa,GAAG,aAAa,CAAA;IACtC,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,CAAC,eAAe,GAAG,eAAe,CAAA;IAC1C,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IAC1B,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAcD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAElD,OAAO;QACL,QAAQ,EACN,QAAQ;YACP,IAAI;iBACF,EAAE,EAAkC;iBACpC,iBAAiB,CAAC,IAAI,CAAoC;QAC/D,YAAY,EACV,YAAY;YACX,IAAI;iBACF,EAAE,EAAsC;iBACxC,iBAAiB,CAAC,gBAAgB,EAAE,CAAwC;QACjF,MAAM,EACJ,MAAM;YACL,IAAI;iBACF,EAAE,EAAgC;iBAClC,eAAe,CAAC,WAAW,CAAkC;KACnE,CAAA;AACH,CAAC"}
|