@ya-modbus/driver-loader 0.10.0 → 0.11.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +30 -3
  3. package/dist/cjs/src/driver-import.d.ts +14 -1
  4. package/dist/cjs/src/driver-import.d.ts.map +1 -1
  5. package/dist/cjs/src/driver-import.js +48 -0
  6. package/dist/cjs/src/driver-import.js.map +1 -1
  7. package/dist/cjs/src/entry-point.d.ts +20 -0
  8. package/dist/cjs/src/entry-point.d.ts.map +1 -0
  9. package/dist/cjs/src/entry-point.js +63 -0
  10. package/dist/cjs/src/entry-point.js.map +1 -0
  11. package/dist/cjs/src/errors.d.ts +23 -0
  12. package/dist/cjs/src/errors.d.ts.map +1 -1
  13. package/dist/cjs/src/errors.js +29 -1
  14. package/dist/cjs/src/errors.js.map +1 -1
  15. package/dist/cjs/src/index.d.ts +1 -1
  16. package/dist/cjs/src/index.d.ts.map +1 -1
  17. package/dist/cjs/src/index.js +2 -1
  18. package/dist/cjs/src/index.js.map +1 -1
  19. package/dist/cjs/src/loader.d.ts +6 -2
  20. package/dist/cjs/src/loader.d.ts.map +1 -1
  21. package/dist/cjs/src/loader.js +22 -67
  22. package/dist/cjs/src/loader.js.map +1 -1
  23. package/dist/cjs/src/local-package.d.ts +19 -0
  24. package/dist/cjs/src/local-package.d.ts.map +1 -0
  25. package/dist/cjs/src/local-package.js +50 -0
  26. package/dist/cjs/src/local-package.js.map +1 -0
  27. package/dist/cjs/src/module-errors.d.ts +24 -0
  28. package/dist/cjs/src/module-errors.d.ts.map +1 -1
  29. package/dist/cjs/src/module-errors.js +55 -0
  30. package/dist/cjs/src/module-errors.js.map +1 -1
  31. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  32. package/dist/esm/src/driver-import.d.ts +14 -1
  33. package/dist/esm/src/driver-import.d.ts.map +1 -1
  34. package/dist/esm/src/driver-import.js +49 -2
  35. package/dist/esm/src/driver-import.js.map +1 -1
  36. package/dist/esm/src/entry-point.d.ts +20 -0
  37. package/dist/esm/src/entry-point.d.ts.map +1 -0
  38. package/dist/esm/src/entry-point.js +59 -0
  39. package/dist/esm/src/entry-point.js.map +1 -0
  40. package/dist/esm/src/errors.d.ts +23 -0
  41. package/dist/esm/src/errors.d.ts.map +1 -1
  42. package/dist/esm/src/errors.js +27 -0
  43. package/dist/esm/src/errors.js.map +1 -1
  44. package/dist/esm/src/index.d.ts +1 -1
  45. package/dist/esm/src/index.d.ts.map +1 -1
  46. package/dist/esm/src/index.js +1 -1
  47. package/dist/esm/src/index.js.map +1 -1
  48. package/dist/esm/src/loader.d.ts +6 -2
  49. package/dist/esm/src/loader.d.ts.map +1 -1
  50. package/dist/esm/src/loader.js +24 -69
  51. package/dist/esm/src/loader.js.map +1 -1
  52. package/dist/esm/src/local-package.d.ts +19 -0
  53. package/dist/esm/src/local-package.d.ts.map +1 -0
  54. package/dist/esm/src/local-package.js +47 -0
  55. package/dist/esm/src/local-package.js.map +1 -0
  56. package/dist/esm/src/module-errors.d.ts +24 -0
  57. package/dist/esm/src/module-errors.d.ts.map +1 -1
  58. package/dist/esm/src/module-errors.js +54 -0
  59. package/dist/esm/src/module-errors.js.map +1 -1
  60. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  61. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.11.0](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/driver-loader@0.10.0...@ya-modbus/driver-loader@0.11.0) (2026-10-12)
7
+
8
+ ### Features
9
+
10
+ - **driver-loader:** load local drivers from their package.json entry point ([#581](https://github.com/groupsky/ya-modbus/issues/581)) ([177bb89](https://github.com/groupsky/ya-modbus/commit/177bb89eab449a4ed55fe7ce37695e314cfdd358)), closes [#24](https://github.com/groupsky/ya-modbus/issues/24)
11
+
6
12
  # [0.10.0](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/driver-loader@0.9.0...@ya-modbus/driver-loader@0.10.0) (2026-10-12)
7
13
 
8
14
  ### Features
package/README.md CHANGED
@@ -18,6 +18,10 @@ import { loadDriver } from '@ya-modbus/driver-loader'
18
18
  const driver = await loadDriver({})
19
19
  ```
20
20
 
21
+ The current directory must hold a package with the `ya-modbus-driver` keyword. The loader imports the file that Node loads for `import` of that package: `exports["."]` (conditions `node`, `import`, `module-sync`, `default`), else `main`, else `index.js`. The entry must name the file with its extension, and Node's `--conditions` flag is not used.
22
+
23
+ The driver must be built, and built again after each change to its source. If the entry file is missing (no `dist` directory), or it is TypeScript source that Node cannot run, `loadDriver` throws a `DriverNotBuiltError`: build the driver first (`npm run build`), or run with Node's built-in type stripping (Node 22.18+ or 24).
24
+
21
25
  ### Load specific driver package
22
26
 
23
27
  ```typescript
@@ -50,6 +54,7 @@ import {
50
54
  loadDriver,
51
55
  ValidationError,
52
56
  DriverNotFoundError,
57
+ DriverNotBuiltError,
53
58
  PackageJsonError,
54
59
  } from '@ya-modbus/driver-loader'
55
60
 
@@ -65,6 +70,8 @@ try {
65
70
  console.error(`Package not found: ${error.packageName}`)
66
71
  console.error(`Install with: npm install ${error.packageName}`)
67
72
  }
73
+ } else if (error instanceof DriverNotBuiltError) {
74
+ console.error(`${error.packageName} is not built: run npm run build`)
68
75
  } else if (error instanceof ValidationError) {
69
76
  console.error(`Validation failed for field: ${error.field}`)
70
77
  console.error(`Error: ${error.message}`)
@@ -87,8 +94,13 @@ try {
87
94
  - `cause?: unknown` - Set when the package is installed but fails to load: the original error
88
95
  - Example: Package not installed, wrong package name, syntax error in the driver
89
96
 
97
+ - **`DriverNotBuiltError`**: Driver package is installed but not built
98
+ - `packageName: string` - The package that cannot be loaded
99
+ - `cause?: unknown` - The error Node reported
100
+ - Example: Missing `dist` directory, TypeScript source that Node cannot run
101
+
90
102
  - **`PackageJsonError`**: package.json not found or invalid
91
- - Example: Missing package.json, invalid JSON, missing ya-modbus-driver keyword
103
+ - Example: Missing package.json, invalid JSON, missing ya-modbus-driver keyword, `exports` without an entry for `import`
92
104
 
93
105
  ### Custom Logging
94
106
 
@@ -128,7 +140,8 @@ Loads a ya-modbus driver package and validates its exports.
128
140
 
129
141
  **Throws:**
130
142
 
131
- - Error if driver package is not found
143
+ - `DriverNotFoundError` if driver package is not found or fails to load
144
+ - `DriverNotBuiltError` if the driver is not built
132
145
  - Error if driver exports are invalid
133
146
  - Error if configuration validation fails
134
147
 
@@ -303,6 +316,20 @@ If you encounter `Driver package not found` errors:
303
316
 
304
317
  If the message starts with `Failed to load driver package`, the package is installed but its code failed to load. Read the reason in the message (or `error.cause`) instead of reinstalling.
305
318
 
319
+ ### Driver Not Built
320
+
321
+ If you encounter `DriverNotBuiltError` (message `Cannot load driver <name>: ...`):
322
+
323
+ 1. **Build the driver:**
324
+
325
+ ```bash
326
+ npm run build
327
+ ```
328
+
329
+ 2. **Check the entry point:** `exports["."]` (or `main`) in package.json must name the built JavaScript file with its extension, for example `./dist/esm/index.js`.
330
+
331
+ 3. **TypeScript source:** Node 22.18+ and 24 run `.ts` files themselves, but only outside `node_modules`, and only if the source uses erasable TypeScript syntax (no enums) and imports files with their `.ts` extension. Build the driver otherwise.
332
+
306
333
  ### Module Resolution Issues
307
334
 
308
335
  If TypeScript or Node.js can't find `@ya-modbus/driver-loader`:
@@ -324,7 +351,7 @@ If TypeScript or Node.js can't find `@ya-modbus/driver-loader`:
324
351
  - Check that `"types"` field isn't excluding driver-loader
325
352
 
326
353
  4. **For local driver development:**
327
- - The loader tries multiple import paths: `src/index.js`, `src/index.ts`, `dist/index.js`
354
+ - The loader imports the entry file from `exports` or `main` in package.json
328
355
  - Build your driver before testing: `npm run build`
329
356
 
330
357
  ### Validation Failures
@@ -1,5 +1,6 @@
1
1
  import type { DriverPackageCandidates } from './driver-name.js';
2
2
  import type { SystemDependencies } from './loader.js';
3
+ type ImportDeps = Pick<SystemDependencies, 'importModule'>;
3
4
  /**
4
5
  * Import the first installed package of a list of candidates
5
6
  *
@@ -10,10 +11,22 @@ import type { SystemDependencies } from './loader.js';
10
11
  * @param candidates - Package names to try, in order
11
12
  * @param deps - System dependencies
12
13
  * @returns The imported module and the name of the package it came from
14
+ * @throws DriverNotBuiltError if the installed package is not built
13
15
  * @throws DriverNotFoundError if no candidate is installed or the installed one fails to load
14
16
  */
15
- export declare function importDriverPackage(name: string, candidates: DriverPackageCandidates, deps: Pick<SystemDependencies, 'importModule'>): Promise<{
17
+ export declare function importDriverPackage(name: string, candidates: DriverPackageCandidates, deps: ImportDeps): Promise<{
16
18
  packageName: string;
17
19
  driverModule: unknown;
18
20
  }>;
21
+ /**
22
+ * Import the entry file of the driver package in the current directory
23
+ *
24
+ * @param packageName - Name from package.json
25
+ * @param entryPoint - Absolute path of the entry file
26
+ * @param deps - System dependencies
27
+ * @returns The imported module
28
+ * @throws DriverNotBuiltError if the entry file is missing or is TypeScript that Node cannot run
29
+ */
30
+ export declare function importLocalDriver(packageName: string, entryPoint: string, deps: ImportDeps): Promise<unknown>;
31
+ export {};
19
32
  //# sourceMappingURL=driver-import.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver-import.d.ts","sourceRoot":"","sources":["../../../src/driver-import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGrD;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,uBAAuB,EACnC,IAAI,EAAE,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,GAC7C,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CAsBzD"}
1
+ {"version":3,"file":"driver-import.d.ts","sourceRoot":"","sources":["../../../src/driver-import.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAGrD,KAAK,UAAU,GAAG,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAA;AAmC1D;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,uBAAuB,EACnC,IAAI,EAAE,UAAU,GACf,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CA0BzD;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,OAAO,CAAC,CAWlB"}
@@ -1,8 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.importDriverPackage = importDriverPackage;
4
+ exports.importLocalDriver = importLocalDriver;
5
+ const node_url_1 = require("node:url");
4
6
  const errors_js_1 = require("./errors.js");
5
7
  const module_errors_js_1 = require("./module-errors.js");
8
+ const NOT_BUILT_HINTS = {
9
+ 'missing-file': 'Drivers are loaded as built JavaScript. Build the driver first (npm run build).',
10
+ typescript: 'Drivers are loaded as built JavaScript. Build the driver first (npm run build), ' +
11
+ "or run with Node's built-in type stripping (Node 22.18+ or 24) to load TypeScript source.",
12
+ 'typescript-unsupported': 'Drivers are loaded as built JavaScript. Build the driver first (npm run build). ' +
13
+ "Node's type stripping needs erasable syntax (no enums) and imports that name files with their .ts extension.",
14
+ 'typescript-in-node-modules': 'Node does not run TypeScript from node_modules, so a package must ship built JavaScript.',
15
+ };
16
+ /**
17
+ * Error for a driver that cannot be loaded because it is not built
18
+ *
19
+ * Shows what Node reported. The "imported from" part is left out when `hideImporter` is set,
20
+ * because then it only names the loader.
21
+ */
22
+ function createNotBuiltError(packageName, cause, notBuilt, hideImporter = false) {
23
+ const firstLine = cause.message.replace(/\n[\s\S]*/, '');
24
+ const reason = hideImporter ? firstLine.replace(/ imported from .*$/, '') : firstLine;
25
+ return new errors_js_1.DriverNotBuiltError(`Cannot load driver ${packageName}: ${reason}\n${NOT_BUILT_HINTS[notBuilt]}`, packageName, { cause });
26
+ }
6
27
  /**
7
28
  * Import the first installed package of a list of candidates
8
29
  *
@@ -13,6 +34,7 @@ const module_errors_js_1 = require("./module-errors.js");
13
34
  * @param candidates - Package names to try, in order
14
35
  * @param deps - System dependencies
15
36
  * @returns The imported module and the name of the package it came from
37
+ * @throws DriverNotBuiltError if the installed package is not built
16
38
  * @throws DriverNotFoundError if no candidate is installed or the installed one fails to load
17
39
  */
18
40
  async function importDriverPackage(name, candidates, deps) {
@@ -21,6 +43,10 @@ async function importDriverPackage(name, candidates, deps) {
21
43
  return { packageName, driverModule: await deps.importModule(packageName) };
22
44
  }
23
45
  catch (error) {
46
+ const notBuilt = (0, module_errors_js_1.getNotBuiltCause)(error);
47
+ if (notBuilt) {
48
+ throw createNotBuiltError(packageName, error, notBuilt);
49
+ }
24
50
  if (!(0, module_errors_js_1.isMissingPackageError)(error, packageName)) {
25
51
  const reason = error instanceof Error ? error.message : String(error);
26
52
  throw new errors_js_1.DriverNotFoundError(`Failed to load driver package ${packageName}: ${reason}`, packageName, { cause: error });
@@ -31,4 +57,26 @@ async function importDriverPackage(name, candidates, deps) {
31
57
  const tried = candidates.length > 1 ? `\nTried: ${candidates.join(', ')}` : '';
32
58
  throw new errors_js_1.DriverNotFoundError(`Driver package not found: ${name}${tried}\nInstall it with: npm install ${preferred}`, preferred);
33
59
  }
60
+ /**
61
+ * Import the entry file of the driver package in the current directory
62
+ *
63
+ * @param packageName - Name from package.json
64
+ * @param entryPoint - Absolute path of the entry file
65
+ * @param deps - System dependencies
66
+ * @returns The imported module
67
+ * @throws DriverNotBuiltError if the entry file is missing or is TypeScript that Node cannot run
68
+ */
69
+ async function importLocalDriver(packageName, entryPoint, deps) {
70
+ try {
71
+ return await deps.importModule((0, node_url_1.pathToFileURL)(entryPoint).href);
72
+ }
73
+ catch (error) {
74
+ const notBuilt = (0, module_errors_js_1.getNotBuiltCause)(error, entryPoint);
75
+ if (notBuilt === undefined) {
76
+ throw error;
77
+ }
78
+ // The missing entry file is reported as imported by the loader, which is no help
79
+ throw createNotBuiltError(packageName, error, notBuilt, notBuilt === 'missing-file');
80
+ }
81
+ }
34
82
  //# sourceMappingURL=driver-import.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver-import.js","sourceRoot":"","sources":["../../../src/driver-import.ts"],"names":[],"mappings":";;AAiBA,kDA0BC;AA1CD,2CAAiD;AAEjD,yDAA0D;AAE1D;;;;;;;;;;;GAWG;AACI,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,UAAmC,EACnC,IAA8C;IAE9C,KAAK,MAAM,WAAW,IAAI,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAA;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,IAAA,wCAAqB,EAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC/C,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBACrE,MAAM,IAAI,+BAAmB,CAC3B,iCAAiC,WAAW,KAAK,MAAM,EAAE,EACzD,WAAW,EACX,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,UAAU,CAAA;IAC9B,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,MAAM,IAAI,+BAAmB,CAC3B,6BAA6B,IAAI,GAAG,KAAK,kCAAkC,SAAS,EAAE,EACtF,SAAS,CACV,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"driver-import.js","sourceRoot":"","sources":["../../../src/driver-import.ts"],"names":[],"mappings":";;AAuDA,kDA8BC;AAWD,8CAeC;AA/GD,uCAAwC;AAGxC,2CAAsE;AAEtE,yDAAgG;AAIhG,MAAM,eAAe,GAAkC;IACrD,cAAc,EAAE,iFAAiF;IACjG,UAAU,EACR,kFAAkF;QAClF,2FAA2F;IAC7F,wBAAwB,EACtB,kFAAkF;QAClF,8GAA8G;IAChH,4BAA4B,EAC1B,0FAA0F;CAC7F,CAAA;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAC1B,WAAmB,EACnB,KAAY,EACZ,QAAuB,EACvB,YAAY,GAAG,KAAK;IAEpB,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;IACxD,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACrF,OAAO,IAAI,+BAAmB,CAC5B,sBAAsB,WAAW,KAAK,MAAM,KAAK,eAAe,CAAC,QAAQ,CAAC,EAAE,EAC5E,WAAW,EACX,EAAE,KAAK,EAAE,CACV,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,mBAAmB,CACvC,IAAY,EACZ,UAAmC,EACnC,IAAgB;IAEhB,KAAK,MAAM,WAAW,IAAI,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAA;QAC5E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,IAAA,mCAAgB,EAAC,KAAK,CAAC,CAAA;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAc,EAAE,QAAQ,CAAC,CAAA;YAClE,CAAC;YACD,IAAI,CAAC,IAAA,wCAAqB,EAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC/C,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;gBACrE,MAAM,IAAI,+BAAmB,CAC3B,iCAAiC,WAAW,KAAK,MAAM,EAAE,EACzD,WAAW,EACX,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,UAAU,CAAA;IAC9B,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9E,MAAM,IAAI,+BAAmB,CAC3B,6BAA6B,IAAI,GAAG,KAAK,kCAAkC,SAAS,EAAE,EACtF,SAAS,CACV,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,iBAAiB,CACrC,WAAmB,EACnB,UAAkB,EAClB,IAAgB;IAEhB,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,IAAA,wBAAa,EAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAA;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,IAAA,mCAAgB,EAAC,KAAK,EAAE,UAAU,CAAC,CAAA;QACpD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,KAAK,CAAA;QACb,CAAC;QACD,iFAAiF;QACjF,MAAM,mBAAmB,CAAC,WAAW,EAAE,KAAc,EAAE,QAAQ,EAAE,QAAQ,KAAK,cAAc,CAAC,CAAA;IAC/F,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Conditions Node uses for `import()` when it resolves package `exports`.
3
+ * Other runtimes use other conditions (for example `deno` or `bun`).
4
+ */
5
+ export declare const IMPORT_CONDITIONS: readonly string[];
6
+ /** The package.json fields that decide where a package is entered */
7
+ export interface PackageEntryFields {
8
+ main?: unknown;
9
+ exports?: unknown;
10
+ }
11
+ /**
12
+ * Find the file that `import('<package>')` loads, from a package.json
13
+ *
14
+ * Uses `exports["."]` when the package has `exports`, otherwise `main`, otherwise `index.js`,
15
+ * like Node does. Paths are relative to the package directory.
16
+ *
17
+ * @returns The relative path, or undefined if `exports` has no entry for these conditions
18
+ */
19
+ export declare function resolvePackageEntry(packageJson: PackageEntryFields, conditions?: readonly string[]): string | undefined;
20
+ //# sourceMappingURL=entry-point.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point.d.ts","sourceRoot":"","sources":["../../../src/entry-point.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAAiD,CAAA;AAEhG,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAwCD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,kBAAkB,EAC/B,UAAU,GAAE,SAAS,MAAM,EAAsB,GAChD,MAAM,GAAG,SAAS,CAoBpB"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IMPORT_CONDITIONS = void 0;
4
+ exports.resolvePackageEntry = resolvePackageEntry;
5
+ /**
6
+ * Conditions Node uses for `import()` when it resolves package `exports`.
7
+ * Other runtimes use other conditions (for example `deno` or `bun`).
8
+ */
9
+ exports.IMPORT_CONDITIONS = ['node', 'import', 'module-sync', 'default'];
10
+ /**
11
+ * Resolve a conditional `exports` target to a file path
12
+ *
13
+ * Follows the Node rules: the first key that matches a condition and leads somewhere wins.
14
+ * A `null` condition blocks the path, so the search stops there. In an array, a `null`
15
+ * result is skipped and the next item is tried.
16
+ */
17
+ function resolveTarget(target, conditions) {
18
+ if (target === null) {
19
+ return null;
20
+ }
21
+ if (typeof target === 'string') {
22
+ return target.startsWith('./') ? target : undefined;
23
+ }
24
+ if (Array.isArray(target)) {
25
+ for (const item of target) {
26
+ const resolved = resolveTarget(item, conditions);
27
+ if (typeof resolved === 'string') {
28
+ return resolved;
29
+ }
30
+ }
31
+ return undefined;
32
+ }
33
+ if (typeof target === 'object') {
34
+ for (const [condition, value] of Object.entries(target)) {
35
+ const resolved = conditions.includes(condition) ? resolveTarget(value, conditions) : undefined;
36
+ if (resolved !== undefined) {
37
+ return resolved;
38
+ }
39
+ }
40
+ }
41
+ return undefined;
42
+ }
43
+ /**
44
+ * Find the file that `import('<package>')` loads, from a package.json
45
+ *
46
+ * Uses `exports["."]` when the package has `exports`, otherwise `main`, otherwise `index.js`,
47
+ * like Node does. Paths are relative to the package directory.
48
+ *
49
+ * @returns The relative path, or undefined if `exports` has no entry for these conditions
50
+ */
51
+ function resolvePackageEntry(packageJson, conditions = exports.IMPORT_CONDITIONS) {
52
+ // Not destructured as `exports`: in the CommonJS build that would shadow the module's own exports
53
+ const { main, exports: exportsField } = packageJson;
54
+ if (exportsField === undefined || exportsField === null) {
55
+ return typeof main === 'string' ? main : 'index.js';
56
+ }
57
+ // `exports` is either a map of subpaths ("." and "./x") or the target of "." itself
58
+ const isSubpathMap = typeof exportsField === 'object' &&
59
+ !Array.isArray(exportsField) &&
60
+ Object.keys(exportsField).some((key) => key.startsWith('.'));
61
+ return (resolveTarget(isSubpathMap ? exportsField['.'] : exportsField, conditions) ?? undefined);
62
+ }
63
+ //# sourceMappingURL=entry-point.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point.js","sourceRoot":"","sources":["../../../src/entry-point.ts"],"names":[],"mappings":";;;AA0DA,kDAuBC;AAjFD;;;GAGG;AACU,QAAA,iBAAiB,GAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,CAAA;AAQhG;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,MAAe,EAAE,UAA6B;IACnE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IACrD,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,MAAmB,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;YAChD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,QAAQ,CAAA;YACjB,CAAC;QACH,CAAC;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,EAAE,CAAC;YACnF,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;YAC9F,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,OAAO,QAAQ,CAAA;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,mBAAmB,CACjC,WAA+B,EAC/B,aAAgC,yBAAiB;IAEjD,kGAAkG;IAClG,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,WAAW,CAAA;IAEnD,IAAI,YAAY,KAAK,SAAS,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QACxD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAA;IACrD,CAAC;IAED,oFAAoF;IACpF,MAAM,YAAY,GAChB,OAAO,YAAY,KAAK,QAAQ;QAChC,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAE9D,OAAO,CACL,aAAa,CACX,YAAY,CAAC,CAAC,CAAE,YAAwC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,EAC5E,UAAU,CACX,IAAI,SAAS,CACf,CAAA;AACH,CAAC"}
@@ -52,6 +52,29 @@ export declare class DriverNotFoundError extends Error {
52
52
  readonly packageName: string;
53
53
  constructor(message: string, packageName: string, options?: ErrorOptions);
54
54
  }
55
+ /**
56
+ * Error thrown when a driver package is installed but cannot be loaded because it is not built
57
+ *
58
+ * Drivers are loaded as built JavaScript. This covers a missing entry file (for example
59
+ * no `dist` directory) and TypeScript source that Node cannot run.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * import { loadDriver, DriverNotBuiltError } from '@ya-modbus/driver-loader'
64
+ *
65
+ * try {
66
+ * await loadDriver({}) // Auto-detect from current directory
67
+ * } catch (error) {
68
+ * if (error instanceof DriverNotBuiltError) {
69
+ * console.error(`Build ${error.packageName} first: npm run build`)
70
+ * }
71
+ * }
72
+ * ```
73
+ */
74
+ export declare class DriverNotBuiltError extends Error {
75
+ readonly packageName: string;
76
+ constructor(message: string, packageName: string, options?: ErrorOptions);
77
+ }
55
78
  /**
56
79
  * Error thrown when package.json is not found or invalid
57
80
  *
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,KAAK,CAAC,EAAE,MAAM;gBAD9B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,MAAM,YAAA;CAMjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,WAAW,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,WAAW,EAAE,MAAM,EACnC,OAAO,CAAC,EAAE,YAAY;CAMzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAK5B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAgB,SAAQ,KAAK;aAGtB,KAAK,CAAC,EAAE,MAAM;gBAD9B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,MAAM,YAAA;CAMjC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,WAAW,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,WAAW,EAAE,MAAM,EACnC,OAAO,CAAC,EAAE,YAAY;CAMzB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,WAAW,EAAE,MAAM;gBADnC,OAAO,EAAE,MAAM,EACC,WAAW,EAAE,MAAM,EACnC,OAAO,CAAC,EAAE,YAAY;CAMzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAK5B"}
@@ -6,7 +6,7 @@
6
6
  * compared to string-based error detection.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.PackageJsonError = exports.DriverNotFoundError = exports.ValidationError = void 0;
9
+ exports.PackageJsonError = exports.DriverNotBuiltError = exports.DriverNotFoundError = exports.ValidationError = void 0;
10
10
  /**
11
11
  * Error thrown when driver configuration validation fails
12
12
  *
@@ -65,6 +65,34 @@ class DriverNotFoundError extends Error {
65
65
  }
66
66
  }
67
67
  exports.DriverNotFoundError = DriverNotFoundError;
68
+ /**
69
+ * Error thrown when a driver package is installed but cannot be loaded because it is not built
70
+ *
71
+ * Drivers are loaded as built JavaScript. This covers a missing entry file (for example
72
+ * no `dist` directory) and TypeScript source that Node cannot run.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * import { loadDriver, DriverNotBuiltError } from '@ya-modbus/driver-loader'
77
+ *
78
+ * try {
79
+ * await loadDriver({}) // Auto-detect from current directory
80
+ * } catch (error) {
81
+ * if (error instanceof DriverNotBuiltError) {
82
+ * console.error(`Build ${error.packageName} first: npm run build`)
83
+ * }
84
+ * }
85
+ * ```
86
+ */
87
+ class DriverNotBuiltError extends Error {
88
+ constructor(message, packageName, options) {
89
+ super(message, options);
90
+ this.packageName = packageName;
91
+ this.name = 'DriverNotBuiltError';
92
+ Object.setPrototypeOf(this, DriverNotBuiltError.prototype);
93
+ }
94
+ }
95
+ exports.DriverNotBuiltError = DriverNotBuiltError;
68
96
  /**
69
97
  * Error thrown when package.json is not found or invalid
70
98
  *
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,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;AATD,0CASC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAC5C,YACE,OAAe,EACC,WAAmB,EACnC,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAHP,gBAAW,GAAX,WAAW,CAAQ;QAInC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAC5D,CAAC;CACF;AAVD,kDAUC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,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;AAND,4CAMC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,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;AATD,0CASC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAC5C,YACE,OAAe,EACC,WAAmB,EACnC,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAHP,gBAAW,GAAX,WAAW,CAAQ;QAInC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAC5D,CAAC;CACF;AAVD,kDAUC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAa,mBAAoB,SAAQ,KAAK;IAC5C,YACE,OAAe,EACC,WAAmB,EACnC,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAHP,gBAAW,GAAX,WAAW,CAAQ;QAInC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;QACjC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAA;IAC5D,CAAC;CACF;AAVD,kDAUC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAa,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;AAND,4CAMC"}
@@ -2,7 +2,7 @@ export { loadDriver, clearDriverCache, getDriverCacheStats } from './loader.js';
2
2
  export type { LoadedDriver, LoadDriverOptions, SystemDependencies, DriverCacheStats, Logger, } from './loader.js';
3
3
  export { validateDefaultConfig, validateSupportedConfig, validateDevices, crossValidateConfigs, } from './config-validator.js';
4
4
  export { DRIVER_PACKAGE_NAME_RULE, assertValidDriverPackageName, isValidDriverPackageName, } from './driver-package-name.js';
5
- export { ValidationError, DriverNotFoundError, PackageJsonError } from './errors.js';
5
+ export { ValidationError, DriverNotFoundError, DriverNotBuiltError, PackageJsonError, } from './errors.js';
6
6
  export { getCallerPackageInfo } from './package-info.js';
7
7
  export type { PackageInfo } from './package-info.js';
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
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,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,GACzB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCallerPackageInfo = exports.PackageJsonError = exports.DriverNotFoundError = exports.ValidationError = exports.isValidDriverPackageName = exports.assertValidDriverPackageName = exports.DRIVER_PACKAGE_NAME_RULE = exports.crossValidateConfigs = exports.validateDevices = exports.validateSupportedConfig = exports.validateDefaultConfig = exports.getDriverCacheStats = exports.clearDriverCache = exports.loadDriver = void 0;
3
+ exports.getCallerPackageInfo = exports.PackageJsonError = exports.DriverNotBuiltError = exports.DriverNotFoundError = exports.ValidationError = exports.isValidDriverPackageName = exports.assertValidDriverPackageName = exports.DRIVER_PACKAGE_NAME_RULE = exports.crossValidateConfigs = exports.validateDevices = exports.validateSupportedConfig = exports.validateDefaultConfig = exports.getDriverCacheStats = exports.clearDriverCache = exports.loadDriver = void 0;
4
4
  var loader_js_1 = require("./loader.js");
5
5
  Object.defineProperty(exports, "loadDriver", { enumerable: true, get: function () { return loader_js_1.loadDriver; } });
6
6
  Object.defineProperty(exports, "clearDriverCache", { enumerable: true, get: function () { return loader_js_1.clearDriverCache; } });
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "isValidDriverPackageName", { enumerable: true, g
17
17
  var errors_js_1 = require("./errors.js");
18
18
  Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_js_1.ValidationError; } });
19
19
  Object.defineProperty(exports, "DriverNotFoundError", { enumerable: true, get: function () { return errors_js_1.DriverNotFoundError; } });
20
+ Object.defineProperty(exports, "DriverNotBuiltError", { enumerable: true, get: function () { return errors_js_1.DriverNotBuiltError; } });
20
21
  Object.defineProperty(exports, "PackageJsonError", { enumerable: true, get: function () { return errors_js_1.PackageJsonError; } });
21
22
  var package_info_js_1 = require("./package-info.js");
22
23
  Object.defineProperty(exports, "getCallerPackageInfo", { enumerable: true, get: function () { return package_info_js_1.getCallerPackageInfo; } });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA+E;AAAtE,uGAAA,UAAU,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,gHAAA,mBAAmB,OAAA;AAQ1D,6DAK8B;AAJ5B,4HAAA,qBAAqB,OAAA;AACrB,8HAAA,uBAAuB,OAAA;AACvB,sHAAA,eAAe,OAAA;AACf,2HAAA,oBAAoB,OAAA;AAEtB,mEAIiC;AAH/B,kIAAA,wBAAwB,OAAA;AACxB,sIAAA,4BAA4B,OAAA;AAC5B,kIAAA,wBAAwB,OAAA;AAE1B,yCAAoF;AAA3E,4GAAA,eAAe,OAAA;AAAE,gHAAA,mBAAmB,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAC/D,qDAAwD;AAA/C,uHAAA,oBAAoB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA+E;AAAtE,uGAAA,UAAU,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,gHAAA,mBAAmB,OAAA;AAQ1D,6DAK8B;AAJ5B,4HAAA,qBAAqB,OAAA;AACrB,8HAAA,uBAAuB,OAAA;AACvB,sHAAA,eAAe,OAAA;AACf,2HAAA,oBAAoB,OAAA;AAEtB,mEAIiC;AAH/B,kIAAA,wBAAwB,OAAA;AACxB,sIAAA,4BAA4B,OAAA;AAC5B,kIAAA,wBAAwB,OAAA;AAE1B,yCAKoB;AAJlB,4GAAA,eAAe,OAAA;AACf,gHAAA,mBAAmB,OAAA;AACnB,gHAAA,mBAAmB,OAAA;AACnB,6GAAA,gBAAgB,OAAA;AAElB,qDAAwD;AAA/C,uHAAA,oBAAoB,OAAA"}
@@ -76,7 +76,8 @@ export interface LoadDriverOptions {
76
76
  */
77
77
  export interface SystemDependencies {
78
78
  readFile: (path: string, encoding: 'utf-8') => Promise<string>;
79
- importModule: (modulePath: string) => Promise<unknown>;
79
+ /** Import a module by package name, or by `file:` URL for the entry file of a local package */
80
+ importModule: (specifier: string) => Promise<unknown>;
80
81
  getCwd: () => string;
81
82
  }
82
83
  /**
@@ -107,7 +108,10 @@ export declare function getDriverCacheStats(): DriverCacheStats;
107
108
  * 1. Explicit package: `loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })`
108
109
  * 2. Auto-detect from cwd: `loadDriver({})` - reads package.json from current directory
109
110
  *
110
- * Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords.
111
+ * Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords and loads
112
+ * the entry file that `import` of the package resolves to (`exports["."]`, else `main`,
113
+ * else `index.js`). The driver must be built: the entry file is JavaScript, or TypeScript
114
+ * that Node can run itself.
111
115
  *
112
116
  * @example
113
117
  * // Auto-detect from current directory
@@ -1 +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;AAahC;;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;;;;;;OAMG;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,CAmHvB"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,eAAe,EAChB,MAAM,yBAAyB,CAAA;AAmBhC;;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;;;;;;OAMG;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,+FAA+F;IAC/F,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IACrD,MAAM,EAAE,MAAM,MAAM,CAAA;CACrB;AA6BD;;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;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,iBAAsB,EAC/B,IAAI,GAAE,kBAAgC,GACrC,OAAO,CAAC,YAAY,CAAC,CA4GvB"}
@@ -37,11 +37,23 @@ exports.clearDriverCache = clearDriverCache;
37
37
  exports.getDriverCacheStats = getDriverCacheStats;
38
38
  exports.loadDriver = loadDriver;
39
39
  const promises_1 = require("fs/promises");
40
- const path_1 = require("path");
41
40
  const config_validator_js_1 = require("./config-validator.js");
42
41
  const driver_import_js_1 = require("./driver-import.js");
43
42
  const driver_name_js_1 = require("./driver-name.js");
44
43
  const errors_js_1 = require("./errors.js");
44
+ const local_package_js_1 = require("./local-package.js");
45
+ /**
46
+ * Native `import()`, in the CommonJS build as well
47
+ *
48
+ * The CommonJS build compiles `import()` to `require()`, which cannot load a `file:` URL.
49
+ * Going through `Function` keeps the native `import()`, which also loads ES modules.
50
+ */
51
+ /* istanbul ignore next */
52
+ const nativeImport = (specifier) => {
53
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval -- keeps `import()` out of the CommonJS transform
54
+ const importFn = new Function('specifier', 'return import(specifier)');
55
+ return importFn(specifier);
56
+ };
45
57
  /**
46
58
  * Default system dependencies using Node.js built-ins
47
59
  */
@@ -50,7 +62,7 @@ const defaultDeps = {
50
62
  /* istanbul ignore next */
51
63
  readFile: (path, encoding) => (0, promises_1.readFile)(path, encoding),
52
64
  /* istanbul ignore next */
53
- importModule: (modulePath) => Promise.resolve(`${modulePath}`).then(s => __importStar(require(s))),
65
+ importModule: (specifier) => specifier.startsWith('file:') ? nativeImport(specifier) : Promise.resolve(`${specifier}`).then(s => __importStar(require(s))),
54
66
  /* istanbul ignore next */
55
67
  getCwd: () => process.cwd(),
56
68
  };
@@ -85,61 +97,6 @@ function getDriverCacheStats() {
85
97
  size: driverCache.size,
86
98
  };
87
99
  }
88
- /**
89
- * Auto-detect local driver package from package.json
90
- *
91
- * @param deps - System dependencies
92
- * @returns Package name if valid driver package
93
- * @throws Error if not a valid driver package
94
- */
95
- async function detectLocalPackage(deps) {
96
- try {
97
- const packageJsonPath = (0, path_1.join)(deps.getCwd(), 'package.json');
98
- const packageJsonContent = await deps.readFile(packageJsonPath, 'utf-8');
99
- const packageJson = JSON.parse(packageJsonContent);
100
- const keywords = packageJson.keywords ?? [];
101
- if (!keywords.includes('ya-modbus-driver')) {
102
- throw new errors_js_1.PackageJsonError('Current package is not a ya-modbus driver. ' +
103
- 'Add "ya-modbus-driver" to keywords in package.json');
104
- }
105
- const name = packageJson.name;
106
- if (!name) {
107
- throw new errors_js_1.PackageJsonError('package.json must have a "name" field');
108
- }
109
- return name;
110
- }
111
- catch (error) {
112
- if (error.code === 'ENOENT') {
113
- throw new errors_js_1.PackageJsonError('package.json not found in current directory. ' +
114
- 'Run this command from a driver package directory or specify --driver');
115
- }
116
- if (error instanceof SyntaxError) {
117
- throw new errors_js_1.PackageJsonError('Failed to parse package.json: invalid JSON');
118
- }
119
- throw error;
120
- }
121
- }
122
- /**
123
- * Try to import a module with multiple path attempts
124
- *
125
- * @param paths - Array of module paths to try
126
- * @param deps - System dependencies
127
- * @returns Imported module
128
- * @throws Error if all paths fail
129
- */
130
- async function tryImport(paths, deps) {
131
- const errors = [];
132
- for (const path of paths) {
133
- try {
134
- return await deps.importModule(path);
135
- }
136
- catch (error) {
137
- errors.push(error);
138
- }
139
- }
140
- const lastError = errors[errors.length - 1];
141
- throw new Error(`Failed to import module from any path. Tried: ${paths.join(', ')}\nLast error: ${lastError?.message}`, { cause: lastError });
142
- }
143
100
  /**
144
101
  * Load a driver package dynamically
145
102
  *
@@ -147,7 +104,10 @@ async function tryImport(paths, deps) {
147
104
  * 1. Explicit package: `loadDriver({ driverPackage: 'ya-modbus-driver-xymd1' })`
148
105
  * 2. Auto-detect from cwd: `loadDriver({})` - reads package.json from current directory
149
106
  *
150
- * Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords.
107
+ * Auto-detection checks for `ya-modbus-driver` keyword in package.json keywords and loads
108
+ * the entry file that `import` of the package resolves to (`exports["."]`, else `main`,
109
+ * else `index.js`). The driver must be built: the entry file is JavaScript, or TypeScript
110
+ * that Node can run itself.
151
111
  *
152
112
  * @example
153
113
  * // Auto-detect from current directory
@@ -181,21 +141,15 @@ async function loadDriver(options = {}, deps = defaultDeps) {
181
141
  driverModule = imported.driverModule;
182
142
  }
183
143
  else {
184
- packageName = await detectLocalPackage(deps);
144
+ const localPackage = await (0, local_package_js_1.detectLocalPackage)(deps);
145
+ packageName = localPackage.name;
185
146
  const cached = driverCache.get(packageName);
186
147
  if (cached) {
187
148
  cacheStats.hits++;
188
149
  return cached;
189
150
  }
190
151
  cacheStats.misses++;
191
- const cwd = deps.getCwd();
192
- const importPaths = [
193
- (0, path_1.join)(cwd, 'src', 'index.js'),
194
- (0, path_1.join)(cwd, 'src', 'index.ts'),
195
- (0, path_1.join)(cwd, 'dist', 'index.js'),
196
- packageName,
197
- ];
198
- driverModule = await tryImport(importPaths, deps);
152
+ driverModule = await (0, driver_import_js_1.importLocalDriver)(packageName, localPackage.entryPoint, deps);
199
153
  }
200
154
  if (!driverModule || typeof driverModule !== 'object') {
201
155
  throw new errors_js_1.ValidationError('Driver package must export a createDriver function', 'createDriver');
@@ -231,6 +185,7 @@ async function loadDriver(options = {}, deps = defaultDeps) {
231
185
  catch (error) {
232
186
  if (error instanceof errors_js_1.ValidationError ||
233
187
  error instanceof errors_js_1.DriverNotFoundError ||
188
+ error instanceof errors_js_1.DriverNotBuiltError ||
234
189
  error instanceof errors_js_1.PackageJsonError) {
235
190
  throw error;
236
191
  }