locter 4.0.0-beta.0 → 4.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.MD CHANGED
@@ -35,7 +35,7 @@
35
35
  ## Features
36
36
 
37
37
  - 🔍 **Locate** — `locate`, `locateMany`, `locateUp`: fast-glob discovery returning structured `LocatorInfo` records.
38
- - 📖 **Read** — one `read()` for JSON, YAML, `.conf`, and JS/TS modules in any runtime (powered by `jiti`); every result normalized to a module record.
38
+ - 📖 **Read** — one `read()` for JSON, YAML, `.conf`, and JS/TS modules in any runtime (powered by `jiti`); `readAsModule()` for the uniform module-record shape.
39
39
  - ✍️ **Write** — `write()` values back without pulling serializers into your app: comment-preserving YAML, indent-preserving JSON, rc9-style `.conf`.
40
40
  - 🔁 **Sync twins** — every operation ships as `fn` / `fnSync`, derived from one shared implementation.
41
41
  - 🧩 **Extensible** — register custom formats with independent reader/writer slots; override built-ins per extension.
@@ -175,55 +175,55 @@ If both flags are set, `onlyDirectories: true` takes precedence over `onlyFiles`
175
175
 
176
176
  ### Reader
177
177
 
178
- The `read` method loads a file/module in an asynchronous fashion.
179
- Either a string or the output of the locate/locateSync method can be passed as argument.
178
+ Two verbs, two shapes:
179
+
180
+ - **`read`** — *raw*: the plain parsed value for data formats (JSON/YAML/Conf
181
+ and custom readers) — mutable and round-trip-symmetric with `write`. For
182
+ modules it returns the normalized module record: a module *is* a record,
183
+ and the normalization only irons out the CJS/ESM interop divergence so
184
+ `read` and `readSync` agree on one shape.
185
+ - **`readAsModule`** — everything as a *module record*: the uniform, frozen
186
+ record shape regardless of format — for export inspection, interop, and
187
+ uniform handling of mixed-extension config.
188
+
189
+ Either a string or the output of the locate/locateSync method can be passed
190
+ as argument; both verbs have `*Sync` twins.
180
191
 
181
192
  ```typescript
182
- import { read, locate } from 'locter';
193
+ import { locate, read, readSync } from 'locter';
183
194
 
184
195
  (async () => {
185
- const file = await locate(
186
- 'files/example.{js,.ts}'
187
- );
196
+ const config = await read('config.yml');
197
+ // → the plain parsed value: { port: 3000, ... } — mutable,
198
+ // round-trip-symmetric with write()
188
199
 
189
- let content = await read(file);
190
- console.log(content);
191
- // ...
200
+ const settings = await read('trapi.config.ts');
201
+ // → the module as a normalized record; unwrap explicitly:
202
+ // settings.default
192
203
 
193
- content = await read('...');
194
- console.log(content);
195
- // ...
204
+ const file = await locate('files/example.{js,.ts}');
205
+ const content = readSync(file); // sync twin
196
206
  })
197
207
  ```
198
208
 
199
- There is also a synchronous method called `readSync`.
200
-
201
- ```typescript
202
- import { readSync, locateSync } from 'locter';
203
-
204
- const file = locateSync(
205
- 'files/example.{js,.ts}'
206
- );
207
-
208
- const content = readSync(file);
209
- ```
210
-
211
209
  Bare module specifiers (no file extension) are routed to the module reader, so
212
210
  `read('yaml')` behaves like `import('yaml')` — note that reading a module
213
211
  **executes** it.
214
212
 
215
- **Module records**
213
+ **Module records — `readAsModule`**
216
214
 
217
- Every `read` / `readSync` result is a **module record** — a frozen,
218
- null-prototype object shaped like an ES module namespace: `default` always
219
- holds the loaded value, and when that value is an object, its top-level keys
220
- are re-exposed as named exports.
215
+ Every `readAsModule` / `readAsModuleSync` result is a **module record** — a
216
+ frozen, null-prototype object shaped like an ES module namespace: `default`
217
+ always holds the loaded value, and when that value is an object, its
218
+ top-level keys are re-exposed as named exports. For modules, `read` and
219
+ `readAsModule` agree; for data formats, `read` returns what
220
+ `readAsModule(...).default` holds.
221
221
 
222
222
  ```typescript
223
- import { read } from 'locter';
223
+ import { readAsModule } from 'locter';
224
224
 
225
225
  (async () => {
226
- const pkg = await read('package.json');
226
+ const pkg = await readAsModule('package.json');
227
227
 
228
228
  console.log(pkg.default); // the full parsed JSON value
229
229
  console.log(pkg.version); // top-level keys are named exports
@@ -233,21 +233,23 @@ import { read } from 'locter';
233
233
  For JavaScript/TypeScript files the module's own namespace passes through
234
234
  unchanged; the output of every other reader (built-in JSON/YAML/Conf and
235
235
  user-registered ones) is always wrapped — even if the parsed data happens to
236
- contain an `__esModule` key. The record is read-only: to mutate the loaded
237
- data, work with `.default`.
236
+ contain an `__esModule` key (`read` of such data likewise returns it
237
+ untouched — a literal `__esModule` key never turns data into a module).
238
+ The record is read-only: to mutate the loaded data, work with `.default`
239
+ (for data records that is the same object `read` returns).
238
240
 
239
241
  Records additionally carry a private, non-forgeable brand: `isModuleRecord`
240
- tells records produced by `read()` apart from arbitrary data, and
242
+ tells records produced by `readAsModule()` apart from arbitrary data, and
241
243
  [`write`](#writer) uses the brand to unwrap `.default` automatically on
242
244
  write-back.
243
245
 
244
246
  To pick an export by predicate, the `getModuleExport` helper is available:
245
247
 
246
248
  ```typescript
247
- import { getModuleExport, read } from 'locter';
249
+ import { getModuleExport, readAsModule } from 'locter';
248
250
 
249
251
  (async () => {
250
- const record = await read('files/example.ts');
252
+ const record = await readAsModule('files/example.ts');
251
253
 
252
254
  const found = getModuleExport(record, (key) => key === 'myExport');
253
255
  // → { key: 'myExport', value: ... }, or undefined if no key matches
@@ -286,15 +288,19 @@ The `write` method serializes a value to a file, dispatched by extension like
286
288
  application:
287
289
 
288
290
  ```typescript
289
- import { read, write } from 'locter';
291
+ import { read, readAsModule, write } from 'locter';
290
292
 
291
293
  (async () => {
294
+ // read → modify → write, fully symmetric
292
295
  const config = await read('config.yml');
293
- config.default.port = 8080;
296
+ config.port = 8080;
297
+ await write('config.yml', config);
294
298
 
295
- // records produced by read() are unwrapped automatically —
299
+ // records produced by readAsModule() are unwrapped automatically —
296
300
  // the file receives the plain value, not the record wrapper
297
- await write('config.yml', config);
301
+ const record = await readAsModule('config.yml');
302
+ record.default.port = 8080;
303
+ await write('config.yml', record);
298
304
 
299
305
  // plain values work just as well
300
306
  await write('generated/settings.json', { port: 8080 });
@@ -307,7 +313,7 @@ Write semantics:
307
313
 
308
314
  - **Missing parent directories are created** (`mkdir -p`).
309
315
  - Output always ends with a single trailing newline.
310
- - Values that are records produced by `read()` (detected via the private
316
+ - Values that are records produced by `readAsModule()` (detected via the private
311
317
  brand — an `__esModule` key in plain data does **not** count) are unwrapped
312
318
  to their `.default` value before serialization.
313
319
  - Module formats (`.js`, `.ts`, …) are **read-only**: `write('config.ts', …)`
@@ -576,7 +582,7 @@ The list below is exhaustive — no other public APIs changed.
576
582
 
577
583
  | 3.x | 4.x |
578
584
  |--------------------------------------|--------------------------------------------|
579
- | `load` / `loadSync` | `read` / `readSync` |
585
+ | `load` / `loadSync` | `read` / `readSync` (raw: plain data values / module records) or `readAsModule` / `readAsModuleSync` (everything as a module record) |
580
586
  | `registerLoader` / `unregisterLoader`| `registerFormat` / `unregisterFormat` |
581
587
  | `LoaderManager` | `FormatRegistry` |
582
588
  | `useLoader` | `useFormatRegistry` |
@@ -612,17 +618,20 @@ The list below is exhaustive — no other public APIs changed.
612
618
  + registry.findReader('file.json'); // IReader | undefined
613
619
  + registry.builtInReader('module'); // statically typed as ModuleReader
614
620
 
615
- // 4. Every read() / readSync() result is now a module record (see
616
- // "Module records" above). Module files already resolved this way —
617
- // json/yaml/conf and custom readers used to return the bare parsed
618
- // value.
619
- const pkg = await read('package.json');
620
- pkg.version; // top-level keys still work
621
- - pkg.default; // undefined
621
+ // 4. Two verbs replace 3.x load(): read() is RAW (the plain parsed
622
+ // value for data — 3.x data loads map to read() nearly 1:1 — and
623
+ // the normalized record for modules), while readAsModule() returns
624
+ // a frozen, null-prototype module record for EVERY format (see
625
+ // "Module records" above).
626
+ const value = await read('package.json');
627
+ value.version; // the plain parsed JSON
628
+
629
+ const pkg = await readAsModule('package.json');
630
+ pkg.version; // top-level keys as named exports
622
631
  + pkg.default; // the full parsed value
623
632
  + // The record is frozen and null-prototype: code that mutates the
624
633
  + // result, relies on Object.prototype, or enumerates/serializes it
625
- + // (now includes `default`) must use pkg.default instead.
634
+ + // must use pkg.default (or read()) instead.
626
635
 
627
636
  // 5. ModuleReader.read() / readSync() return the raw module value;
628
637
  // normalization happens exactly once, at the registry boundary. Only
@@ -635,7 +644,7 @@ The list below is exhaustive — no other public APIs changed.
635
644
  **Removed from the public surface** (internal plumbing that leaked through the old `export *` barrels; the package now exports a curated, snapshot-tested list):
636
645
 
637
646
  - Locator internals: `buildLocatorPatterns`, `buildLocatorOptions`, `pathToLocatorInfo`, `buildFilePathWithoutExtension` (deleted — it had no callers). `buildFilePath` and `isLocatorInfo` stay public.
638
- - Record internals: `isESModule`, `toModuleRecord`, `createModuleRecord`. Use `read()` (which normalizes) and the public `getModuleExport` / `isModuleRecord`.
647
+ - Record internals: `isESModule`, `toModuleRecord`, `createModuleRecord`. Use `readAsModule()` (which normalizes) / `read()` (raw) and the public `getModuleExport` / `isModuleRecord`.
639
648
  - Generic helpers: `isObject`, `isSafeObjectKey`, `hasOwnProperty`, `hasStringProperty`, `toArray`, `isFilePath`, `getFileNameExtension`, `removeFileNameExtension`, `isTypeScriptError`. The runtime detection helpers (`isJestRuntimeEnvironment`, `isVitestRuntimeEnvironment`, `isTsNodeRuntimeEnvironment`, `isTsxRuntimeEnvironment`) stay public.
640
649
 
641
650
  **Locator option precedence** — `{ onlyFiles: true, onlyDirectories: true }` used to resolve to *neither* restriction (everything matched); `onlyDirectories: true` now wins. `{ onlyFiles: false }` used to mean directories-only; it now means "no restriction" (files and directories).
package/dist/index.d.mts CHANGED
@@ -440,23 +440,44 @@ declare class FormatRegistry {
440
440
  * configured via setModuleReader / configure).
441
441
  */
442
442
  reset(): void;
443
+ /**
444
+ * Read a file/module RAW: the plain parsed value for data formats
445
+ * (mutable, round-trip-symmetric with write); for modules the
446
+ * normalized module record — a module IS a record, and the
447
+ * normalization only irons out the CJS/ESM interop divergence so
448
+ * both twin variants agree on one shape.
449
+ */
443
450
  read(input: LocatorInfo | string): Promise<any>;
444
451
  readSync(input: LocatorInfo | string): any;
445
452
  /**
446
- * Shared body of read/readSync: dispatch, read, normalize, wrap.
453
+ * Read a file/module and present the result as a normalized module
454
+ * record — the uniform, frozen shape regardless of format:
455
+ * `.default` always holds the loaded value, top-level keys are
456
+ * re-exposed as named exports.
447
457
  */
458
+ readAsModule(input: LocatorInfo | string): Promise<any>;
459
+ readAsModuleSync(input: LocatorInfo | string): any;
448
460
  protected readBody(input: LocatorInfo | string): TwinBody<any>;
461
+ protected readAsModuleBody(input: LocatorInfo | string): TwinBody<any>;
462
+ /**
463
+ * Shared dispatch + execution of both read bodies: resolve the
464
+ * reader, run it, wrap errors. Normalization is the caller's call.
465
+ */
466
+ protected executeBody(input: LocatorInfo | string): TwinBody<{
467
+ output: unknown;
468
+ reader: IReader;
469
+ }>;
449
470
  write(input: LocatorInfo | string, value: unknown): Promise<void>;
450
471
  writeSync(input: LocatorInfo | string, value: unknown): void;
451
472
  /**
452
473
  * Shared body of write/writeSync: dispatch, unwrap records, write, wrap.
453
- * The inverse boundary of readBody: a record produced by read() (brand
454
- * detected) is unwrapped to its `.default` value; anything else is
455
- * written as-is.
474
+ * The inverse boundary of readAsModuleBody: a record produced by
475
+ * readAsModule() (brand detected) is unwrapped to its `.default` value;
476
+ * anything else is written as-is.
456
477
  */
457
478
  protected writeBody(input: LocatorInfo | string, value: unknown): TwinBody<void>;
458
479
  /**
459
- * The single normalization boundary: every read result becomes a module
480
+ * The single normalization boundary: every readAsModule result becomes a module
460
481
  * record (`.default` is always the loaded value, top-level keys stay
461
482
  * accessible as named exports). Provenance decides how: module-reader
462
483
  * output may legitimately already be a record (`__esModule` is meaningful
@@ -505,8 +526,22 @@ declare function registerFormat(rule: Rule): FormatRegistration;
505
526
  * (as returned by registerFormat). Built-in ids cannot be unregistered.
506
527
  */
507
528
  declare function unregisterFormat(id: string): boolean;
529
+ /**
530
+ * Read a file/module RAW: the plain parsed value for data formats
531
+ * (json/yaml/conf and custom readers — mutable, round-trip-symmetric
532
+ * with write); for modules the normalized module record (a module IS a
533
+ * record; normalization only irons out CJS/ESM interop divergence).
534
+ */
508
535
  declare function read(input: LocatorInfo | string): Promise<any>;
509
536
  declare function readSync(input: LocatorInfo | string): any;
537
+ /**
538
+ * Read a file/module and present the result as a normalized module
539
+ * record — the uniform, frozen shape regardless of format: `.default`
540
+ * always holds the loaded value, top-level keys are re-exposed as
541
+ * named exports.
542
+ */
543
+ declare function readAsModule(input: LocatorInfo | string): Promise<any>;
544
+ declare function readAsModuleSync(input: LocatorInfo | string): any;
510
545
  declare function write(input: LocatorInfo | string, value: unknown): Promise<void>;
511
546
  declare function writeSync(input: LocatorInfo | string, value: unknown): void;
512
547
  /**
@@ -559,5 +594,5 @@ declare function isVitestRuntimeEnvironment(): boolean;
559
594
  declare function isTsNodeRuntimeEnvironment(): boolean;
560
595
  declare function isTsxRuntimeEnvironment(): boolean;
561
596
  //#endregion
562
- export { ConfReader, ConfWriter, type FormatPreset, type FormatRegistration, FormatRegistry, type FormatRegistryOptions, type IReader, type IWriter, JSONReader, JSONWriter, type JSONWriterOptions, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LOCTER_WRITE_ERROR_MARKER, type LocatorInfo, type LocatorOptions, type LocatorOptionsInput, type LocatorUpOptionsInput, LocterError, type LocterErrorInput, type LocterErrorOptions, LocterLoadError, LocterNotFoundError, LocterUnknownExtensionError, LocterWriteError, MODULE_FILE_EXTENSIONS, type ModuleExport, type ModuleExportFilterFn, type ModuleLoadFn, type ModuleLoadOptions, type ModuleLoadSyncFn, ModuleReader, type ModuleReaderOptions, type ReadPackageFieldOptions, type ReaderFactory, type Rule, TextFileReader, TextFileWriter, type WritePackageFieldOptions, type WriterFactory, YAMLReader, YAMLWriter, type YAMLWriterOptions, buildFilePath, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readPackageField, readPackageFieldSync, readSync, registerFormat, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
597
+ export { ConfReader, ConfWriter, type FormatPreset, type FormatRegistration, FormatRegistry, type FormatRegistryOptions, type IReader, type IWriter, JSONReader, JSONWriter, type JSONWriterOptions, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LOCTER_WRITE_ERROR_MARKER, type LocatorInfo, type LocatorOptions, type LocatorOptionsInput, type LocatorUpOptionsInput, LocterError, type LocterErrorInput, type LocterErrorOptions, LocterLoadError, LocterNotFoundError, LocterUnknownExtensionError, LocterWriteError, MODULE_FILE_EXTENSIONS, type ModuleExport, type ModuleExportFilterFn, type ModuleLoadFn, type ModuleLoadOptions, type ModuleLoadSyncFn, ModuleReader, type ModuleReaderOptions, type ReadPackageFieldOptions, type ReaderFactory, type Rule, TextFileReader, TextFileWriter, type WritePackageFieldOptions, type WriterFactory, YAMLReader, YAMLWriter, type YAMLWriterOptions, buildFilePath, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
563
598
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -876,6 +876,13 @@ var FormatRegistry = class {
876
876
  this.builtInWriterCache.clear();
877
877
  this.ruleCounter = 0;
878
878
  }
879
+ /**
880
+ * Read a file/module RAW: the plain parsed value for data formats
881
+ * (mutable, round-trip-symmetric with write); for modules the
882
+ * normalized module record — a module IS a record, and the
883
+ * normalization only irons out the CJS/ESM interop divergence so
884
+ * both twin variants agree on one shape.
885
+ */
879
886
  async read(input) {
880
887
  return runTwinAsync(this.readBody(input));
881
888
  }
@@ -883,15 +890,39 @@ var FormatRegistry = class {
883
890
  return runTwinSync(this.readBody(input));
884
891
  }
885
892
  /**
886
- * Shared body of read/readSync: dispatch, read, normalize, wrap.
893
+ * Read a file/module and present the result as a normalized module
894
+ * record — the uniform, frozen shape regardless of format:
895
+ * `.default` always holds the loaded value, top-level keys are
896
+ * re-exposed as named exports.
887
897
  */
898
+ async readAsModule(input) {
899
+ return runTwinAsync(this.readAsModuleBody(input));
900
+ }
901
+ readAsModuleSync(input) {
902
+ return runTwinSync(this.readAsModuleBody(input));
903
+ }
888
904
  *readBody(input) {
905
+ const { output, reader } = yield* this.executeBody(input);
906
+ if (reader instanceof ModuleReader) return toModuleRecord(output);
907
+ return output;
908
+ }
909
+ *readAsModuleBody(input) {
910
+ const { output, reader } = yield* this.executeBody(input);
911
+ return this.toRecord(output, reader);
912
+ }
913
+ /**
914
+ * Shared dispatch + execution of both read bodies: resolve the
915
+ * reader, run it, wrap errors. Normalization is the caller's call.
916
+ */
917
+ *executeBody(input) {
889
918
  const filePath = buildFilePath(input);
890
919
  const reader = this.findReader(filePath);
891
920
  if (!reader) throw this.unknownExtensionError(filePath);
892
921
  try {
893
- const output = yield* op(() => reader.read(filePath), () => reader.readSync(filePath));
894
- return this.toRecord(output, reader);
922
+ return {
923
+ output: yield* op(() => reader.read(filePath), () => reader.readSync(filePath)),
924
+ reader
925
+ };
895
926
  } catch (e) {
896
927
  throw wrapLoaderError(e, filePath);
897
928
  }
@@ -904,9 +935,9 @@ var FormatRegistry = class {
904
935
  }
905
936
  /**
906
937
  * Shared body of write/writeSync: dispatch, unwrap records, write, wrap.
907
- * The inverse boundary of readBody: a record produced by read() (brand
908
- * detected) is unwrapped to its `.default` value; anything else is
909
- * written as-is.
938
+ * The inverse boundary of readAsModuleBody: a record produced by
939
+ * readAsModule() (brand detected) is unwrapped to its `.default` value;
940
+ * anything else is written as-is.
910
941
  */
911
942
  *writeBody(input, value) {
912
943
  const filePath = buildFilePath(input);
@@ -930,7 +961,7 @@ var FormatRegistry = class {
930
961
  }
931
962
  }
932
963
  /**
933
- * The single normalization boundary: every read result becomes a module
964
+ * The single normalization boundary: every readAsModule result becomes a module
934
965
  * record (`.default` is always the loaded value, top-level keys stay
935
966
  * accessible as named exports). Provenance decides how: module-reader
936
967
  * output may legitimately already be a record (`__esModule` is meaningful
@@ -1054,12 +1085,30 @@ function registerFormat(rule) {
1054
1085
  function unregisterFormat(id) {
1055
1086
  return useFormatRegistry().unregister(id);
1056
1087
  }
1088
+ /**
1089
+ * Read a file/module RAW: the plain parsed value for data formats
1090
+ * (json/yaml/conf and custom readers — mutable, round-trip-symmetric
1091
+ * with write); for modules the normalized module record (a module IS a
1092
+ * record; normalization only irons out CJS/ESM interop divergence).
1093
+ */
1057
1094
  async function read(input) {
1058
1095
  return useFormatRegistry().read(input);
1059
1096
  }
1060
1097
  function readSync(input) {
1061
1098
  return useFormatRegistry().readSync(input);
1062
1099
  }
1100
+ /**
1101
+ * Read a file/module and present the result as a normalized module
1102
+ * record — the uniform, frozen shape regardless of format: `.default`
1103
+ * always holds the loaded value, top-level keys are re-exposed as
1104
+ * named exports.
1105
+ */
1106
+ async function readAsModule(input) {
1107
+ return useFormatRegistry().readAsModule(input);
1108
+ }
1109
+ function readAsModuleSync(input) {
1110
+ return useFormatRegistry().readAsModuleSync(input);
1111
+ }
1063
1112
  async function write(input, value) {
1064
1113
  return useFormatRegistry().write(input, value);
1065
1114
  }
@@ -1159,6 +1208,6 @@ function writePackageFieldSync(field, value, options = {}) {
1159
1208
  runTwinSync(writePackageFieldBody(field, value, options));
1160
1209
  }
1161
1210
  //#endregion
1162
- export { ConfReader, ConfWriter, FormatRegistry, JSONReader, JSONWriter, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LOCTER_WRITE_ERROR_MARKER, LocterError, LocterLoadError, LocterNotFoundError, LocterUnknownExtensionError, LocterWriteError, MODULE_FILE_EXTENSIONS, ModuleReader, TextFileReader, TextFileWriter, YAMLReader, YAMLWriter, buildFilePath, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readPackageField, readPackageFieldSync, readSync, registerFormat, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
1211
+ export { ConfReader, ConfWriter, FormatRegistry, JSONReader, JSONWriter, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LOCTER_WRITE_ERROR_MARKER, LocterError, LocterLoadError, LocterNotFoundError, LocterUnknownExtensionError, LocterWriteError, MODULE_FILE_EXTENSIONS, ModuleReader, TextFileReader, TextFileWriter, YAMLReader, YAMLWriter, buildFilePath, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
1163
1212
 
1164
1213
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["parseYAML","stringifyYAML"],"sources":["../src/errors/base.ts","../src/errors/load.ts","../src/errors/not-found.ts","../src/errors/unknown-extension.ts","../src/utils/has-property.ts","../src/utils/object.ts","../src/utils/to-array.ts","../src/utils/file-path.ts","../src/utils/runtime.ts","../src/utils/typescript.ts","../src/errors/write.ts","../src/errors/wrap.ts","../src/utils/twin.ts","../src/locator/utils.ts","../src/locator/core.ts","../src/locator/async.ts","../src/locator/sync.ts","../src/locator/up.ts","../src/format/text-file/reader.ts","../src/format/text-file/writer.ts","../src/format/built-in/conf/reader.ts","../src/format/built-in/conf/writer.ts","../src/format/built-in/json/reader.ts","../src/format/built-in/json/writer.ts","../src/format/built-in/module/constants.ts","../src/format/built-in/module/reader.ts","../src/format/built-in/module/utils.ts","../src/format/built-in/yaml/reader.ts","../src/format/built-in/yaml/writer.ts","../src/format/built-in/registry.ts","../src/format/registry/module.ts","../src/format/registry/singleton.ts","../src/format/helpers.ts","../src/format/package-field.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n BaseError,\n type ErrorOptions,\n hasInstanceof,\n markInstanceof,\n} from '@ebec/core';\n\nexport type LocterErrorOptions = ErrorOptions & {\n path?: string,\n};\n\nexport type LocterErrorInput = string | LocterErrorOptions;\n\nexport const LOCTER_ERROR_MARKER = Symbol.for('@locter/error');\n\nexport class LocterError extends BaseError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_ERROR_MARKER);\n }\n\n public readonly path?: string;\n\n constructor(input: LocterErrorInput = {}) {\n if (typeof input === 'string') {\n super(input);\n } else {\n const { path, ...rest } = input;\n super(rest);\n this.path = path;\n }\n\n markInstanceof(this, LOCTER_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_LOAD_ERROR_MARKER = Symbol.for('@locter/load-error');\n\nexport class LocterLoadError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_LOAD_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_LOAD_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for('@locter/not-found-error');\n\nexport class LocterNotFoundError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_NOT_FOUND_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_NOT_FOUND_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for('@locter/unknown-extension-error');\n\nexport class LocterUnknownExtensionError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);\n }\n}\n","export function hasOwnProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, unknown> {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nexport function hasStringProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, string> {\n return hasOwnProperty(obj, prop) && typeof obj[prop] === 'string';\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isObject(item: unknown) : item is Record<string, any> {\n return (\n !!item &&\n typeof item === 'object' &&\n !Array.isArray(item)\n );\n}\n\nexport function isSafeObjectKey(key: string) : boolean {\n return key !== '__proto__' &&\n key !== 'prototype' &&\n key !== 'constructor';\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function toArray(input: string | string[]) : string[] {\n return Array.isArray(input) ? input : [input];\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\nimport path from 'node:path';\n\nexport function isFilePath(input: string) {\n const extension = path.extname(input);\n return extension && extension !== '';\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isJestRuntimeEnvironment() : boolean {\n return process.env &&\n process.env.JEST_WORKER_ID !== undefined;\n}\n\nexport function isVitestRuntimeEnvironment() : boolean {\n return typeof process !== 'undefined' &&\n process.env.VITEST === 'true';\n}\n\nexport function isTsNodeRuntimeEnvironment(): boolean {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return !!process[Symbol.for('ts-node.register.instance')];\n}\n\n// matches the bare `tsx` specifier (node --import tsx), optionally with a\n// subpath (tsx/esm), as well as resolved paths into the tsx package\n// (.../node_modules/tsx/dist/loader.mjs)\nconst TSX_MARKER_REGEX = /(?:^|=|[\\\\/])tsx(?:$|[\\\\/])/;\n\nexport function isTsxRuntimeEnvironment() : boolean {\n if (typeof process === 'undefined') {\n return false;\n }\n\n if (\n Array.isArray(process.execArgv) &&\n process.execArgv.some((arg) => TSX_MARKER_REGEX.test(arg))\n ) {\n return true;\n }\n\n const { _preload_modules: preloadModules } = process as unknown as { _preload_modules?: string[] };\n\n return Array.isArray(preloadModules) &&\n preloadModules.some((el) => TSX_MARKER_REGEX.test(el));\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject } from './object';\n\nexport function isTypeScriptError(input: unknown) : input is Error {\n if (!isObject(input)) {\n return false;\n }\n\n if (typeof input.diagnosticCodes !== 'undefined') {\n return true;\n }\n\n return typeof input.message === 'string' &&\n /TS\\d+/.test(input.message);\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_WRITE_ERROR_MARKER = Symbol.for('@locter/write-error');\n\nexport class LocterWriteError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_WRITE_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_WRITE_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasStringProperty, isObject } from '../utils';\nimport { LocterError } from './base';\nimport { LocterLoadError } from './load';\nimport { LocterNotFoundError } from './not-found';\nimport { LocterWriteError } from './write';\n\nconst NOT_FOUND_CODES = new Set([\n 'ENOENT',\n 'MODULE_NOT_FOUND',\n 'ERR_MODULE_NOT_FOUND',\n]);\n\nexport function wrapLoaderError(input: unknown, path: string) : LocterError {\n if (input instanceof LocterError) {\n return input;\n }\n\n const code = isObject(input) && hasStringProperty(input, 'code') ?\n input.code :\n undefined;\n\n const message = isObject(input) && hasStringProperty(input, 'message') ?\n input.message :\n `Failed to load: ${path}`;\n\n if (code && NOT_FOUND_CODES.has(code)) {\n return new LocterNotFoundError({\n message,\n code,\n cause: input,\n path,\n });\n }\n\n return new LocterLoadError({\n message,\n code,\n cause: input,\n path,\n });\n}\n\nexport function wrapWriteError(input: unknown, path: string) : LocterError {\n if (input instanceof LocterError) {\n return input;\n }\n\n const code = isObject(input) && hasStringProperty(input, 'code') ?\n input.code :\n undefined;\n\n const message = isObject(input) && hasStringProperty(input, 'message') ?\n input.message :\n `Failed to write: ${path}`;\n\n return new LocterWriteError({\n message,\n code,\n cause: input,\n path,\n });\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * Internal protocol to derive the parallel sync + async public surfaces\n * from one shared body. A body is a generator that yields effect pairs —\n * an async and a sync thunk for the same operation — and the two drivers\n * (runTwinAsync / runTwinSync) execute the side they stand for. Effect\n * errors are re-entered into the body via `Generator.throw`, so try/catch\n * inside a body behaves identically in both variants.\n *\n * Deliberately NOT exported from the utils barrel — this is internal\n * plumbing, not public API.\n */\n\nexport type TwinOp<T = unknown> = {\n async: () => Promise<T>,\n sync: () => T,\n};\n\nexport type TwinBody<R> = Generator<TwinOp<any>, R, any>;\n\n/**\n * Perform one effect inside a twin body: `const x = yield* op(a, s)`.\n */\nexport function* op<T>(\n asyncFn: () => Promise<T>,\n syncFn: () => T,\n) : Generator<TwinOp<T>, T, T> {\n return yield { async: asyncFn, sync: syncFn };\n}\n\nexport async function runTwinAsync<R>(body: TwinBody<R>) : Promise<R> {\n let step = body.next();\n while (!step.done) {\n let result : unknown;\n try {\n result = await step.value.async();\n } catch (e) {\n step = body.throw(e);\n continue;\n }\n\n step = body.next(result);\n }\n\n return step.value;\n}\n\nexport function runTwinSync<R>(body: TwinBody<R>) : R {\n let step = body.next();\n while (!step.done) {\n let result : unknown;\n try {\n result = step.value.sync();\n } catch (e) {\n step = body.throw(e);\n continue;\n }\n\n step = body.next(result);\n }\n\n return step.value;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport path from 'node:path';\nimport { isObject, toArray } from '../utils';\nimport type { LocatorInfo, LocatorOptions, LocatorOptionsInput } from './types';\n\nexport function buildLocatorPatterns(pattern: string | string[]) : string[] {\n return Array.isArray(pattern) ?\n pattern :\n [pattern];\n}\n\nexport function buildLocatorOptions(options: LocatorOptionsInput = {}) : LocatorOptions {\n const cwd = options.cwd ?\n toArray(options.cwd) :\n [];\n\n const ignore = options.ignore ?\n toArray(options.ignore) :\n [];\n\n if (cwd.length === 0) {\n cwd.push(process.cwd());\n }\n\n // precedence: an explicit `onlyDirectories: true` wins over `onlyFiles`\n // (which defaults to true); when neither restricts, everything matches\n const onlyDirectories = options.onlyDirectories ?? false;\n const onlyFiles = onlyDirectories ?\n false :\n options.onlyFiles ?? true;\n\n return {\n cwd,\n ignore,\n onlyDirectories,\n onlyFiles,\n dot: options.dot ?? false,\n };\n}\n\nexport function pathToLocatorInfo(\n input: string,\n skipResolve?: boolean,\n) : LocatorInfo {\n if (\n !skipResolve &&\n !path.isAbsolute(input)\n ) {\n input = path.resolve(process.cwd(), input);\n }\n\n const info = path.parse(input);\n const directory = info.dir.split('/').join(path.sep);\n const extension = info.ext ? info.ext : undefined;\n const filePath = extension ?\n path.join(directory, info.name) + extension :\n path.join(directory, info.name);\n\n return {\n directory,\n name: info.name,\n extension,\n path: filePath,\n };\n}\n\nexport function isLocatorInfo(\n input: unknown,\n) : input is LocatorInfo {\n return isObject(input) &&\n typeof input.directory === 'string' &&\n typeof input.name === 'string' &&\n (typeof input.extension === 'undefined' || typeof input.extension === 'string') &&\n typeof input.path === 'string';\n}\n\nexport function buildFilePath(input: LocatorInfo | string) {\n if (typeof input === 'string') {\n return input;\n }\n\n return input.path;\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fg from 'fast-glob';\nimport type { TwinBody } from '../utils/twin';\nimport { op } from '../utils/twin';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\nimport { buildLocatorOptions, buildLocatorPatterns, pathToLocatorInfo } from './utils';\n\ntype GlobJob = {\n pattern: string,\n options: fg.Options,\n};\n\nfunction buildGlobJobs(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : GlobJob[] {\n const patterns = buildLocatorPatterns(pattern);\n const opts = buildLocatorOptions(options);\n\n const jobs : GlobJob[] = [];\n for (const p of patterns) {\n for (const cwd of opts.cwd) {\n jobs.push({\n pattern: p,\n options: {\n absolute: true,\n cwd,\n ignore: opts.ignore,\n onlyFiles: opts.onlyFiles,\n onlyDirectories: opts.onlyDirectories,\n dot: opts.dot,\n },\n });\n }\n }\n\n return jobs;\n}\n\nfunction* glob(job: GlobJob) : Generator<any, string[], any> {\n return yield* op(\n () => fg(job.pattern, job.options),\n () => fg.sync(job.pattern, job.options),\n );\n}\n\nexport function* locateBody(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : TwinBody<LocatorInfo | undefined> {\n for (const job of buildGlobJobs(pattern, options)) {\n const files = yield* glob(job);\n\n const element = files.shift();\n if (element) {\n return pathToLocatorInfo(element, true);\n }\n }\n\n return undefined;\n}\n\nexport function* locateManyBody(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : TwinBody<LocatorInfo[]> {\n const items : LocatorInfo[] = [];\n\n for (const job of buildGlobJobs(pattern, options)) {\n const files = yield* glob(job);\n\n for (const file of files) {\n items.push(pathToLocatorInfo(file, true));\n }\n }\n\n return items;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { runTwinAsync } from '../utils/twin';\nimport { locateBody, locateManyBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport async function locateMany(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : Promise<LocatorInfo[]> {\n return runTwinAsync(locateManyBody(pattern, options));\n}\n\nexport async function locate(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : Promise<LocatorInfo | undefined> {\n return runTwinAsync(locateBody(pattern, options));\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { runTwinSync } from '../utils/twin';\nimport { locateBody, locateManyBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport function locateManySync(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : LocatorInfo[] {\n return runTwinSync(locateManyBody(pattern, options));\n}\n\nexport function locateSync(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : LocatorInfo | undefined {\n return runTwinSync(locateBody(pattern, options));\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport path from 'node:path';\nimport type { TwinBody } from '../utils/twin';\nimport { runTwinAsync, runTwinSync } from '../utils/twin';\nimport { locateBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport type LocatorUpOptionsInput = Omit<LocatorOptionsInput, 'cwd'> & {\n cwd?: string,\n stopAt?: string,\n};\n\ntype WalkStep = {\n current: string,\n stopAt: string,\n baseOptions: Omit<LocatorOptionsInput, 'cwd'>,\n};\n\nfunction startWalk(options: LocatorUpOptionsInput) : WalkStep {\n const {\n cwd,\n stopAt,\n ...baseOptions\n } = options;\n const current = path.resolve(cwd ?? process.cwd());\n const ceiling = stopAt ?\n path.resolve(current, stopAt) :\n path.parse(current).root;\n\n return {\n current,\n stopAt: ceiling,\n baseOptions,\n };\n}\n\nfunction nextDirectory(current: string, stopAt: string) : string | undefined {\n if (current === stopAt) {\n return undefined;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n\n return parent;\n}\n\nfunction* locateUpBody(\n pattern: string | string[],\n options: LocatorUpOptionsInput,\n) : TwinBody<LocatorInfo | undefined> {\n let walk = startWalk(options);\n\n while (true) {\n const found = yield* locateBody(pattern, { ...walk.baseOptions, cwd: walk.current });\n if (found) {\n return found;\n }\n\n const next = nextDirectory(walk.current, walk.stopAt);\n if (!next) {\n return undefined;\n }\n\n walk = { ...walk, current: next };\n }\n}\n\nexport async function locateUp(\n pattern: string | string[],\n options: LocatorUpOptionsInput = {},\n) : Promise<LocatorInfo | undefined> {\n return runTwinAsync(locateUpBody(pattern, options));\n}\n\nexport function locateUpSync(\n pattern: string | string[],\n options: LocatorUpOptionsInput = {},\n) : LocatorInfo | undefined {\n return runTwinSync(locateUpBody(pattern, options));\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fs from 'node:fs';\nimport { wrapLoaderError } from '../../errors';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport type { IReader } from '../type';\n\n/**\n * Base class for readers of text-based file formats: reads the file as\n * UTF-8, delegates to `parse`, and wraps I/O and parse errors in typed\n * LocterError subclasses. Subclasses implement `parse` only — both\n * `read` variants are derived from the same body.\n */\nexport abstract class TextFileReader implements IReader {\n abstract parse(content: string) : any;\n\n async read(input: string) : Promise<any> {\n return runTwinAsync(this.body(input));\n }\n\n readSync(input: string) : any {\n return runTwinSync(this.body(input));\n }\n\n protected* body(input: string) : TwinBody<any> {\n try {\n const content = yield* op(\n () => fs.promises.readFile(input, { encoding: 'utf-8' }),\n () => fs.readFileSync(input, { encoding: 'utf-8' }),\n );\n\n return this.parse(content);\n } catch (e) {\n throw wrapLoaderError(e, input);\n }\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { wrapWriteError } from '../../errors';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport type { IWriter } from '../type';\n\nfunction isNotFound(e: unknown) : boolean {\n return e instanceof Error && 'code' in e && e.code === 'ENOENT';\n}\n\n/**\n * Base class for writers of text-based file formats: serializes via\n * `stringify`, creates missing parent directories, writes the file as\n * UTF-8 (always terminated by a single trailing newline), and wraps\n * failures in LocterWriteError. Subclasses implement `stringify` only —\n * both `write` variants are derived from the same body.\n */\nexport abstract class TextFileWriter implements IWriter {\n /**\n * Opt-in: when true, the body reads the target file first (undefined\n * if absent) and passes its content to `stringify` as `existing` —\n * the hook behind format-preserving write-back (YAML comment\n * grafting, JSON indent detection).\n */\n protected get usesExistingContent() : boolean {\n return false;\n }\n\n abstract stringify(value: unknown, existing?: string) : string;\n\n async write(input: string, value: unknown) : Promise<void> {\n return runTwinAsync(this.body(input, value));\n }\n\n writeSync(input: string, value: unknown) : void {\n runTwinSync(this.body(input, value));\n }\n\n protected* body(input: string, value: unknown) : TwinBody<void> {\n const filePath = input;\n\n try {\n let existing : string | undefined;\n if (this.usesExistingContent) {\n existing = yield* op(\n () => fs.promises.readFile(filePath, { encoding: 'utf-8' })\n .catch((e) => {\n if (isNotFound(e)) {\n return undefined;\n }\n throw e;\n }),\n () => {\n try {\n return fs.readFileSync(filePath, { encoding: 'utf-8' });\n } catch (e) {\n if (isNotFound(e)) {\n return undefined;\n }\n throw e;\n }\n },\n );\n }\n\n let content = this.stringify(value, existing);\n if (!content.endsWith('\\n')) {\n content += '\\n';\n }\n\n const directory = path.dirname(filePath);\n yield* op(\n async () => {\n await fs.promises.mkdir(directory, { recursive: true });\n },\n () => {\n fs.mkdirSync(directory, { recursive: true });\n },\n );\n\n yield* op(\n () => fs.promises.writeFile(filePath, content, { encoding: 'utf-8' }),\n () => fs.writeFileSync(filePath, content, { encoding: 'utf-8' }),\n );\n } catch (e) {\n throw wrapWriteError(e, filePath);\n }\n }\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n// Based on https://github.com/unjs/rc9 (MIT)\n\nimport { destr } from 'destr';\nimport { unflatten } from 'flat';\nimport { isSafeObjectKey } from '../../../utils';\nimport { TextFileReader } from '../../text-file';\n\nexport class ConfReader extends TextFileReader {\n parse(contents: string): Record<string, any> {\n const config: Record<string, any> = {};\n\n const lines = contents.split(/\\n|\\r|\\r\\n/);\n\n for (const line of lines) {\n const match = line.match(/^\\s*([^\\s=]+)\\s*=\\s*(.*)?\\s*$/);\n if (!match) {\n continue;\n }\n\n const key = match[1];\n const rawValue = match[2];\n\n if (!key || !isSafeObjectKey(key)) {\n continue;\n }\n\n const value = destr(rawValue ? rawValue.trim() : '');\n\n if (key.endsWith('[]')) {\n const arrKey = key.slice(0, Math.max(0, key.length - 2));\n config[arrKey] = (config[arrKey] || []).concat(value);\n continue;\n }\n\n config[key] = value;\n }\n\n return unflatten(config, { overwrite: true });\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n// Based on https://github.com/unjs/rc9 (MIT)\n\nimport { flatten } from 'flat';\nimport { isObject } from '../../../utils';\nimport { TextFileWriter } from '../../text-file';\n\nfunction serializeValue(value: unknown) : string {\n return typeof value === 'string' ? value : JSON.stringify(value);\n}\n\n/**\n * Serializes an object to `key=value` lines (the inverse of ConfReader):\n * nested objects become dot-separated keys, arrays become repeated\n * `key[]=` lines. Round-trips are structural, not textual — comments,\n * blank lines, and line order of an existing file are not preserved,\n * and a string that parses as another type (e.g. '123') reads back as\n * that type.\n */\nexport class ConfWriter extends TextFileWriter {\n stringify(value: unknown) : string {\n if (!isObject(value)) {\n throw new Error('The value must be an object for the conf format.');\n }\n\n const flat : Record<string, unknown> = flatten(value, { safe: true });\n\n const lines : string[] = [];\n for (const key of Object.keys(flat)) {\n const entry = flat[key];\n if (typeof entry === 'undefined') {\n continue;\n }\n\n if (Array.isArray(entry)) {\n for (const item of entry) {\n lines.push(`${key}[]=${serializeValue(item)}`);\n }\n continue;\n }\n\n lines.push(`${key}=${serializeValue(entry)}`);\n }\n\n return lines.join('\\n');\n }\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { TextFileReader } from '../../text-file';\n\nexport class JSONReader extends TextFileReader {\n parse(content: string) {\n return JSON.parse(content);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { TextFileWriter } from '../../text-file';\n\nexport type JSONWriterOptions = {\n /**\n * Indentation of the emitted JSON. A number of spaces, a literal\n * indent string, or 'auto' — detect the indentation of the existing\n * target file and keep it (falls back to 4 for new files).\n *\n * @default 4\n */\n indent?: number | string | 'auto'\n};\n\nfunction detectIndent(content: string) : string | undefined {\n const match = /^([ \\t]+)\\S/m.exec(content);\n return match ? match[1] : undefined;\n}\n\nexport class JSONWriter extends TextFileWriter {\n protected options : JSONWriterOptions;\n\n constructor(options: JSONWriterOptions = {}) {\n super();\n this.options = options;\n }\n\n protected override get usesExistingContent() : boolean {\n return this.options.indent === 'auto';\n }\n\n stringify(value: unknown, existing?: string) : string {\n let indent : number | string | undefined;\n if (this.options.indent === 'auto') {\n indent = existing ? detectIndent(existing) : undefined;\n } else {\n indent = this.options.indent;\n }\n\n indent = indent ?? 4;\n\n const output = JSON.stringify(value, null, indent);\n if (typeof output === 'undefined') {\n throw new Error('The value is not JSON-serializable.');\n }\n\n return output;\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * Single source of truth for the extensions handled by the module loader:\n * consumed by BOTH the built-in routing registry and the jiti config.\n */\nexport const MODULE_FILE_EXTENSIONS = ['.js', '.mjs', '.mts', '.cjs', '.cts', '.ts'] as const;\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { createJiti } from 'jiti';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport { LocterError, wrapLoaderError } from '../../../errors';\nimport type { LocatorInfo } from '../../../locator';\nimport {\n buildFilePath,\n isLocatorInfo,\n} from '../../../locator';\nimport {\n hasStringProperty,\n isFilePath,\n isJestRuntimeEnvironment,\n isObject,\n isTsNodeRuntimeEnvironment,\n isTypeScriptError,\n} from '../../../utils';\nimport type { IReader } from '../../type';\nimport { MODULE_FILE_EXTENSIONS } from './constants';\nimport type {\n ModuleLoadFn,\n ModuleLoadOptions,\n ModuleLoadSyncFn,\n ModuleReaderOptions,\n} from './type';\n\nconst require = createRequire(import.meta.url);\n\ntype Jiti = ReturnType<typeof createJiti>;\n\nfunction originalPath(data: LocatorInfo | string) : string {\n return typeof data === 'string' ? data : buildFilePath(data);\n}\n\nfunction isUnrecoverableError(error: unknown) : boolean {\n const underlying = error instanceof LocterError ? error.cause : error;\n return underlying instanceof SyntaxError ||\n underlying instanceof ReferenceError ||\n isTypeScriptError(underlying);\n}\n\nexport class ModuleReader implements IReader {\n protected instance : Jiti;\n\n protected loadFn?: ModuleLoadFn;\n\n protected loadSyncFn?: ModuleLoadSyncFn;\n\n constructor(options: ModuleReaderOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.instance = createJiti(undefined, { extensions: [...MODULE_FILE_EXTENSIONS] });\n this.loadFn = options.load;\n this.loadSyncFn = options.loadSync;\n }\n\n /**\n * Returns the previous configuration, so callers can restore it.\n */\n configure(options: ModuleReaderOptions) : ModuleReaderOptions {\n const previous : ModuleReaderOptions = {\n load: this.loadFn,\n loadSync: this.loadSyncFn,\n };\n\n if ('load' in options) {\n this.loadFn = options.load;\n }\n if ('loadSync' in options) {\n this.loadSyncFn = options.loadSync;\n }\n\n return previous;\n }\n\n /**\n * Returns the raw module value (import / require / jiti output) —\n * normalization to a module record happens once, at the\n * FormatRegistry boundary.\n *\n * read/readSync are deliberately NOT derived from a shared body\n * (unlike every other sync/async twin in this package): their\n * recovery paths differ. The async variant falls back to loadSync\n * under ts-node (jiti's async path does not cooperate with ts-node)\n * and to the jiti instance otherwise; the sync variant only has the\n * jiti fallback. The divergence is pinned by the fallback tests in\n * test/unit/format/module.spec.ts.\n */\n async read(input: string) {\n try {\n return await this.load(input);\n } catch (e) {\n if (isUnrecoverableError(e)) {\n throw e;\n }\n\n // jiti + ts-node\n // issue: https://github.com/nuxt/bridge/issues/228\n if (isTsNodeRuntimeEnvironment()) {\n return this.loadSync(input);\n }\n\n return this.instance(input);\n }\n }\n\n readSync(input: string) {\n try {\n return this.loadSync(input);\n } catch (e) {\n if (isUnrecoverableError(e)) {\n throw e;\n }\n\n return this.instance(input);\n }\n }\n\n // ---------------------------------------------------------------------------\n\n async load(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : Promise<unknown> {\n const id = this.build(data, options);\n\n try {\n if (this.loadFn) {\n return await this.loadFn(id);\n }\n\n // segmentation fault\n // issue: https://github.com/nodejs/node/issues/35889\n if (isJestRuntimeEnvironment()) {\n return require(id);\n }\n\n return await import(id);\n } catch (e) {\n /* istanbul ignore next */\n if (\n !options.withFilePrefix &&\n isObject(e) &&\n hasStringProperty(e, 'code') &&\n (\n e.code === 'ERR_UNSUPPORTED_ESM_URL_SCHEME' ||\n e.code === 'UNSUPPORTED_ESM_URL_SCHEME'\n )\n ) {\n return this.load(data, {\n ...options,\n withFilePrefix: true,\n });\n }\n\n throw wrapLoaderError(e, originalPath(data));\n }\n }\n\n loadSync(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : unknown {\n const id = this.build(data, options);\n\n try {\n if (this.loadSyncFn) {\n return this.loadSyncFn(id);\n }\n\n return require(id);\n } catch (e) {\n throw wrapLoaderError(e, originalPath(data));\n }\n }\n\n private build(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : string {\n if (isLocatorInfo(data) || isFilePath(data)) {\n if (typeof data !== 'string') {\n data = buildFilePath(data);\n }\n\n if (options.withFilePrefix) {\n data = pathToFileURL(data).href;\n }\n }\n\n return data;\n }\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasOwnProperty, isObject } from '../../../utils';\nimport type { ModuleExport, ModuleExportFilterFn } from './type';\n\ntype ESModule = { [key: string]: any, __esModule: boolean };\n\n/**\n * Brand carried by every record locter's read() produces. Deliberately a\n * module-private Symbol (NOT Symbol.for) so arbitrary parsed data cannot\n * forge it — unlike `__esModule`, its presence is trustworthy. write()\n * uses it to unwrap `.default` on round-trips.\n */\nconst MODULE_RECORD = Symbol('locter.record');\n\n/**\n * True when the value is a record produced by locter's read()/toModuleRecord.\n * Detection is brand-based; a plain object with an `__esModule` key is NOT\n * a module record.\n */\nexport function isModuleRecord(input: unknown) : input is Record<string, any> {\n return isObject(input) && MODULE_RECORD in input;\n}\n\nfunction brand<T>(input: T) : T {\n if (isObject(input) && Object.isExtensible(input)) {\n Object.defineProperty(input, MODULE_RECORD, { value: true });\n }\n\n return input;\n}\n\n/**\n * Detect the transpiler interop marker (`__esModule`). Only meaningful for\n * values that came out of a module system — arbitrary parsed data can carry\n * an `__esModule` key without being a module, so callers must decide by\n * provenance whether this check applies (see FormatRegistry).\n */\nexport function isESModule(input: unknown) : input is ESModule {\n return isObject(input) &&\n typeof input.__esModule !== 'undefined';\n}\n\n/**\n * Wrap an arbitrary value in a frozen module record: enumerable keys are\n * re-exposed as named exports and `default` is the value itself.\n */\nexport function createModuleRecord(data: unknown) {\n const output = Object.create(null, {\n __esModule: { value: true },\n [Symbol.toStringTag]: { value: 'Module' },\n [MODULE_RECORD]: { value: true },\n });\n\n if (isObject(data)) {\n for (const key in data) {\n if (hasOwnProperty(output, key)) {\n continue;\n }\n\n let descriptor = Object.getOwnPropertyDescriptor(data, key);\n if (\n !descriptor ||\n ('get' in descriptor || descriptor.writable || descriptor.configurable)\n ) {\n descriptor = {\n enumerable: true,\n get() {\n return data[key];\n },\n };\n }\n\n Object.defineProperty(output, key, descriptor);\n }\n }\n\n if (!hasOwnProperty(output, 'default')) {\n Object.defineProperty(output, 'default', {\n value: data,\n enumerable: true,\n });\n }\n\n return Object.freeze(output);\n}\n\n/**\n * Normalize module-loader output to a module record. Values already carrying\n * the `__esModule` marker pass through (module provenance makes the marker\n * trustworthy); everything else is wrapped via createModuleRecord.\n *\n * https://2ality.com/2017/01/babel-esm-spec-mode.html\n */\nexport function toModuleRecord(\n data: unknown,\n) {\n if (isESModule(data)) {\n // @see https://github.com/testing-library/user-event/issues/813\n // @see https://stackoverflow.com/questions/62717394/export-default-class-exports-double-nested-default\n if (\n isESModule(data.default) &&\n data.default.default\n ) {\n return brand({\n ...data,\n default: data.default.default,\n });\n }\n\n // best-effort: module namespace objects are non-extensible and\n // stay unbranded — they have no writable format anyway\n return brand(data);\n }\n\n return createModuleRecord(data);\n}\n\nexport function getModuleExport(\n data: Record<string, any>,\n filterFn: ModuleExportFilterFn,\n): ModuleExport | undefined {\n const keys = Object.keys(data);\n for (const key of keys) {\n if (filterFn(key as string, data[key as string])) {\n return {\n key: key as string,\n value: data[key as string],\n };\n }\n }\n\n return undefined;\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { parse as parseYAML } from 'yaml';\nimport { TextFileReader } from '../../text-file';\n\nexport class YAMLReader extends TextFileReader {\n parse(content: string) {\n return parseYAML(content);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Document, ToStringOptions, YAMLMap } from 'yaml';\nimport {\n isMap,\n isNode,\n isScalar,\n parseDocument,\n stringify as stringifyYAML,\n} from 'yaml';\nimport { hasOwnProperty, isObject } from '../../../utils';\nimport { TextFileWriter } from '../../text-file';\n\nexport type YAMLWriterOptions = ToStringOptions;\n\nfunction pairKey(key: unknown) : string {\n return isScalar(key) ? String(key.value) : String(key);\n}\n\n/**\n * Merge a plain object into an existing YAML map node: added/changed keys\n * are set, absent keys are deleted, and nested objects recurse — so\n * comments, anchors, and formatting attached to surviving keys are\n * preserved. Arrays, scalars, and type changes replace the node wholesale\n * (comments inside the replaced subtree are lost).\n */\nfunction graftMap(doc: Document, node: YAMLMap, value: Record<string, unknown>) : void {\n for (const pair of [...node.items]) {\n if (!hasOwnProperty(value, pairKey(pair.key))) {\n node.delete(pair.key);\n }\n }\n\n for (const key of Object.keys(value)) {\n const entry = value[key];\n const current = node.get(key, true);\n\n if (isMap(current) && isObject(entry)) {\n graftMap(doc, current, entry);\n continue;\n }\n\n const replacement = doc.createNode(entry);\n if (isNode(current)) {\n // keep comments anchored to the value node itself\n // (`key: value # trailing`, standalone lines above the value)\n replacement.commentBefore = current.commentBefore;\n replacement.comment = current.comment;\n replacement.spaceBefore = current.spaceBefore;\n }\n\n node.set(doc.createNode(key), replacement);\n }\n}\n\n/**\n * Writes YAML preserving hand-edited structure where possible: when the\n * target file already exists, the new value is grafted into its parsed\n * document, so comments and anchors attached to surviving keys survive\n * the write-back. New files are plain `yaml.stringify` output. An\n * existing file that fails to parse throws (wrapped as LocterWriteError)\n * instead of being silently overwritten.\n */\nexport class YAMLWriter extends TextFileWriter {\n protected options : YAMLWriterOptions;\n\n constructor(options: YAMLWriterOptions = {}) {\n super();\n this.options = options;\n }\n\n protected override get usesExistingContent() : boolean {\n return true;\n }\n\n stringify(value: unknown, existing?: string) : string {\n if (typeof existing === 'undefined') {\n return stringifyYAML(value, this.options);\n }\n\n // widen from Document.Parsed: contents is replaced with\n // freshly created (non-parsed) nodes while grafting\n const doc : Document = parseDocument(existing);\n if (doc.errors.length > 0) {\n throw doc.errors[0];\n }\n\n if (isMap(doc.contents) && isObject(value)) {\n graftMap(doc, doc.contents, value);\n } else {\n doc.contents = doc.createNode(value);\n }\n\n return doc.toString(this.options);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { FormatPreset } from '../registry/type';\nimport type { IWriter } from '../type';\nimport { ConfReader, ConfWriter } from './conf';\nimport { JSONReader, JSONWriter } from './json';\nimport { ModuleReader } from './module';\nimport { MODULE_FILE_EXTENSIONS } from './module/constants';\nimport { YAMLReader, YAMLWriter } from './yaml';\n\n/**\n * Every built-in format, in one place. Keys are the format ids; each entry\n * couples routing and construction. The id union, the extension → format\n * table, lazy caching, and the typed `builtInReader()` accessor are all\n * DERIVED from this object. Adding a format = adding one entry.\n *\n * Intentionally NOT re-exported from any barrel (internal API).\n */\nexport const BUILT_IN_PRESETS = {\n module: { extensions: MODULE_FILE_EXTENSIONS, reader: () => new ModuleReader() },\n conf: {\n extensions: ['.conf'],\n reader: () => new ConfReader(),\n writer: () => new ConfWriter(),\n },\n json: {\n extensions: ['.json'],\n reader: () => new JSONReader(),\n writer: () => new JSONWriter(),\n },\n yaml: {\n extensions: ['.yml', '.yaml'],\n reader: () => new YAMLReader(),\n writer: () => new YAMLWriter(),\n },\n} as const satisfies Record<string, FormatPreset>;\n\nexport type BuiltInFormatId = keyof typeof BUILT_IN_PRESETS;\n\nexport type BuiltInReaderOf<K extends BuiltInFormatId> = ReturnType<(typeof BUILT_IN_PRESETS)[K]['reader']>;\n\n/**\n * Built-in format ids whose preset declares a writer — derived at the type\n * level, so builtInWriter('module') is a compile error, not a runtime one.\n */\nexport type WritableBuiltInFormatId = {\n [K in BuiltInFormatId]: (typeof BUILT_IN_PRESETS)[K] extends { writer: () => IWriter } ? K : never\n}[BuiltInFormatId];\n\nexport type BuiltInWriterOf<K extends WritableBuiltInFormatId> = ReturnType<(typeof BUILT_IN_PRESETS)[K]['writer']>;\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n LocterError,\n LocterUnknownExtensionError,\n LocterWriteError,\n wrapLoaderError,\n wrapWriteError,\n} from '../../errors';\nimport type { LocatorInfo } from '../../locator';\nimport { buildFilePath, pathToLocatorInfo } from '../../locator';\nimport { hasOwnProperty, isFilePath } from '../../utils';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport {\n ModuleReader, \n createModuleRecord, \n isModuleRecord, \n toModuleRecord,\n} from '../built-in';\nimport type {\n BuiltInFormatId,\n BuiltInReaderOf,\n BuiltInWriterOf,\n WritableBuiltInFormatId,\n} from '../built-in/registry';\nimport { BUILT_IN_PRESETS } from '../built-in/registry';\nimport type { IReader, IWriter } from '../type';\nimport type {\n FormatRegistration,\n Rule,\n} from './type';\n\nexport type FormatRegistryOptions = {\n /**\n * Seed user rules (matched before built-ins, in array order).\n */\n rules?: Rule[]\n};\n\n/**\n * A rule compiled to memoizing per-slot accessors. Caller-owned Rule\n * objects are never mutated; factory caching lives in the closures.\n */\ntype CompiledRule = {\n id: string,\n test: RegExp | string[],\n getReader?: () => IReader,\n getWriter?: () => IWriter\n};\n\nfunction compileSlot<T>(slot: T | (() => T) | undefined) : (() => T) | undefined {\n if (typeof slot === 'undefined') {\n return undefined;\n }\n\n if (typeof slot !== 'function') {\n return () => slot;\n }\n\n const factory = slot as () => T;\n let cached : T | undefined;\n return () => {\n if (!cached) {\n cached = factory();\n }\n\n return cached;\n };\n}\n\nexport class FormatRegistry {\n /**\n * User rules only — built-ins live in the extension table instead.\n */\n protected rules : CompiledRule[];\n\n /**\n * Lazy per-instance cache of built-in reader instances.\n */\n protected builtInReaderCache : Map<BuiltInFormatId, IReader>;\n\n /**\n * Lazy per-instance cache of built-in writer instances.\n */\n protected builtInWriterCache : Map<BuiltInFormatId, IWriter>;\n\n /**\n * extension → built-in format id, precomputed once from BUILT_IN_PRESETS.\n */\n protected builtInExtensions : Map<string, BuiltInFormatId>;\n\n protected ruleCounter : number;\n\n constructor(options: FormatRegistryOptions = {}) {\n this.rules = [];\n this.builtInReaderCache = new Map();\n this.builtInWriterCache = new Map();\n this.builtInExtensions = new Map();\n this.ruleCounter = 0;\n\n const ids = Object.keys(BUILT_IN_PRESETS) as BuiltInFormatId[];\n for (const id of ids) {\n for (const extension of BUILT_IN_PRESETS[id].extensions) {\n const existing = this.builtInExtensions.get(extension);\n if (existing) {\n throw new LocterError({ message: `Extension ${extension} is claimed by two built-in formats: ${existing}, ${id}.` });\n }\n\n this.builtInExtensions.set(extension, id);\n }\n }\n\n if (options.rules) {\n for (const rule of options.rules) {\n this.register(rule);\n }\n }\n }\n\n register(rule: Rule) : FormatRegistration {\n if (\n typeof rule.id !== 'undefined' &&\n hasOwnProperty(BUILT_IN_PRESETS, rule.id)\n ) {\n throw new LocterError({ message: `The id ${rule.id} is reserved by a built-in format.` });\n }\n\n if (\n typeof rule.reader === 'undefined' &&\n typeof rule.writer === 'undefined'\n ) {\n throw new LocterError({ message: 'A rule requires at least one of: reader, writer.' });\n }\n\n const id = rule.id ?? this.generateRuleId();\n const entry = this.compile(id, rule);\n\n const index = this.rules.findIndex((item) => item.id === id);\n if (index === -1) {\n this.rules.push(entry);\n } else {\n // replace in place: position preserved, cached instance evicted\n this.rules[index] = entry;\n }\n\n return {\n id,\n test: rule.test,\n builtIn: false,\n };\n }\n\n /**\n * Remove a user-registered rule by id. Built-in ids cannot be\n * unregistered (returns false).\n */\n unregister(id: string) : boolean {\n const index = this.rules.findIndex((item) => item.id === id);\n if (index === -1) {\n return false;\n }\n\n this.rules.splice(index, 1);\n return true;\n }\n\n has(id: string) : boolean {\n if (this.rules.some((item) => item.id === id)) {\n return true;\n }\n\n return hasOwnProperty(BUILT_IN_PRESETS, id);\n }\n\n /**\n * All registrations in effective match order: user rules\n * (registration order) first, then the built-ins.\n */\n entries() : FormatRegistration[] {\n const output : FormatRegistration[] = this.rules.map(\n (item) => ({\n id: item.id,\n test: item.test,\n builtIn: false,\n }),\n );\n\n const ids = Object.keys(BUILT_IN_PRESETS) as BuiltInFormatId[];\n for (const id of ids) {\n output.push({\n id,\n test: [...BUILT_IN_PRESETS[id].extensions],\n builtIn: true,\n });\n }\n\n return output;\n }\n\n /**\n * Restore the registry to its construction state: drop all user rules\n * and evict every cached reader instance (including a module reader\n * configured via setModuleReader / configure).\n */\n reset() : void {\n this.rules = [];\n this.builtInReaderCache.clear();\n this.builtInWriterCache.clear();\n this.ruleCounter = 0;\n }\n\n async read(input: LocatorInfo | string) : Promise<any> {\n return runTwinAsync(this.readBody(input));\n }\n\n readSync(input: LocatorInfo | string) : any {\n return runTwinSync(this.readBody(input));\n }\n\n /**\n * Shared body of read/readSync: dispatch, read, normalize, wrap.\n */\n protected* readBody(input: LocatorInfo | string) : TwinBody<any> {\n const filePath = buildFilePath(input);\n const reader = this.findReader(filePath);\n if (!reader) {\n throw this.unknownExtensionError(filePath);\n }\n\n try {\n const output = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n return this.toRecord(output, reader);\n } catch (e) {\n throw wrapLoaderError(e, filePath);\n }\n }\n\n async write(input: LocatorInfo | string, value: unknown) : Promise<void> {\n return runTwinAsync(this.writeBody(input, value));\n }\n\n writeSync(input: LocatorInfo | string, value: unknown) : void {\n runTwinSync(this.writeBody(input, value));\n }\n\n /**\n * Shared body of write/writeSync: dispatch, unwrap records, write, wrap.\n * The inverse boundary of readBody: a record produced by read() (brand\n * detected) is unwrapped to its `.default` value; anything else is\n * written as-is.\n */\n protected* writeBody(input: LocatorInfo | string, value: unknown) : TwinBody<void> {\n const filePath = buildFilePath(input);\n if (!isFilePath(filePath)) {\n throw new LocterWriteError({\n message: `Cannot write to a bare module specifier: ${filePath}`,\n path: filePath,\n });\n }\n\n const writer = this.findWriter(filePath);\n if (!writer) {\n if (this.findReader(filePath)) {\n const info = pathToLocatorInfo(filePath);\n throw new LocterWriteError({\n message: `The format of extension ${info.extension} is read-only.`,\n path: filePath,\n });\n }\n\n throw this.unknownExtensionError(filePath);\n }\n\n const plain = isModuleRecord(value) ? value.default : value;\n\n try {\n yield* op(\n () => writer.write(filePath, plain),\n () => writer.writeSync(filePath, plain),\n );\n } catch (e) {\n throw wrapWriteError(e, filePath);\n }\n }\n\n /**\n * The single normalization boundary: every read result becomes a module\n * record (`.default` is always the loaded value, top-level keys stay\n * accessible as named exports). Provenance decides how: module-reader\n * output may legitimately already be a record (`__esModule` is meaningful\n * there); any other reader returns arbitrary parsed data, which is always\n * wrapped — even if it happens to contain an `__esModule` key.\n */\n protected toRecord(output: unknown, reader: IReader) : any {\n if (reader instanceof ModuleReader) {\n return toModuleRecord(output);\n }\n\n return createModuleRecord(output);\n }\n\n /**\n * Typed accessor for the LIVE built-in reader instance (lazy, cached).\n */\n builtInReader<K extends BuiltInFormatId>(id: K) : BuiltInReaderOf<K> {\n let reader = this.builtInReaderCache.get(id);\n if (!reader) {\n reader = BUILT_IN_PRESETS[id].reader();\n this.builtInReaderCache.set(id, reader);\n }\n\n return reader as BuiltInReaderOf<K>;\n }\n\n /**\n * Typed accessor for the LIVE built-in writer instance (lazy, cached).\n * Only writable format ids are accepted — read-only formats (module)\n * are a compile error.\n */\n builtInWriter<K extends WritableBuiltInFormatId>(id: K) : BuiltInWriterOf<K> {\n let writer = this.builtInWriterCache.get(id);\n if (!writer) {\n writer = BUILT_IN_PRESETS[id].writer();\n this.builtInWriterCache.set(id, writer);\n }\n\n return writer as BuiltInWriterOf<K>;\n }\n\n /**\n * Dispatch order:\n * 1. bare specifier (no extension) → module reader, always\n * 2. user rules, registration order → first match wins (can override built-ins)\n * 3. built-in extension table\n * 4. undefined → read/readSync throw LocterUnknownExtensionError\n */\n findReader(input: string) : IReader | undefined {\n if (!isFilePath(input)) {\n return this.builtInReader('module');\n }\n\n const rule = this.findRule(input, (item) => typeof item.getReader !== 'undefined');\n if (rule && rule.getReader) {\n return rule.getReader();\n }\n\n const id = this.findBuiltInId(input);\n if (id) {\n return this.builtInReader(id);\n }\n\n return undefined;\n }\n\n /**\n * Write-side dispatch. No bare-specifier step (there is nothing to\n * write to); only rules with a writer slot participate, then built-in\n * presets that declare a writer.\n */\n findWriter(input: string) : IWriter | undefined {\n if (!isFilePath(input)) {\n return undefined;\n }\n\n const rule = this.findRule(input, (item) => typeof item.getWriter !== 'undefined');\n if (rule && rule.getWriter) {\n return rule.getWriter();\n }\n\n const id = this.findBuiltInId(input);\n if (id && 'writer' in BUILT_IN_PRESETS[id]) {\n return this.builtInWriter(id as WritableBuiltInFormatId);\n }\n\n return undefined;\n }\n\n protected findRule(\n input: string,\n filter: (rule: CompiledRule) => boolean,\n ) : CompiledRule | undefined {\n const info = pathToLocatorInfo(input);\n\n for (const rule of this.rules) {\n if (!filter(rule)) {\n continue;\n }\n\n const { test } = rule;\n if (Array.isArray(test)) {\n if (\n info.extension &&\n test.includes(info.extension)\n ) {\n return rule;\n }\n } else {\n // reset before AND after: a g/y regex mutates lastIndex on\n // test(), which would make repeated dispatch alternate and\n // leak state back into the caller-owned RegExp\n test.lastIndex = 0;\n const matched = test.test(buildFilePath(info));\n test.lastIndex = 0;\n if (matched) {\n return rule;\n }\n }\n }\n\n return undefined;\n }\n\n protected findBuiltInId(input: string) : BuiltInFormatId | undefined {\n const info = pathToLocatorInfo(input);\n if (!info.extension) {\n return undefined;\n }\n\n return this.builtInExtensions.get(info.extension);\n }\n\n protected unknownExtensionError(input: string) : LocterUnknownExtensionError {\n const info = pathToLocatorInfo(input);\n return new LocterUnknownExtensionError({\n message: `No format registered for extension: ${info.extension ?? 'unknown'}`,\n path: input,\n });\n }\n\n protected compile(id: string, rule: Rule) : CompiledRule {\n return {\n id,\n test: rule.test,\n getReader: compileSlot<IReader>(rule.reader),\n getWriter: compileSlot<IWriter>(rule.writer),\n };\n }\n\n protected generateRuleId() : string {\n let id : string;\n do {\n this.ruleCounter++;\n id = `rule:${this.ruleCounter}`;\n } while (this.rules.some((item) => item.id === id));\n\n return id;\n }\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { FormatRegistry } from './module';\n\nlet instance : FormatRegistry;\nexport function useFormatRegistry() {\n if (typeof instance !== 'undefined') {\n return instance;\n }\n\n instance = new FormatRegistry();\n\n return instance;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { LocatorInfo } from '../locator';\nimport type { ModuleReaderOptions } from './built-in/module/type';\nimport {\n type FormatRegistration,\n type Rule,\n useFormatRegistry,\n} from './registry';\n\nexport function registerFormat(rule: Rule) : FormatRegistration {\n return useFormatRegistry().register(rule);\n}\n\n/**\n * Remove a rule from the process-global registry by its id\n * (as returned by registerFormat). Built-in ids cannot be unregistered.\n */\nexport function unregisterFormat(id: string) : boolean {\n return useFormatRegistry().unregister(id);\n}\n\nexport async function read(input: LocatorInfo | string) : Promise<any> {\n return useFormatRegistry().read(input);\n}\n\nexport function readSync(input: LocatorInfo | string) : any {\n return useFormatRegistry().readSync(input);\n}\n\nexport async function write(input: LocatorInfo | string, value: unknown) : Promise<void> {\n return useFormatRegistry().write(input, value);\n}\n\nexport function writeSync(input: LocatorInfo | string, value: unknown) : void {\n useFormatRegistry().writeSync(input, value);\n}\n\n/**\n * Override the built-in module reader's `import` / `require` calls.\n *\n * Useful for test runners (e.g. Vitest) where the dynamic `import()` inside\n * `node_modules/locter` would bypass the runner's module graph. Calling this\n * from user code (e.g. a Vitest setup file) lets the runner rewrite the\n * `import()` so loaded modules share identity with statically imported ones.\n *\n * Returns a restore function that re-applies the previous configuration —\n * handy for scoped overrides (e.g. test teardown). The restore function is\n * scoped to the exact reader instance it configured: after a registry\n * reset() (which discards that instance) it becomes a no-op instead of\n * re-applying stale configuration to the fresh instance.\n *\n * @example\n * ```ts\n * // vitest setup file\n * import { setModuleReader } from 'locter';\n *\n * setModuleReader({\n * load: (id) => import(id),\n * });\n * ```\n */\nexport function setModuleReader(options: ModuleReaderOptions) : () => void {\n const reader = useFormatRegistry().builtInReader('module');\n const previous = reader.configure(options);\n\n return () => {\n reader.configure(previous);\n };\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { LocterError, LocterNotFoundError, LocterWriteError } from '../errors';\nimport type { LocatorInfo } from '../locator';\nimport {\n buildFilePath,\n locate,\n locateSync,\n locateUp,\n locateUpSync,\n} from '../locator';\nimport { hasOwnProperty, isObject, isSafeObjectKey } from '../utils';\nimport type { TwinBody } from '../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../utils/twin';\nimport { JSONWriter } from './built-in';\nimport { useFormatRegistry } from './registry';\n\nexport type ReadPackageFieldOptions = {\n cwd?: string,\n walkUp?: boolean,\n stopAt?: string,\n};\n\nexport type WritePackageFieldOptions = ReadPackageFieldOptions;\n\nfunction extractField<T>(pkg: unknown, field: string) : T | undefined {\n if (!isObject(pkg) || !hasOwnProperty(pkg, field)) {\n return undefined;\n }\n return pkg[field] as T;\n}\n\nfunction* locatePackageBody(\n options: ReadPackageFieldOptions,\n) : TwinBody<LocatorInfo | undefined> {\n if (options.walkUp) {\n return yield* op(\n () => locateUp('package.json', { cwd: options.cwd, stopAt: options.stopAt }),\n () => locateUpSync('package.json', { cwd: options.cwd, stopAt: options.stopAt }),\n );\n }\n\n return yield* op(\n () => locate('package.json', { cwd: options.cwd }),\n () => locateSync('package.json', { cwd: options.cwd }),\n );\n}\n\nfunction* readPackageFieldBody<T>(\n field: string,\n options: ReadPackageFieldOptions,\n) : TwinBody<T | undefined> {\n const info = yield* locatePackageBody(options);\n if (!info) {\n return undefined;\n }\n\n // Read the raw parsed package.json via the built-in JSON reader —\n // not the normalized record read() returns — so synthetic record\n // keys (`default`, `__esModule`) can never resolve as package fields.\n const reader = useFormatRegistry().builtInReader('json');\n const filePath = buildFilePath(info);\n\n try {\n const pkg = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n return extractField<T>(pkg, field);\n } catch (e) {\n if (e instanceof LocterNotFoundError) {\n return undefined;\n }\n throw e;\n }\n}\n\nexport async function readPackageField<T = unknown>(\n field: string,\n options: ReadPackageFieldOptions = {},\n) : Promise<T | undefined> {\n return runTwinAsync(readPackageFieldBody<T>(field, options));\n}\n\nexport function readPackageFieldSync<T = unknown>(\n field: string,\n options: ReadPackageFieldOptions = {},\n) : T | undefined {\n return runTwinSync(readPackageFieldBody<T>(field, options));\n}\n\nfunction* writePackageFieldBody(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions,\n) : TwinBody<void> {\n if (!isSafeObjectKey(field)) {\n throw new LocterError({ message: `The field ${field} is not a safe object key.` });\n }\n\n const info = yield* locatePackageBody(options);\n if (!info) {\n // unlike the reader, there is nothing sensible to return —\n // a write without a target is an error\n throw new LocterNotFoundError({ message: 'No package.json could be located.' });\n }\n\n const reader = useFormatRegistry().builtInReader('json');\n const filePath = buildFilePath(info);\n\n const pkg = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n if (!isObject(pkg)) {\n throw new LocterWriteError({\n message: 'The located package.json does not contain an object.',\n path: filePath,\n });\n }\n\n pkg[field] = value;\n\n // dedicated writer instance: keeps the indentation (and the built-in\n // registry writer's configuration untouched)\n const writer = new JSONWriter({ indent: 'auto' });\n yield* op(\n () => writer.write(filePath, pkg),\n () => writer.writeSync(filePath, pkg),\n );\n}\n\n/**\n * Set a top-level field of the nearest `package.json` (same locate\n * semantics as readPackageField) and write it back, preserving the\n * file's existing indentation. Passing `undefined` removes the field.\n * Throws LocterNotFoundError when no package.json could be located.\n */\nexport async function writePackageField(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : Promise<void> {\n return runTwinAsync(writePackageFieldBody(field, value, options));\n}\n\nexport function writePackageFieldSync(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : void {\n runTwinSync(writePackageFieldBody(field, value, options));\n}\n"],"mappings":";;;;;;;;;;;AAoBA,MAAa,sBAAsB,OAAO,IAAI,eAAe;AAE7D,IAAa,cAAb,cAAiC,UAAU;CACvC,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,mBAAmB;CACnD;CAEA;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,IAAI,OAAO,UAAU,UACjB,MAAM,KAAK;OACR;GACH,MAAM,EAAE,MAAM,GAAG,SAAS;GAC1B,MAAM,IAAI;GACV,KAAK,OAAO;EAChB;EAEA,eAAe,MAAM,mBAAmB;CAC5C;AACJ;;;AC9BA,MAAa,2BAA2B,OAAO,IAAI,oBAAoB;AAEvE,IAAa,kBAAb,cAAqC,YAAY;CAC7C,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,wBAAwB;CACxD;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,wBAAwB;CACjD;AACJ;;;ACXA,MAAa,gCAAgC,OAAO,IAAI,yBAAyB;AAEjF,IAAa,sBAAb,cAAyC,YAAY;CACjD,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,6BAA6B;CAC7D;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,6BAA6B;CACtD;AACJ;;;ACXA,MAAa,wCAAwC,OAAO,IAAI,iCAAiC;AAEjG,IAAa,8BAAb,cAAiD,YAAY;CACzD,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,qCAAqC;CACrE;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,qCAAqC;CAC9D;AACJ;;;ACrBA,SAAgB,eAAqE,KAAQ,MAAwC;CACjI,OAAO,OAAO,UAAU,eAAe,KAAK,KAAK,IAAI;AACzD;AAEA,SAAgB,kBAAwE,KAAQ,MAAuC;CACnI,OAAO,eAAe,KAAK,IAAI,KAAK,OAAO,IAAI,UAAU;AAC7D;;;ACCA,SAAgB,SAAS,MAA6C;CAClE,OACI,CAAC,CAAC,QACF,OAAO,SAAS,YAChB,CAAC,MAAM,QAAQ,IAAI;AAE3B;AAEA,SAAgB,gBAAgB,KAAuB;CACnD,OAAO,QAAQ,eACX,QAAQ,eACR,QAAQ;AAChB;;;ACZA,SAAgB,QAAQ,OAAqC;CACzD,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAChD;;;ACDA,SAAgB,WAAW,OAAe;CACtC,MAAM,YAAY,KAAK,QAAQ,KAAK;CACpC,OAAO,aAAa,cAAc;AACtC;;;ACJA,SAAgB,2BAAqC;CACjD,OAAO,QAAQ,OACX,QAAQ,IAAI,mBAAmB,KAAA;AACvC;AAEA,SAAgB,6BAAuC;CACnD,OAAO,OAAO,YAAY,eACtB,QAAQ,IAAI,WAAW;AAC/B;AAEA,SAAgB,6BAAsC;CAGlD,OAAO,CAAC,CAAC,QAAQ,OAAO,IAAI,2BAA2B;AAC3D;AAKA,MAAM,mBAAmB;AAEzB,SAAgB,0BAAoC;CAChD,IAAI,OAAO,YAAY,aACnB,OAAO;CAGX,IACI,MAAM,QAAQ,QAAQ,QAAQ,KAC9B,QAAQ,SAAS,MAAM,QAAQ,iBAAiB,KAAK,GAAG,CAAC,GAEzD,OAAO;CAGX,MAAM,EAAE,kBAAkB,mBAAmB;CAE7C,OAAO,MAAM,QAAQ,cAAc,KAC/B,eAAe,MAAM,OAAO,iBAAiB,KAAK,EAAE,CAAC;AAC7D;;;ACnCA,SAAgB,kBAAkB,OAAiC;CAC/D,IAAI,CAAC,SAAS,KAAK,GACf,OAAO;CAGX,IAAI,OAAO,MAAM,oBAAoB,aACjC,OAAO;CAGX,OAAO,OAAO,MAAM,YAAY,YAC5B,QAAQ,KAAK,MAAM,OAAO;AAClC;;;ACVA,MAAa,4BAA4B,OAAO,IAAI,qBAAqB;AAEzE,IAAa,mBAAb,cAAsC,YAAY;CAC9C,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,yBAAyB;CACzD;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,yBAAyB;CAClD;AACJ;;;ACRA,MAAM,kCAAkB,IAAI,IAAI;CAC5B;CACA;CACA;AACJ,CAAC;AAED,SAAgB,gBAAgB,OAAgB,MAA4B;CACxE,IAAI,iBAAiB,aACjB,OAAO;CAGX,MAAM,OAAO,SAAS,KAAK,KAAK,kBAAkB,OAAO,MAAM,IAC3D,MAAM,OACN,KAAA;CAEJ,MAAM,UAAU,SAAS,KAAK,KAAK,kBAAkB,OAAO,SAAS,IACjE,MAAM,UACN,mBAAmB;CAEvB,IAAI,QAAQ,gBAAgB,IAAI,IAAI,GAChC,OAAO,IAAI,oBAAoB;EAC3B;EACA;EACA,OAAO;EACP;CACJ,CAAC;CAGL,OAAO,IAAI,gBAAgB;EACvB;EACA;EACA,OAAO;EACP;CACJ,CAAC;AACL;AAEA,SAAgB,eAAe,OAAgB,MAA4B;CACvE,IAAI,iBAAiB,aACjB,OAAO;CAGX,MAAM,OAAO,SAAS,KAAK,KAAK,kBAAkB,OAAO,MAAM,IAC3D,MAAM,OACN,KAAA;CAMJ,OAAO,IAAI,iBAAiB;EACxB,SALY,SAAS,KAAK,KAAK,kBAAkB,OAAO,SAAS,IACjE,MAAM,UACN,oBAAoB;EAIpB;EACA,OAAO;EACP;CACJ,CAAC;AACL;;;;;;ACvCA,UAAiB,GACb,SACA,QAC2B;CAC3B,OAAO,MAAM;EAAE,OAAO;EAAS,MAAM;CAAO;AAChD;AAEA,eAAsB,aAAgB,MAAgC;CAClE,IAAI,OAAO,KAAK,KAAK;CACrB,OAAO,CAAC,KAAK,MAAM;EACf,IAAI;EACJ,IAAI;GACA,SAAS,MAAM,KAAK,MAAM,MAAM;EACpC,SAAS,GAAG;GACR,OAAO,KAAK,MAAM,CAAC;GACnB;EACJ;EAEA,OAAO,KAAK,KAAK,MAAM;CAC3B;CAEA,OAAO,KAAK;AAChB;AAEA,SAAgB,YAAe,MAAuB;CAClD,IAAI,OAAO,KAAK,KAAK;CACrB,OAAO,CAAC,KAAK,MAAM;EACf,IAAI;EACJ,IAAI;GACA,SAAS,KAAK,MAAM,KAAK;EAC7B,SAAS,GAAG;GACR,OAAO,KAAK,MAAM,CAAC;GACnB;EACJ;EAEA,OAAO,KAAK,KAAK,MAAM;CAC3B;CAEA,OAAO,KAAK;AAChB;;;ACzDA,SAAgB,qBAAqB,SAAuC;CACxE,OAAO,MAAM,QAAQ,OAAO,IACxB,UACA,CAAC,OAAO;AAChB;AAEA,SAAgB,oBAAoB,UAA+B,CAAC,GAAoB;CACpF,MAAM,MAAM,QAAQ,MAChB,QAAQ,QAAQ,GAAG,IACnB,CAAC;CAEL,MAAM,SAAS,QAAQ,SACnB,QAAQ,QAAQ,MAAM,IACtB,CAAC;CAEL,IAAI,IAAI,WAAW,GACf,IAAI,KAAK,QAAQ,IAAI,CAAC;CAK1B,MAAM,kBAAkB,QAAQ,mBAAmB;CAKnD,OAAO;EACH;EACA;EACA;EACA,WARc,kBACd,QACA,QAAQ,aAAa;EAOrB,KAAK,QAAQ,OAAO;CACxB;AACJ;AAEA,SAAgB,kBACZ,OACA,aACY;CACZ,IACI,CAAC,eACD,CAAC,KAAK,WAAW,KAAK,GAEtB,QAAQ,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;CAG7C,MAAM,OAAO,KAAK,MAAM,KAAK;CAC7B,MAAM,YAAY,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG;CACnD,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,KAAA;CACxC,MAAM,WAAW,YACb,KAAK,KAAK,WAAW,KAAK,IAAI,IAAI,YAClC,KAAK,KAAK,WAAW,KAAK,IAAI;CAElC,OAAO;EACH;EACA,MAAM,KAAK;EACX;EACA,MAAM;CACV;AACJ;AAEA,SAAgB,cACZ,OACqB;CACrB,OAAO,SAAS,KAAK,KACjB,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,SAAS,aACrB,OAAO,MAAM,cAAc,eAAe,OAAO,MAAM,cAAc,aACtE,OAAO,MAAM,SAAS;AAC9B;AAEA,SAAgB,cAAc,OAA6B;CACvD,IAAI,OAAO,UAAU,UACjB,OAAO;CAGX,OAAO,MAAM;AACjB;;;ACtEA,SAAS,cACL,SACA,SACU;CACV,MAAM,WAAW,qBAAqB,OAAO;CAC7C,MAAM,OAAO,oBAAoB,OAAO;CAExC,MAAM,OAAmB,CAAC;CAC1B,KAAK,MAAM,KAAK,UACZ,KAAK,MAAM,OAAO,KAAK,KACnB,KAAK,KAAK;EACN,SAAS;EACT,SAAS;GACL,UAAU;GACV;GACA,QAAQ,KAAK;GACb,WAAW,KAAK;GAChB,iBAAiB,KAAK;GACtB,KAAK,KAAK;EACd;CACJ,CAAC;CAIT,OAAO;AACX;AAEA,UAAU,KAAK,KAA8C;CACzD,OAAO,OAAO,SACJ,GAAG,IAAI,SAAS,IAAI,OAAO,SAC3B,GAAG,KAAK,IAAI,SAAS,IAAI,OAAO,CAC1C;AACJ;AAEA,UAAiB,WACb,SACA,SACkC;CAClC,KAAK,MAAM,OAAO,cAAc,SAAS,OAAO,GAAG;EAG/C,MAAM,WAAU,OAFK,KAAK,GAAG,EAAA,CAEP,MAAM;EAC5B,IAAI,SACA,OAAO,kBAAkB,SAAS,IAAI;CAE9C;AAGJ;AAEA,UAAiB,eACb,SACA,SACwB;CACxB,MAAM,QAAwB,CAAC;CAE/B,KAAK,MAAM,OAAO,cAAc,SAAS,OAAO,GAAG;EAC/C,MAAM,QAAQ,OAAO,KAAK,GAAG;EAE7B,KAAK,MAAM,QAAQ,OACf,MAAM,KAAK,kBAAkB,MAAM,IAAI,CAAC;CAEhD;CAEA,OAAO;AACX;;;ACxEA,eAAsB,WAClB,SACA,SACuB;CACvB,OAAO,aAAa,eAAe,SAAS,OAAO,CAAC;AACxD;AAEA,eAAsB,OAClB,SACA,SACiC;CACjC,OAAO,aAAa,WAAW,SAAS,OAAO,CAAC;AACpD;;;ACZA,SAAgB,eACZ,SACA,SACc;CACd,OAAO,YAAY,eAAe,SAAS,OAAO,CAAC;AACvD;AAEA,SAAgB,WACZ,SACA,SACwB;CACxB,OAAO,YAAY,WAAW,SAAS,OAAO,CAAC;AACnD;;;ACCA,SAAS,UAAU,SAA2C;CAC1D,MAAM,EACF,KACA,QACA,GAAG,gBACH;CACJ,MAAM,UAAU,KAAK,QAAQ,OAAO,QAAQ,IAAI,CAAC;CAKjD,OAAO;EACH;EACA,QANY,SACZ,KAAK,QAAQ,SAAS,MAAM,IAC5B,KAAK,MAAM,OAAO,CAAC,CAAC;EAKpB;CACJ;AACJ;AAEA,SAAS,cAAc,SAAiB,QAAqC;CACzE,IAAI,YAAY,QACZ;CAGJ,MAAM,SAAS,KAAK,QAAQ,OAAO;CACnC,IAAI,WAAW,SACX;CAGJ,OAAO;AACX;AAEA,UAAU,aACN,SACA,SACkC;CAClC,IAAI,OAAO,UAAU,OAAO;CAE5B,OAAO,MAAM;EACT,MAAM,QAAQ,OAAO,WAAW,SAAS;GAAE,GAAG,KAAK;GAAa,KAAK,KAAK;EAAQ,CAAC;EACnF,IAAI,OACA,OAAO;EAGX,MAAM,OAAO,cAAc,KAAK,SAAS,KAAK,MAAM;EACpD,IAAI,CAAC,MACD;EAGJ,OAAO;GAAE,GAAG;GAAM,SAAS;EAAK;CACpC;AACJ;AAEA,eAAsB,SAClB,SACA,UAAiC,CAAC,GACD;CACjC,OAAO,aAAa,aAAa,SAAS,OAAO,CAAC;AACtD;AAEA,SAAgB,aACZ,SACA,UAAiC,CAAC,GACV;CACxB,OAAO,YAAY,aAAa,SAAS,OAAO,CAAC;AACrD;;;;;;;;;ACrEA,IAAsB,iBAAtB,MAAwD;CAGpD,MAAM,KAAK,OAA8B;EACrC,OAAO,aAAa,KAAK,KAAK,KAAK,CAAC;CACxC;CAEA,SAAS,OAAqB;EAC1B,OAAO,YAAY,KAAK,KAAK,KAAK,CAAC;CACvC;CAEA,CAAW,KAAK,OAA+B;EAC3C,IAAI;GACA,MAAM,UAAU,OAAO,SACb,GAAG,SAAS,SAAS,OAAO,EAAE,UAAU,QAAQ,CAAC,SACjD,GAAG,aAAa,OAAO,EAAE,UAAU,QAAQ,CAAC,CACtD;GAEA,OAAO,KAAK,MAAM,OAAO;EAC7B,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,KAAK;EAClC;CACJ;AACJ;;;AC5BA,SAAS,WAAW,GAAsB;CACtC,OAAO,aAAa,SAAS,UAAU,KAAK,EAAE,SAAS;AAC3D;;;;;;;;AASA,IAAsB,iBAAtB,MAAwD;;;;;;;CAOpD,IAAc,sBAAgC;EAC1C,OAAO;CACX;CAIA,MAAM,MAAM,OAAe,OAAgC;EACvD,OAAO,aAAa,KAAK,KAAK,OAAO,KAAK,CAAC;CAC/C;CAEA,UAAU,OAAe,OAAuB;EAC5C,YAAY,KAAK,KAAK,OAAO,KAAK,CAAC;CACvC;CAEA,CAAW,KAAK,OAAe,OAAiC;EAC5D,MAAM,WAAW;EAEjB,IAAI;GACA,IAAI;GACJ,IAAI,KAAK,qBACL,WAAW,OAAO,SACR,GAAG,SAAS,SAAS,UAAU,EAAE,UAAU,QAAQ,CAAC,CAAC,CACtD,OAAO,MAAM;IACV,IAAI,WAAW,CAAC,GACZ;IAEJ,MAAM;GACV,CAAC,SACC;IACF,IAAI;KACA,OAAO,GAAG,aAAa,UAAU,EAAE,UAAU,QAAQ,CAAC;IAC1D,SAAS,GAAG;KACR,IAAI,WAAW,CAAC,GACZ;KAEJ,MAAM;IACV;GACJ,CACJ;GAGJ,IAAI,UAAU,KAAK,UAAU,OAAO,QAAQ;GAC5C,IAAI,CAAC,QAAQ,SAAS,IAAI,GACtB,WAAW;GAGf,MAAM,YAAY,KAAK,QAAQ,QAAQ;GACvC,OAAO,GACH,YAAY;IACR,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;GAC1D,SACM;IACF,GAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;GAC/C,CACJ;GAEA,OAAO,SACG,GAAG,SAAS,UAAU,UAAU,SAAS,EAAE,UAAU,QAAQ,CAAC,SAC9D,GAAG,cAAc,UAAU,SAAS,EAAE,UAAU,QAAQ,CAAC,CACnE;EACJ,SAAS,GAAG;GACR,MAAM,eAAe,GAAG,QAAQ;EACpC;CACJ;AACJ;;;AClFA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,UAAuC;EACzC,MAAM,SAA8B,CAAC;EAErC,MAAM,QAAQ,SAAS,MAAM,YAAY;EAEzC,KAAK,MAAM,QAAQ,OAAO;GACtB,MAAM,QAAQ,KAAK,MAAM,+BAA+B;GACxD,IAAI,CAAC,OACD;GAGJ,MAAM,MAAM,MAAM;GAClB,MAAM,WAAW,MAAM;GAEvB,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,GAC5B;GAGJ,MAAM,QAAQ,MAAM,WAAW,SAAS,KAAK,IAAI,EAAE;GAEnD,IAAI,IAAI,SAAS,IAAI,GAAG;IACpB,MAAM,SAAS,IAAI,MAAM,GAAG,KAAK,IAAI,GAAG,IAAI,SAAS,CAAC,CAAC;IACvD,OAAO,WAAW,OAAO,WAAW,CAAC,EAAA,CAAG,OAAO,KAAK;IACpD;GACJ;GAEA,OAAO,OAAO;EAClB;EAEA,OAAO,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;CAChD;AACJ;;;ACjCA,SAAS,eAAe,OAAyB;CAC7C,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACnE;;;;;;;;;AAUA,IAAa,aAAb,cAAgC,eAAe;CAC3C,UAAU,OAAyB;EAC/B,IAAI,CAAC,SAAS,KAAK,GACf,MAAM,IAAI,MAAM,kDAAkD;EAGtE,MAAM,OAAiC,QAAQ,OAAO,EAAE,MAAM,KAAK,CAAC;EAEpE,MAAM,QAAmB,CAAC;EAC1B,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAAG;GACjC,MAAM,QAAQ,KAAK;GACnB,IAAI,OAAO,UAAU,aACjB;GAGJ,IAAI,MAAM,QAAQ,KAAK,GAAG;IACtB,KAAK,MAAM,QAAQ,OACf,MAAM,KAAK,GAAG,IAAI,KAAK,eAAe,IAAI,GAAG;IAEjD;GACJ;GAEA,MAAM,KAAK,GAAG,IAAI,GAAG,eAAe,KAAK,GAAG;EAChD;EAEA,OAAO,MAAM,KAAK,IAAI;CAC1B;AACJ;;;AC3CA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,SAAiB;EACnB,OAAO,KAAK,MAAM,OAAO;CAC7B;AACJ;;;ACOA,SAAS,aAAa,SAAsC;CACxD,MAAM,QAAQ,eAAe,KAAK,OAAO;CACzC,OAAO,QAAQ,MAAM,KAAK,KAAA;AAC9B;AAEA,IAAa,aAAb,cAAgC,eAAe;CAC3C;CAEA,YAAY,UAA6B,CAAC,GAAG;EACzC,MAAM;EACN,KAAK,UAAU;CACnB;CAEA,IAAuB,sBAAgC;EACnD,OAAO,KAAK,QAAQ,WAAW;CACnC;CAEA,UAAU,OAAgB,UAA4B;EAClD,IAAI;EACJ,IAAI,KAAK,QAAQ,WAAW,QACxB,SAAS,WAAW,aAAa,QAAQ,IAAI,KAAA;OAE7C,SAAS,KAAK,QAAQ;EAG1B,SAAS,UAAU;EAEnB,MAAM,SAAS,KAAK,UAAU,OAAO,MAAM,MAAM;EACjD,IAAI,OAAO,WAAW,aAClB,MAAM,IAAI,MAAM,qCAAqC;EAGzD,OAAO;CACX;AACJ;;;;;;;AC3CA,MAAa,yBAAyB;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;;;ACsBnF,MAAM,UAAU,cAAc,OAAO,KAAK,GAAG;AAI7C,SAAS,aAAa,MAAqC;CACvD,OAAO,OAAO,SAAS,WAAW,OAAO,cAAc,IAAI;AAC/D;AAEA,SAAS,qBAAqB,OAA0B;CACpD,MAAM,aAAa,iBAAiB,cAAc,MAAM,QAAQ;CAChE,OAAO,sBAAsB,eACzB,sBAAsB,kBACtB,kBAAkB,UAAU;AACpC;AAEA,IAAa,eAAb,MAA6C;CACzC;CAEA;CAEA;CAEA,YAAY,UAA+B,CAAC,GAAG;EAG3C,KAAK,WAAW,WAAW,KAAA,GAAW,EAAE,YAAY,CAAC,GAAG,sBAAsB,EAAE,CAAC;EACjF,KAAK,SAAS,QAAQ;EACtB,KAAK,aAAa,QAAQ;CAC9B;;;;CAKA,UAAU,SAAoD;EAC1D,MAAM,WAAiC;GACnC,MAAM,KAAK;GACX,UAAU,KAAK;EACnB;EAEA,IAAI,UAAU,SACV,KAAK,SAAS,QAAQ;EAE1B,IAAI,cAAc,SACd,KAAK,aAAa,QAAQ;EAG9B,OAAO;CACX;;;;;;;;;;;;;;CAeA,MAAM,KAAK,OAAe;EACtB,IAAI;GACA,OAAO,MAAM,KAAK,KAAK,KAAK;EAChC,SAAS,GAAG;GACR,IAAI,qBAAqB,CAAC,GACtB,MAAM;GAKV,IAAI,2BAA2B,GAC3B,OAAO,KAAK,SAAS,KAAK;GAG9B,OAAO,KAAK,SAAS,KAAK;EAC9B;CACJ;CAEA,SAAS,OAAe;EACpB,IAAI;GACA,OAAO,KAAK,SAAS,KAAK;EAC9B,SAAS,GAAG;GACR,IAAI,qBAAqB,CAAC,GACtB,MAAM;GAGV,OAAO,KAAK,SAAS,KAAK;EAC9B;CACJ;CAIA,MAAM,KACF,MACA,UAA6B,CAAC,GACb;EACjB,MAAM,KAAK,KAAK,MAAM,MAAM,OAAO;EAEnC,IAAI;GACA,IAAI,KAAK,QACL,OAAO,MAAM,KAAK,OAAO,EAAE;GAK/B,IAAI,yBAAyB,GACzB,OAAO,QAAQ,EAAE;GAGrB,OAAO,MAAM,OAAO;EACxB,SAAS,GAAG;;GAER,IACI,CAAC,QAAQ,kBACT,SAAS,CAAC,KACV,kBAAkB,GAAG,MAAM,MAEvB,EAAE,SAAS,oCACX,EAAE,SAAS,+BAGf,OAAO,KAAK,KAAK,MAAM;IACnB,GAAG;IACH,gBAAgB;GACpB,CAAC;GAGL,MAAM,gBAAgB,GAAG,aAAa,IAAI,CAAC;EAC/C;CACJ;CAEA,SACI,MACA,UAA6B,CAAC,GACtB;EACR,MAAM,KAAK,KAAK,MAAM,MAAM,OAAO;EAEnC,IAAI;GACA,IAAI,KAAK,YACL,OAAO,KAAK,WAAW,EAAE;GAG7B,OAAO,QAAQ,EAAE;EACrB,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,aAAa,IAAI,CAAC;EAC/C;CACJ;CAEA,MACI,MACA,UAA6B,CAAC,GACvB;EACP,IAAI,cAAc,IAAI,KAAK,WAAW,IAAI,GAAG;GACzC,IAAI,OAAO,SAAS,UAChB,OAAO,cAAc,IAAI;GAG7B,IAAI,QAAQ,gBACR,OAAO,cAAc,IAAI,CAAC,CAAC;EAEnC;EAEA,OAAO;CACX;AACJ;;;;;;;;;ACrLA,MAAM,gBAAgB,OAAO,eAAe;;;;;;AAO5C,SAAgB,eAAe,OAA+C;CAC1E,OAAO,SAAS,KAAK,KAAK,iBAAiB;AAC/C;AAEA,SAAS,MAAS,OAAc;CAC5B,IAAI,SAAS,KAAK,KAAK,OAAO,aAAa,KAAK,GAC5C,OAAO,eAAe,OAAO,eAAe,EAAE,OAAO,KAAK,CAAC;CAG/D,OAAO;AACX;;;;;;;AAQA,SAAgB,WAAW,OAAoC;CAC3D,OAAO,SAAS,KAAK,KACjB,OAAO,MAAM,eAAe;AACpC;;;;;AAMA,SAAgB,mBAAmB,MAAe;CAC9C,MAAM,SAAS,OAAO,OAAO,MAAM;EAC/B,YAAY,EAAE,OAAO,KAAK;GACzB,OAAO,cAAc,EAAE,OAAO,SAAS;GACvC,gBAAgB,EAAE,OAAO,KAAK;CACnC,CAAC;CAED,IAAI,SAAS,IAAI,GACb,KAAK,MAAM,OAAO,MAAM;EACpB,IAAI,eAAe,QAAQ,GAAG,GAC1B;EAGJ,IAAI,aAAa,OAAO,yBAAyB,MAAM,GAAG;EAC1D,IACI,CAAC,cACA,SAAS,cAAc,WAAW,YAAY,WAAW,cAE1D,aAAa;GACT,YAAY;GACZ,MAAM;IACF,OAAO,KAAK;GAChB;EACJ;EAGJ,OAAO,eAAe,QAAQ,KAAK,UAAU;CACjD;CAGJ,IAAI,CAAC,eAAe,QAAQ,SAAS,GACjC,OAAO,eAAe,QAAQ,WAAW;EACrC,OAAO;EACP,YAAY;CAChB,CAAC;CAGL,OAAO,OAAO,OAAO,MAAM;AAC/B;;;;;;;;AASA,SAAgB,eACZ,MACF;CACE,IAAI,WAAW,IAAI,GAAG;EAGlB,IACI,WAAW,KAAK,OAAO,KACvB,KAAK,QAAQ,SAEb,OAAO,MAAM;GACT,GAAG;GACH,SAAS,KAAK,QAAQ;EAC1B,CAAC;EAKL,OAAO,MAAM,IAAI;CACrB;CAEA,OAAO,mBAAmB,IAAI;AAClC;AAEA,SAAgB,gBACZ,MACA,UACwB;CACxB,MAAM,OAAO,OAAO,KAAK,IAAI;CAC7B,KAAK,MAAM,OAAO,MACd,IAAI,SAAS,KAAe,KAAK,IAAc,GAC3C,OAAO;EACE;EACL,OAAO,KAAK;CAChB;AAKZ;;;AChIA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,SAAiB;EACnB,OAAOA,MAAU,OAAO;CAC5B;AACJ;;;ACMA,SAAS,QAAQ,KAAuB;CACpC,OAAO,SAAS,GAAG,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,GAAG;AACzD;;;;;;;;AASA,SAAS,SAAS,KAAe,MAAe,OAAuC;CACnF,KAAK,MAAM,QAAQ,CAAC,GAAG,KAAK,KAAK,GAC7B,IAAI,CAAC,eAAe,OAAO,QAAQ,KAAK,GAAG,CAAC,GACxC,KAAK,OAAO,KAAK,GAAG;CAI5B,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EAClC,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI;EAElC,IAAI,MAAM,OAAO,KAAK,SAAS,KAAK,GAAG;GACnC,SAAS,KAAK,SAAS,KAAK;GAC5B;EACJ;EAEA,MAAM,cAAc,IAAI,WAAW,KAAK;EACxC,IAAI,OAAO,OAAO,GAAG;GAGjB,YAAY,gBAAgB,QAAQ;GACpC,YAAY,UAAU,QAAQ;GAC9B,YAAY,cAAc,QAAQ;EACtC;EAEA,KAAK,IAAI,IAAI,WAAW,GAAG,GAAG,WAAW;CAC7C;AACJ;;;;;;;;;AAUA,IAAa,aAAb,cAAgC,eAAe;CAC3C;CAEA,YAAY,UAA6B,CAAC,GAAG;EACzC,MAAM;EACN,KAAK,UAAU;CACnB;CAEA,IAAuB,sBAAgC;EACnD,OAAO;CACX;CAEA,UAAU,OAAgB,UAA4B;EAClD,IAAI,OAAO,aAAa,aACpB,OAAOC,UAAc,OAAO,KAAK,OAAO;EAK5C,MAAM,MAAiB,cAAc,QAAQ;EAC7C,IAAI,IAAI,OAAO,SAAS,GACpB,MAAM,IAAI,OAAO;EAGrB,IAAI,MAAM,IAAI,QAAQ,KAAK,SAAS,KAAK,GACrC,SAAS,KAAK,IAAI,UAAU,KAAK;OAEjC,IAAI,WAAW,IAAI,WAAW,KAAK;EAGvC,OAAO,IAAI,SAAS,KAAK,OAAO;CACpC;AACJ;;;;;;;;;;;AC7EA,MAAa,mBAAmB;CAC5B,QAAQ;EAAE,YAAY;EAAwB,cAAc,IAAI,aAAa;CAAE;CAC/E,MAAM;EACF,YAAY,CAAC,OAAO;EACpB,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;CACA,MAAM;EACF,YAAY,CAAC,OAAO;EACpB,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;CACA,MAAM;EACF,YAAY,CAAC,QAAQ,OAAO;EAC5B,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;AACJ;;;ACgBA,SAAS,YAAe,MAAyD;CAC7E,IAAI,OAAO,SAAS,aAChB;CAGJ,IAAI,OAAO,SAAS,YAChB,aAAa;CAGjB,MAAM,UAAU;CAChB,IAAI;CACJ,aAAa;EACT,IAAI,CAAC,QACD,SAAS,QAAQ;EAGrB,OAAO;CACX;AACJ;AAEA,IAAa,iBAAb,MAA4B;;;;CAIxB;;;;CAKA;;;;CAKA;;;;CAKA;CAEA;CAEA,YAAY,UAAiC,CAAC,GAAG;EAC7C,KAAK,QAAQ,CAAC;EACd,KAAK,qCAAqB,IAAI,IAAI;EAClC,KAAK,qCAAqB,IAAI,IAAI;EAClC,KAAK,oCAAoB,IAAI,IAAI;EACjC,KAAK,cAAc;EAEnB,MAAM,MAAM,OAAO,KAAK,gBAAgB;EACxC,KAAK,MAAM,MAAM,KACb,KAAK,MAAM,aAAa,iBAAiB,GAAG,CAAC,YAAY;GACrD,MAAM,WAAW,KAAK,kBAAkB,IAAI,SAAS;GACrD,IAAI,UACA,MAAM,IAAI,YAAY,EAAE,SAAS,aAAa,UAAU,uCAAuC,SAAS,IAAI,GAAG,GAAG,CAAC;GAGvH,KAAK,kBAAkB,IAAI,WAAW,EAAE;EAC5C;EAGJ,IAAI,QAAQ,OACR,KAAK,MAAM,QAAQ,QAAQ,OACvB,KAAK,SAAS,IAAI;CAG9B;CAEA,SAAS,MAAiC;EACtC,IACI,OAAO,KAAK,OAAO,eACnB,eAAe,kBAAkB,KAAK,EAAE,GAExC,MAAM,IAAI,YAAY,EAAE,SAAS,UAAU,KAAK,GAAG,oCAAoC,CAAC;EAG5F,IACI,OAAO,KAAK,WAAW,eACvB,OAAO,KAAK,WAAW,aAEvB,MAAM,IAAI,YAAY,EAAE,SAAS,mDAAmD,CAAC;EAGzF,MAAM,KAAK,KAAK,MAAM,KAAK,eAAe;EAC1C,MAAM,QAAQ,KAAK,QAAQ,IAAI,IAAI;EAEnC,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,UAAU,IACV,KAAK,MAAM,KAAK,KAAK;OAGrB,KAAK,MAAM,SAAS;EAGxB,OAAO;GACH;GACA,MAAM,KAAK;GACX,SAAS;EACb;CACJ;;;;;CAMA,WAAW,IAAsB;EAC7B,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,UAAU,IACV,OAAO;EAGX,KAAK,MAAM,OAAO,OAAO,CAAC;EAC1B,OAAO;CACX;CAEA,IAAI,IAAsB;EACtB,IAAI,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE,GACxC,OAAO;EAGX,OAAO,eAAe,kBAAkB,EAAE;CAC9C;;;;;CAMA,UAAiC;EAC7B,MAAM,SAAgC,KAAK,MAAM,KAC5C,UAAU;GACP,IAAI,KAAK;GACT,MAAM,KAAK;GACX,SAAS;EACb,EACJ;EAEA,MAAM,MAAM,OAAO,KAAK,gBAAgB;EACxC,KAAK,MAAM,MAAM,KACb,OAAO,KAAK;GACR;GACA,MAAM,CAAC,GAAG,iBAAiB,GAAG,CAAC,UAAU;GACzC,SAAS;EACb,CAAC;EAGL,OAAO;CACX;;;;;;CAOA,QAAe;EACX,KAAK,QAAQ,CAAC;EACd,KAAK,mBAAmB,MAAM;EAC9B,KAAK,mBAAmB,MAAM;EAC9B,KAAK,cAAc;CACvB;CAEA,MAAM,KAAK,OAA4C;EACnD,OAAO,aAAa,KAAK,SAAS,KAAK,CAAC;CAC5C;CAEA,SAAS,OAAmC;EACxC,OAAO,YAAY,KAAK,SAAS,KAAK,CAAC;CAC3C;;;;CAKA,CAAW,SAAS,OAA6C;EAC7D,MAAM,WAAW,cAAc,KAAK;EACpC,MAAM,SAAS,KAAK,WAAW,QAAQ;EACvC,IAAI,CAAC,QACD,MAAM,KAAK,sBAAsB,QAAQ;EAG7C,IAAI;GACA,MAAM,SAAS,OAAO,SACZ,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC;GAEA,OAAO,KAAK,SAAS,QAAQ,MAAM;EACvC,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,QAAQ;EACrC;CACJ;CAEA,MAAM,MAAM,OAA6B,OAAgC;EACrE,OAAO,aAAa,KAAK,UAAU,OAAO,KAAK,CAAC;CACpD;CAEA,UAAU,OAA6B,OAAuB;EAC1D,YAAY,KAAK,UAAU,OAAO,KAAK,CAAC;CAC5C;;;;;;;CAQA,CAAW,UAAU,OAA6B,OAAiC;EAC/E,MAAM,WAAW,cAAc,KAAK;EACpC,IAAI,CAAC,WAAW,QAAQ,GACpB,MAAM,IAAI,iBAAiB;GACvB,SAAS,4CAA4C;GACrD,MAAM;EACV,CAAC;EAGL,MAAM,SAAS,KAAK,WAAW,QAAQ;EACvC,IAAI,CAAC,QAAQ;GACT,IAAI,KAAK,WAAW,QAAQ,GAExB,MAAM,IAAI,iBAAiB;IACvB,SAAS,2BAFA,kBAAkB,QAEY,CAAC,CAAC,UAAU;IACnD,MAAM;GACV,CAAC;GAGL,MAAM,KAAK,sBAAsB,QAAQ;EAC7C;EAEA,MAAM,QAAQ,eAAe,KAAK,IAAI,MAAM,UAAU;EAEtD,IAAI;GACA,OAAO,SACG,OAAO,MAAM,UAAU,KAAK,SAC5B,OAAO,UAAU,UAAU,KAAK,CAC1C;EACJ,SAAS,GAAG;GACR,MAAM,eAAe,GAAG,QAAQ;EACpC;CACJ;;;;;;;;;CAUA,SAAmB,QAAiB,QAAuB;EACvD,IAAI,kBAAkB,cAClB,OAAO,eAAe,MAAM;EAGhC,OAAO,mBAAmB,MAAM;CACpC;;;;CAKA,cAAyC,IAA4B;EACjE,IAAI,SAAS,KAAK,mBAAmB,IAAI,EAAE;EAC3C,IAAI,CAAC,QAAQ;GACT,SAAS,iBAAiB,GAAG,CAAC,OAAO;GACrC,KAAK,mBAAmB,IAAI,IAAI,MAAM;EAC1C;EAEA,OAAO;CACX;;;;;;CAOA,cAAiD,IAA4B;EACzE,IAAI,SAAS,KAAK,mBAAmB,IAAI,EAAE;EAC3C,IAAI,CAAC,QAAQ;GACT,SAAS,iBAAiB,GAAG,CAAC,OAAO;GACrC,KAAK,mBAAmB,IAAI,IAAI,MAAM;EAC1C;EAEA,OAAO;CACX;;;;;;;;CASA,WAAW,OAAqC;EAC5C,IAAI,CAAC,WAAW,KAAK,GACjB,OAAO,KAAK,cAAc,QAAQ;EAGtC,MAAM,OAAO,KAAK,SAAS,QAAQ,SAAS,OAAO,KAAK,cAAc,WAAW;EACjF,IAAI,QAAQ,KAAK,WACb,OAAO,KAAK,UAAU;EAG1B,MAAM,KAAK,KAAK,cAAc,KAAK;EACnC,IAAI,IACA,OAAO,KAAK,cAAc,EAAE;CAIpC;;;;;;CAOA,WAAW,OAAqC;EAC5C,IAAI,CAAC,WAAW,KAAK,GACjB;EAGJ,MAAM,OAAO,KAAK,SAAS,QAAQ,SAAS,OAAO,KAAK,cAAc,WAAW;EACjF,IAAI,QAAQ,KAAK,WACb,OAAO,KAAK,UAAU;EAG1B,MAAM,KAAK,KAAK,cAAc,KAAK;EACnC,IAAI,MAAM,YAAY,iBAAiB,KACnC,OAAO,KAAK,cAAc,EAA6B;CAI/D;CAEA,SACI,OACA,QACyB;EACzB,MAAM,OAAO,kBAAkB,KAAK;EAEpC,KAAK,MAAM,QAAQ,KAAK,OAAO;GAC3B,IAAI,CAAC,OAAO,IAAI,GACZ;GAGJ,MAAM,EAAE,SAAS;GACjB,IAAI,MAAM,QAAQ,IAAI;QAEd,KAAK,aACL,KAAK,SAAS,KAAK,SAAS,GAE5B,OAAO;GAAA,OAER;IAIH,KAAK,YAAY;IACjB,MAAM,UAAU,KAAK,KAAK,cAAc,IAAI,CAAC;IAC7C,KAAK,YAAY;IACjB,IAAI,SACA,OAAO;GAEf;EACJ;CAGJ;CAEA,cAAwB,OAA6C;EACjE,MAAM,OAAO,kBAAkB,KAAK;EACpC,IAAI,CAAC,KAAK,WACN;EAGJ,OAAO,KAAK,kBAAkB,IAAI,KAAK,SAAS;CACpD;CAEA,sBAAgC,OAA6C;EAEzE,OAAO,IAAI,4BAA4B;GACnC,SAAS,uCAFA,kBAAkB,KAEwB,CAAC,CAAC,aAAa;GAClE,MAAM;EACV,CAAC;CACL;CAEA,QAAkB,IAAY,MAA2B;EACrD,OAAO;GACH;GACA,MAAM,KAAK;GACX,WAAW,YAAqB,KAAK,MAAM;GAC3C,WAAW,YAAqB,KAAK,MAAM;EAC/C;CACJ;CAEA,iBAAoC;EAChC,IAAI;EACJ,GAAG;GACC,KAAK;GACL,KAAK,QAAQ,KAAK;EACtB,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;EAEjD,OAAO;CACX;AACJ;;;AChcA,IAAI;AACJ,SAAgB,oBAAoB;CAChC,IAAI,OAAO,aAAa,aACpB,OAAO;CAGX,WAAW,IAAI,eAAe;CAE9B,OAAO;AACX;;;ACHA,SAAgB,eAAe,MAAiC;CAC5D,OAAO,kBAAkB,CAAC,CAAC,SAAS,IAAI;AAC5C;;;;;AAMA,SAAgB,iBAAiB,IAAsB;CACnD,OAAO,kBAAkB,CAAC,CAAC,WAAW,EAAE;AAC5C;AAEA,eAAsB,KAAK,OAA4C;CACnE,OAAO,kBAAkB,CAAC,CAAC,KAAK,KAAK;AACzC;AAEA,SAAgB,SAAS,OAAmC;CACxD,OAAO,kBAAkB,CAAC,CAAC,SAAS,KAAK;AAC7C;AAEA,eAAsB,MAAM,OAA6B,OAAgC;CACrF,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,KAAK;AACjD;AAEA,SAAgB,UAAU,OAA6B,OAAuB;CAC1E,kBAAkB,CAAC,CAAC,UAAU,OAAO,KAAK;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,gBAAgB,SAA2C;CACvE,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,QAAQ;CACzD,MAAM,WAAW,OAAO,UAAU,OAAO;CAEzC,aAAa;EACT,OAAO,UAAU,QAAQ;CAC7B;AACJ;;;AC5CA,SAAS,aAAgB,KAAc,OAA+B;CAClE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,eAAe,KAAK,KAAK,GAC5C;CAEJ,OAAO,IAAI;AACf;AAEA,UAAU,kBACN,SACkC;CAClC,IAAI,QAAQ,QACR,OAAO,OAAO,SACJ,SAAS,gBAAgB;EAAE,KAAK,QAAQ;EAAK,QAAQ,QAAQ;CAAO,CAAC,SACrE,aAAa,gBAAgB;EAAE,KAAK,QAAQ;EAAK,QAAQ,QAAQ;CAAO,CAAC,CACnF;CAGJ,OAAO,OAAO,SACJ,OAAO,gBAAgB,EAAE,KAAK,QAAQ,IAAI,CAAC,SAC3C,WAAW,gBAAgB,EAAE,KAAK,QAAQ,IAAI,CAAC,CACzD;AACJ;AAEA,UAAU,qBACN,OACA,SACwB;CACxB,MAAM,OAAO,OAAO,kBAAkB,OAAO;CAC7C,IAAI,CAAC,MACD;CAMJ,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,MAAM;CACvD,MAAM,WAAW,cAAc,IAAI;CAEnC,IAAI;EAMA,OAAO,aAAgB,OALJ,SACT,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC,GAE4B,KAAK;CACrC,SAAS,GAAG;EACR,IAAI,aAAa,qBACb;EAEJ,MAAM;CACV;AACJ;AAEA,eAAsB,iBAClB,OACA,UAAmC,CAAC,GACb;CACvB,OAAO,aAAa,qBAAwB,OAAO,OAAO,CAAC;AAC/D;AAEA,SAAgB,qBACZ,OACA,UAAmC,CAAC,GACtB;CACd,OAAO,YAAY,qBAAwB,OAAO,OAAO,CAAC;AAC9D;AAEA,UAAU,sBACN,OACA,OACA,SACe;CACf,IAAI,CAAC,gBAAgB,KAAK,GACtB,MAAM,IAAI,YAAY,EAAE,SAAS,aAAa,MAAM,4BAA4B,CAAC;CAGrF,MAAM,OAAO,OAAO,kBAAkB,OAAO;CAC7C,IAAI,CAAC,MAGD,MAAM,IAAI,oBAAoB,EAAE,SAAS,oCAAoC,CAAC;CAGlF,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,MAAM;CACvD,MAAM,WAAW,cAAc,IAAI;CAEnC,MAAM,MAAM,OAAO,SACT,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC;CAEA,IAAI,CAAC,SAAS,GAAG,GACb,MAAM,IAAI,iBAAiB;EACvB,SAAS;EACT,MAAM;CACV,CAAC;CAGL,IAAI,SAAS;CAIb,MAAM,SAAS,IAAI,WAAW,EAAE,QAAQ,OAAO,CAAC;CAChD,OAAO,SACG,OAAO,MAAM,UAAU,GAAG,SAC1B,OAAO,UAAU,UAAU,GAAG,CACxC;AACJ;;;;;;;AAQA,eAAsB,kBAClB,OACA,OACA,UAAoC,CAAC,GACvB;CACd,OAAO,aAAa,sBAAsB,OAAO,OAAO,OAAO,CAAC;AACpE;AAEA,SAAgB,sBACZ,OACA,OACA,UAAoC,CAAC,GAChC;CACL,YAAY,sBAAsB,OAAO,OAAO,OAAO,CAAC;AAC5D"}
1
+ {"version":3,"file":"index.mjs","names":["parseYAML","stringifyYAML"],"sources":["../src/errors/base.ts","../src/errors/load.ts","../src/errors/not-found.ts","../src/errors/unknown-extension.ts","../src/utils/has-property.ts","../src/utils/object.ts","../src/utils/to-array.ts","../src/utils/file-path.ts","../src/utils/runtime.ts","../src/utils/typescript.ts","../src/errors/write.ts","../src/errors/wrap.ts","../src/utils/twin.ts","../src/locator/utils.ts","../src/locator/core.ts","../src/locator/async.ts","../src/locator/sync.ts","../src/locator/up.ts","../src/format/text-file/reader.ts","../src/format/text-file/writer.ts","../src/format/built-in/conf/reader.ts","../src/format/built-in/conf/writer.ts","../src/format/built-in/json/reader.ts","../src/format/built-in/json/writer.ts","../src/format/built-in/module/constants.ts","../src/format/built-in/module/reader.ts","../src/format/built-in/module/utils.ts","../src/format/built-in/yaml/reader.ts","../src/format/built-in/yaml/writer.ts","../src/format/built-in/registry.ts","../src/format/registry/module.ts","../src/format/registry/singleton.ts","../src/format/helpers.ts","../src/format/package-field.ts"],"sourcesContent":["/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n BaseError,\n type ErrorOptions,\n hasInstanceof,\n markInstanceof,\n} from '@ebec/core';\n\nexport type LocterErrorOptions = ErrorOptions & {\n path?: string,\n};\n\nexport type LocterErrorInput = string | LocterErrorOptions;\n\nexport const LOCTER_ERROR_MARKER = Symbol.for('@locter/error');\n\nexport class LocterError extends BaseError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_ERROR_MARKER);\n }\n\n public readonly path?: string;\n\n constructor(input: LocterErrorInput = {}) {\n if (typeof input === 'string') {\n super(input);\n } else {\n const { path, ...rest } = input;\n super(rest);\n this.path = path;\n }\n\n markInstanceof(this, LOCTER_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_LOAD_ERROR_MARKER = Symbol.for('@locter/load-error');\n\nexport class LocterLoadError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_LOAD_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_LOAD_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for('@locter/not-found-error');\n\nexport class LocterNotFoundError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_NOT_FOUND_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_NOT_FOUND_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for('@locter/unknown-extension-error');\n\nexport class LocterUnknownExtensionError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);\n }\n}\n","export function hasOwnProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, unknown> {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\nexport function hasStringProperty<X extends Record<string, any>, Y extends PropertyKey>(obj: X, prop: Y): obj is X & Record<Y, string> {\n return hasOwnProperty(obj, prop) && typeof obj[prop] === 'string';\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isObject(item: unknown) : item is Record<string, any> {\n return (\n !!item &&\n typeof item === 'object' &&\n !Array.isArray(item)\n );\n}\n\nexport function isSafeObjectKey(key: string) : boolean {\n return key !== '__proto__' &&\n key !== 'prototype' &&\n key !== 'constructor';\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function toArray(input: string | string[]) : string[] {\n return Array.isArray(input) ? input : [input];\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\nimport path from 'node:path';\n\nexport function isFilePath(input: string) {\n const extension = path.extname(input);\n return extension && extension !== '';\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nexport function isJestRuntimeEnvironment() : boolean {\n return process.env &&\n process.env.JEST_WORKER_ID !== undefined;\n}\n\nexport function isVitestRuntimeEnvironment() : boolean {\n return typeof process !== 'undefined' &&\n process.env.VITEST === 'true';\n}\n\nexport function isTsNodeRuntimeEnvironment(): boolean {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n return !!process[Symbol.for('ts-node.register.instance')];\n}\n\n// matches the bare `tsx` specifier (node --import tsx), optionally with a\n// subpath (tsx/esm), as well as resolved paths into the tsx package\n// (.../node_modules/tsx/dist/loader.mjs)\nconst TSX_MARKER_REGEX = /(?:^|=|[\\\\/])tsx(?:$|[\\\\/])/;\n\nexport function isTsxRuntimeEnvironment() : boolean {\n if (typeof process === 'undefined') {\n return false;\n }\n\n if (\n Array.isArray(process.execArgv) &&\n process.execArgv.some((arg) => TSX_MARKER_REGEX.test(arg))\n ) {\n return true;\n }\n\n const { _preload_modules: preloadModules } = process as unknown as { _preload_modules?: string[] };\n\n return Array.isArray(preloadModules) &&\n preloadModules.some((el) => TSX_MARKER_REGEX.test(el));\n}\n","/*\n * Copyright (c) 2024.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { isObject } from './object';\n\nexport function isTypeScriptError(input: unknown) : input is Error {\n if (!isObject(input)) {\n return false;\n }\n\n if (typeof input.diagnosticCodes !== 'undefined') {\n return true;\n }\n\n return typeof input.message === 'string' &&\n /TS\\d+/.test(input.message);\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasInstanceof, markInstanceof } from '@ebec/core';\nimport { LocterError, type LocterErrorInput } from './base';\n\nexport const LOCTER_WRITE_ERROR_MARKER = Symbol.for('@locter/write-error');\n\nexport class LocterWriteError extends LocterError {\n static override [Symbol.hasInstance](input: unknown) : boolean {\n return hasInstanceof(input, LOCTER_WRITE_ERROR_MARKER);\n }\n\n constructor(input: LocterErrorInput = {}) {\n super(input);\n markInstanceof(this, LOCTER_WRITE_ERROR_MARKER);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasStringProperty, isObject } from '../utils';\nimport { LocterError } from './base';\nimport { LocterLoadError } from './load';\nimport { LocterNotFoundError } from './not-found';\nimport { LocterWriteError } from './write';\n\nconst NOT_FOUND_CODES = new Set([\n 'ENOENT',\n 'MODULE_NOT_FOUND',\n 'ERR_MODULE_NOT_FOUND',\n]);\n\nexport function wrapLoaderError(input: unknown, path: string) : LocterError {\n if (input instanceof LocterError) {\n return input;\n }\n\n const code = isObject(input) && hasStringProperty(input, 'code') ?\n input.code :\n undefined;\n\n const message = isObject(input) && hasStringProperty(input, 'message') ?\n input.message :\n `Failed to load: ${path}`;\n\n if (code && NOT_FOUND_CODES.has(code)) {\n return new LocterNotFoundError({\n message,\n code,\n cause: input,\n path,\n });\n }\n\n return new LocterLoadError({\n message,\n code,\n cause: input,\n path,\n });\n}\n\nexport function wrapWriteError(input: unknown, path: string) : LocterError {\n if (input instanceof LocterError) {\n return input;\n }\n\n const code = isObject(input) && hasStringProperty(input, 'code') ?\n input.code :\n undefined;\n\n const message = isObject(input) && hasStringProperty(input, 'message') ?\n input.message :\n `Failed to write: ${path}`;\n\n return new LocterWriteError({\n message,\n code,\n cause: input,\n path,\n });\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * Internal protocol to derive the parallel sync + async public surfaces\n * from one shared body. A body is a generator that yields effect pairs —\n * an async and a sync thunk for the same operation — and the two drivers\n * (runTwinAsync / runTwinSync) execute the side they stand for. Effect\n * errors are re-entered into the body via `Generator.throw`, so try/catch\n * inside a body behaves identically in both variants.\n *\n * Deliberately NOT exported from the utils barrel — this is internal\n * plumbing, not public API.\n */\n\nexport type TwinOp<T = unknown> = {\n async: () => Promise<T>,\n sync: () => T,\n};\n\nexport type TwinBody<R> = Generator<TwinOp<any>, R, any>;\n\n/**\n * Perform one effect inside a twin body: `const x = yield* op(a, s)`.\n */\nexport function* op<T>(\n asyncFn: () => Promise<T>,\n syncFn: () => T,\n) : Generator<TwinOp<T>, T, T> {\n return yield { async: asyncFn, sync: syncFn };\n}\n\nexport async function runTwinAsync<R>(body: TwinBody<R>) : Promise<R> {\n let step = body.next();\n while (!step.done) {\n let result : unknown;\n try {\n result = await step.value.async();\n } catch (e) {\n step = body.throw(e);\n continue;\n }\n\n step = body.next(result);\n }\n\n return step.value;\n}\n\nexport function runTwinSync<R>(body: TwinBody<R>) : R {\n let step = body.next();\n while (!step.done) {\n let result : unknown;\n try {\n result = step.value.sync();\n } catch (e) {\n step = body.throw(e);\n continue;\n }\n\n step = body.next(result);\n }\n\n return step.value;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport path from 'node:path';\nimport { isObject, toArray } from '../utils';\nimport type { LocatorInfo, LocatorOptions, LocatorOptionsInput } from './types';\n\nexport function buildLocatorPatterns(pattern: string | string[]) : string[] {\n return Array.isArray(pattern) ?\n pattern :\n [pattern];\n}\n\nexport function buildLocatorOptions(options: LocatorOptionsInput = {}) : LocatorOptions {\n const cwd = options.cwd ?\n toArray(options.cwd) :\n [];\n\n const ignore = options.ignore ?\n toArray(options.ignore) :\n [];\n\n if (cwd.length === 0) {\n cwd.push(process.cwd());\n }\n\n // precedence: an explicit `onlyDirectories: true` wins over `onlyFiles`\n // (which defaults to true); when neither restricts, everything matches\n const onlyDirectories = options.onlyDirectories ?? false;\n const onlyFiles = onlyDirectories ?\n false :\n options.onlyFiles ?? true;\n\n return {\n cwd,\n ignore,\n onlyDirectories,\n onlyFiles,\n dot: options.dot ?? false,\n };\n}\n\nexport function pathToLocatorInfo(\n input: string,\n skipResolve?: boolean,\n) : LocatorInfo {\n if (\n !skipResolve &&\n !path.isAbsolute(input)\n ) {\n input = path.resolve(process.cwd(), input);\n }\n\n const info = path.parse(input);\n const directory = info.dir.split('/').join(path.sep);\n const extension = info.ext ? info.ext : undefined;\n const filePath = extension ?\n path.join(directory, info.name) + extension :\n path.join(directory, info.name);\n\n return {\n directory,\n name: info.name,\n extension,\n path: filePath,\n };\n}\n\nexport function isLocatorInfo(\n input: unknown,\n) : input is LocatorInfo {\n return isObject(input) &&\n typeof input.directory === 'string' &&\n typeof input.name === 'string' &&\n (typeof input.extension === 'undefined' || typeof input.extension === 'string') &&\n typeof input.path === 'string';\n}\n\nexport function buildFilePath(input: LocatorInfo | string) {\n if (typeof input === 'string') {\n return input;\n }\n\n return input.path;\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fg from 'fast-glob';\nimport type { TwinBody } from '../utils/twin';\nimport { op } from '../utils/twin';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\nimport { buildLocatorOptions, buildLocatorPatterns, pathToLocatorInfo } from './utils';\n\ntype GlobJob = {\n pattern: string,\n options: fg.Options,\n};\n\nfunction buildGlobJobs(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : GlobJob[] {\n const patterns = buildLocatorPatterns(pattern);\n const opts = buildLocatorOptions(options);\n\n const jobs : GlobJob[] = [];\n for (const p of patterns) {\n for (const cwd of opts.cwd) {\n jobs.push({\n pattern: p,\n options: {\n absolute: true,\n cwd,\n ignore: opts.ignore,\n onlyFiles: opts.onlyFiles,\n onlyDirectories: opts.onlyDirectories,\n dot: opts.dot,\n },\n });\n }\n }\n\n return jobs;\n}\n\nfunction* glob(job: GlobJob) : Generator<any, string[], any> {\n return yield* op(\n () => fg(job.pattern, job.options),\n () => fg.sync(job.pattern, job.options),\n );\n}\n\nexport function* locateBody(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : TwinBody<LocatorInfo | undefined> {\n for (const job of buildGlobJobs(pattern, options)) {\n const files = yield* glob(job);\n\n const element = files.shift();\n if (element) {\n return pathToLocatorInfo(element, true);\n }\n }\n\n return undefined;\n}\n\nexport function* locateManyBody(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : TwinBody<LocatorInfo[]> {\n const items : LocatorInfo[] = [];\n\n for (const job of buildGlobJobs(pattern, options)) {\n const files = yield* glob(job);\n\n for (const file of files) {\n items.push(pathToLocatorInfo(file, true));\n }\n }\n\n return items;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { runTwinAsync } from '../utils/twin';\nimport { locateBody, locateManyBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport async function locateMany(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : Promise<LocatorInfo[]> {\n return runTwinAsync(locateManyBody(pattern, options));\n}\n\nexport async function locate(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : Promise<LocatorInfo | undefined> {\n return runTwinAsync(locateBody(pattern, options));\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { runTwinSync } from '../utils/twin';\nimport { locateBody, locateManyBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport function locateManySync(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : LocatorInfo[] {\n return runTwinSync(locateManyBody(pattern, options));\n}\n\nexport function locateSync(\n pattern: string | string[],\n options?: LocatorOptionsInput,\n) : LocatorInfo | undefined {\n return runTwinSync(locateBody(pattern, options));\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport path from 'node:path';\nimport type { TwinBody } from '../utils/twin';\nimport { runTwinAsync, runTwinSync } from '../utils/twin';\nimport { locateBody } from './core';\nimport type { LocatorInfo, LocatorOptionsInput } from './types';\n\nexport type LocatorUpOptionsInput = Omit<LocatorOptionsInput, 'cwd'> & {\n cwd?: string,\n stopAt?: string,\n};\n\ntype WalkStep = {\n current: string,\n stopAt: string,\n baseOptions: Omit<LocatorOptionsInput, 'cwd'>,\n};\n\nfunction startWalk(options: LocatorUpOptionsInput) : WalkStep {\n const {\n cwd,\n stopAt,\n ...baseOptions\n } = options;\n const current = path.resolve(cwd ?? process.cwd());\n const ceiling = stopAt ?\n path.resolve(current, stopAt) :\n path.parse(current).root;\n\n return {\n current,\n stopAt: ceiling,\n baseOptions,\n };\n}\n\nfunction nextDirectory(current: string, stopAt: string) : string | undefined {\n if (current === stopAt) {\n return undefined;\n }\n\n const parent = path.dirname(current);\n if (parent === current) {\n return undefined;\n }\n\n return parent;\n}\n\nfunction* locateUpBody(\n pattern: string | string[],\n options: LocatorUpOptionsInput,\n) : TwinBody<LocatorInfo | undefined> {\n let walk = startWalk(options);\n\n while (true) {\n const found = yield* locateBody(pattern, { ...walk.baseOptions, cwd: walk.current });\n if (found) {\n return found;\n }\n\n const next = nextDirectory(walk.current, walk.stopAt);\n if (!next) {\n return undefined;\n }\n\n walk = { ...walk, current: next };\n }\n}\n\nexport async function locateUp(\n pattern: string | string[],\n options: LocatorUpOptionsInput = {},\n) : Promise<LocatorInfo | undefined> {\n return runTwinAsync(locateUpBody(pattern, options));\n}\n\nexport function locateUpSync(\n pattern: string | string[],\n options: LocatorUpOptionsInput = {},\n) : LocatorInfo | undefined {\n return runTwinSync(locateUpBody(pattern, options));\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fs from 'node:fs';\nimport { wrapLoaderError } from '../../errors';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport type { IReader } from '../type';\n\n/**\n * Base class for readers of text-based file formats: reads the file as\n * UTF-8, delegates to `parse`, and wraps I/O and parse errors in typed\n * LocterError subclasses. Subclasses implement `parse` only — both\n * `read` variants are derived from the same body.\n */\nexport abstract class TextFileReader implements IReader {\n abstract parse(content: string) : any;\n\n async read(input: string) : Promise<any> {\n return runTwinAsync(this.body(input));\n }\n\n readSync(input: string) : any {\n return runTwinSync(this.body(input));\n }\n\n protected* body(input: string) : TwinBody<any> {\n try {\n const content = yield* op(\n () => fs.promises.readFile(input, { encoding: 'utf-8' }),\n () => fs.readFileSync(input, { encoding: 'utf-8' }),\n );\n\n return this.parse(content);\n } catch (e) {\n throw wrapLoaderError(e, input);\n }\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { wrapWriteError } from '../../errors';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport type { IWriter } from '../type';\n\nfunction isNotFound(e: unknown) : boolean {\n return e instanceof Error && 'code' in e && e.code === 'ENOENT';\n}\n\n/**\n * Base class for writers of text-based file formats: serializes via\n * `stringify`, creates missing parent directories, writes the file as\n * UTF-8 (always terminated by a single trailing newline), and wraps\n * failures in LocterWriteError. Subclasses implement `stringify` only —\n * both `write` variants are derived from the same body.\n */\nexport abstract class TextFileWriter implements IWriter {\n /**\n * Opt-in: when true, the body reads the target file first (undefined\n * if absent) and passes its content to `stringify` as `existing` —\n * the hook behind format-preserving write-back (YAML comment\n * grafting, JSON indent detection).\n */\n protected get usesExistingContent() : boolean {\n return false;\n }\n\n abstract stringify(value: unknown, existing?: string) : string;\n\n async write(input: string, value: unknown) : Promise<void> {\n return runTwinAsync(this.body(input, value));\n }\n\n writeSync(input: string, value: unknown) : void {\n runTwinSync(this.body(input, value));\n }\n\n protected* body(input: string, value: unknown) : TwinBody<void> {\n const filePath = input;\n\n try {\n let existing : string | undefined;\n if (this.usesExistingContent) {\n existing = yield* op(\n () => fs.promises.readFile(filePath, { encoding: 'utf-8' })\n .catch((e) => {\n if (isNotFound(e)) {\n return undefined;\n }\n throw e;\n }),\n () => {\n try {\n return fs.readFileSync(filePath, { encoding: 'utf-8' });\n } catch (e) {\n if (isNotFound(e)) {\n return undefined;\n }\n throw e;\n }\n },\n );\n }\n\n let content = this.stringify(value, existing);\n if (!content.endsWith('\\n')) {\n content += '\\n';\n }\n\n const directory = path.dirname(filePath);\n yield* op(\n async () => {\n await fs.promises.mkdir(directory, { recursive: true });\n },\n () => {\n fs.mkdirSync(directory, { recursive: true });\n },\n );\n\n yield* op(\n () => fs.promises.writeFile(filePath, content, { encoding: 'utf-8' }),\n () => fs.writeFileSync(filePath, content, { encoding: 'utf-8' }),\n );\n } catch (e) {\n throw wrapWriteError(e, filePath);\n }\n }\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n// Based on https://github.com/unjs/rc9 (MIT)\n\nimport { destr } from 'destr';\nimport { unflatten } from 'flat';\nimport { isSafeObjectKey } from '../../../utils';\nimport { TextFileReader } from '../../text-file';\n\nexport class ConfReader extends TextFileReader {\n parse(contents: string): Record<string, any> {\n const config: Record<string, any> = {};\n\n const lines = contents.split(/\\n|\\r|\\r\\n/);\n\n for (const line of lines) {\n const match = line.match(/^\\s*([^\\s=]+)\\s*=\\s*(.*)?\\s*$/);\n if (!match) {\n continue;\n }\n\n const key = match[1];\n const rawValue = match[2];\n\n if (!key || !isSafeObjectKey(key)) {\n continue;\n }\n\n const value = destr(rawValue ? rawValue.trim() : '');\n\n if (key.endsWith('[]')) {\n const arrKey = key.slice(0, Math.max(0, key.length - 2));\n config[arrKey] = (config[arrKey] || []).concat(value);\n continue;\n }\n\n config[key] = value;\n }\n\n return unflatten(config, { overwrite: true });\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n// Based on https://github.com/unjs/rc9 (MIT)\n\nimport { flatten } from 'flat';\nimport { isObject } from '../../../utils';\nimport { TextFileWriter } from '../../text-file';\n\nfunction serializeValue(value: unknown) : string {\n return typeof value === 'string' ? value : JSON.stringify(value);\n}\n\n/**\n * Serializes an object to `key=value` lines (the inverse of ConfReader):\n * nested objects become dot-separated keys, arrays become repeated\n * `key[]=` lines. Round-trips are structural, not textual — comments,\n * blank lines, and line order of an existing file are not preserved,\n * and a string that parses as another type (e.g. '123') reads back as\n * that type.\n */\nexport class ConfWriter extends TextFileWriter {\n stringify(value: unknown) : string {\n if (!isObject(value)) {\n throw new Error('The value must be an object for the conf format.');\n }\n\n const flat : Record<string, unknown> = flatten(value, { safe: true });\n\n const lines : string[] = [];\n for (const key of Object.keys(flat)) {\n const entry = flat[key];\n if (typeof entry === 'undefined') {\n continue;\n }\n\n if (Array.isArray(entry)) {\n for (const item of entry) {\n lines.push(`${key}[]=${serializeValue(item)}`);\n }\n continue;\n }\n\n lines.push(`${key}=${serializeValue(entry)}`);\n }\n\n return lines.join('\\n');\n }\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { TextFileReader } from '../../text-file';\n\nexport class JSONReader extends TextFileReader {\n parse(content: string) {\n return JSON.parse(content);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { TextFileWriter } from '../../text-file';\n\nexport type JSONWriterOptions = {\n /**\n * Indentation of the emitted JSON. A number of spaces, a literal\n * indent string, or 'auto' — detect the indentation of the existing\n * target file and keep it (falls back to 4 for new files).\n *\n * @default 4\n */\n indent?: number | string | 'auto'\n};\n\nfunction detectIndent(content: string) : string | undefined {\n const match = /^([ \\t]+)\\S/m.exec(content);\n return match ? match[1] : undefined;\n}\n\nexport class JSONWriter extends TextFileWriter {\n protected options : JSONWriterOptions;\n\n constructor(options: JSONWriterOptions = {}) {\n super();\n this.options = options;\n }\n\n protected override get usesExistingContent() : boolean {\n return this.options.indent === 'auto';\n }\n\n stringify(value: unknown, existing?: string) : string {\n let indent : number | string | undefined;\n if (this.options.indent === 'auto') {\n indent = existing ? detectIndent(existing) : undefined;\n } else {\n indent = this.options.indent;\n }\n\n indent = indent ?? 4;\n\n const output = JSON.stringify(value, null, indent);\n if (typeof output === 'undefined') {\n throw new Error('The value is not JSON-serializable.');\n }\n\n return output;\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\n/**\n * Single source of truth for the extensions handled by the module loader:\n * consumed by BOTH the built-in routing registry and the jiti config.\n */\nexport const MODULE_FILE_EXTENSIONS = ['.js', '.mjs', '.mts', '.cjs', '.cts', '.ts'] as const;\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { createJiti } from 'jiti';\nimport { createRequire } from 'node:module';\nimport { pathToFileURL } from 'node:url';\nimport { LocterError, wrapLoaderError } from '../../../errors';\nimport type { LocatorInfo } from '../../../locator';\nimport {\n buildFilePath,\n isLocatorInfo,\n} from '../../../locator';\nimport {\n hasStringProperty,\n isFilePath,\n isJestRuntimeEnvironment,\n isObject,\n isTsNodeRuntimeEnvironment,\n isTypeScriptError,\n} from '../../../utils';\nimport type { IReader } from '../../type';\nimport { MODULE_FILE_EXTENSIONS } from './constants';\nimport type {\n ModuleLoadFn,\n ModuleLoadOptions,\n ModuleLoadSyncFn,\n ModuleReaderOptions,\n} from './type';\n\nconst require = createRequire(import.meta.url);\n\ntype Jiti = ReturnType<typeof createJiti>;\n\nfunction originalPath(data: LocatorInfo | string) : string {\n return typeof data === 'string' ? data : buildFilePath(data);\n}\n\nfunction isUnrecoverableError(error: unknown) : boolean {\n const underlying = error instanceof LocterError ? error.cause : error;\n return underlying instanceof SyntaxError ||\n underlying instanceof ReferenceError ||\n isTypeScriptError(underlying);\n}\n\nexport class ModuleReader implements IReader {\n protected instance : Jiti;\n\n protected loadFn?: ModuleLoadFn;\n\n protected loadSyncFn?: ModuleLoadSyncFn;\n\n constructor(options: ModuleReaderOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n this.instance = createJiti(undefined, { extensions: [...MODULE_FILE_EXTENSIONS] });\n this.loadFn = options.load;\n this.loadSyncFn = options.loadSync;\n }\n\n /**\n * Returns the previous configuration, so callers can restore it.\n */\n configure(options: ModuleReaderOptions) : ModuleReaderOptions {\n const previous : ModuleReaderOptions = {\n load: this.loadFn,\n loadSync: this.loadSyncFn,\n };\n\n if ('load' in options) {\n this.loadFn = options.load;\n }\n if ('loadSync' in options) {\n this.loadSyncFn = options.loadSync;\n }\n\n return previous;\n }\n\n /**\n * Returns the raw module value (import / require / jiti output) —\n * normalization to a module record happens once, at the\n * FormatRegistry boundary.\n *\n * read/readSync are deliberately NOT derived from a shared body\n * (unlike every other sync/async twin in this package): their\n * recovery paths differ. The async variant falls back to loadSync\n * under ts-node (jiti's async path does not cooperate with ts-node)\n * and to the jiti instance otherwise; the sync variant only has the\n * jiti fallback. The divergence is pinned by the fallback tests in\n * test/unit/format/module.spec.ts.\n */\n async read(input: string) {\n try {\n return await this.load(input);\n } catch (e) {\n if (isUnrecoverableError(e)) {\n throw e;\n }\n\n // jiti + ts-node\n // issue: https://github.com/nuxt/bridge/issues/228\n if (isTsNodeRuntimeEnvironment()) {\n return this.loadSync(input);\n }\n\n return this.instance(input);\n }\n }\n\n readSync(input: string) {\n try {\n return this.loadSync(input);\n } catch (e) {\n if (isUnrecoverableError(e)) {\n throw e;\n }\n\n return this.instance(input);\n }\n }\n\n // ---------------------------------------------------------------------------\n\n async load(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : Promise<unknown> {\n const id = this.build(data, options);\n\n try {\n if (this.loadFn) {\n return await this.loadFn(id);\n }\n\n // segmentation fault\n // issue: https://github.com/nodejs/node/issues/35889\n if (isJestRuntimeEnvironment()) {\n return require(id);\n }\n\n return await import(id);\n } catch (e) {\n /* istanbul ignore next */\n if (\n !options.withFilePrefix &&\n isObject(e) &&\n hasStringProperty(e, 'code') &&\n (\n e.code === 'ERR_UNSUPPORTED_ESM_URL_SCHEME' ||\n e.code === 'UNSUPPORTED_ESM_URL_SCHEME'\n )\n ) {\n return this.load(data, {\n ...options,\n withFilePrefix: true,\n });\n }\n\n throw wrapLoaderError(e, originalPath(data));\n }\n }\n\n loadSync(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : unknown {\n const id = this.build(data, options);\n\n try {\n if (this.loadSyncFn) {\n return this.loadSyncFn(id);\n }\n\n return require(id);\n } catch (e) {\n throw wrapLoaderError(e, originalPath(data));\n }\n }\n\n private build(\n data: LocatorInfo | string,\n options: ModuleLoadOptions = {},\n ) : string {\n if (isLocatorInfo(data) || isFilePath(data)) {\n if (typeof data !== 'string') {\n data = buildFilePath(data);\n }\n\n if (options.withFilePrefix) {\n data = pathToFileURL(data).href;\n }\n }\n\n return data;\n }\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { hasOwnProperty, isObject } from '../../../utils';\nimport type { ModuleExport, ModuleExportFilterFn } from './type';\n\ntype ESModule = { [key: string]: any, __esModule: boolean };\n\n/**\n * Brand carried by every record locter's read() produces. Deliberately a\n * module-private Symbol (NOT Symbol.for) so arbitrary parsed data cannot\n * forge it — unlike `__esModule`, its presence is trustworthy. write()\n * uses it to unwrap `.default` on round-trips.\n */\nconst MODULE_RECORD = Symbol('locter.record');\n\n/**\n * True when the value is a record produced by locter's read()/toModuleRecord.\n * Detection is brand-based; a plain object with an `__esModule` key is NOT\n * a module record.\n */\nexport function isModuleRecord(input: unknown) : input is Record<string, any> {\n return isObject(input) && MODULE_RECORD in input;\n}\n\nfunction brand<T>(input: T) : T {\n if (isObject(input) && Object.isExtensible(input)) {\n Object.defineProperty(input, MODULE_RECORD, { value: true });\n }\n\n return input;\n}\n\n/**\n * Detect the transpiler interop marker (`__esModule`). Only meaningful for\n * values that came out of a module system — arbitrary parsed data can carry\n * an `__esModule` key without being a module, so callers must decide by\n * provenance whether this check applies (see FormatRegistry).\n */\nexport function isESModule(input: unknown) : input is ESModule {\n return isObject(input) &&\n typeof input.__esModule !== 'undefined';\n}\n\n/**\n * Wrap an arbitrary value in a frozen module record: enumerable keys are\n * re-exposed as named exports and `default` is the value itself.\n */\nexport function createModuleRecord(data: unknown) {\n const output = Object.create(null, {\n __esModule: { value: true },\n [Symbol.toStringTag]: { value: 'Module' },\n [MODULE_RECORD]: { value: true },\n });\n\n if (isObject(data)) {\n for (const key in data) {\n if (hasOwnProperty(output, key)) {\n continue;\n }\n\n let descriptor = Object.getOwnPropertyDescriptor(data, key);\n if (\n !descriptor ||\n ('get' in descriptor || descriptor.writable || descriptor.configurable)\n ) {\n descriptor = {\n enumerable: true,\n get() {\n return data[key];\n },\n };\n }\n\n Object.defineProperty(output, key, descriptor);\n }\n }\n\n if (!hasOwnProperty(output, 'default')) {\n Object.defineProperty(output, 'default', {\n value: data,\n enumerable: true,\n });\n }\n\n return Object.freeze(output);\n}\n\n/**\n * Normalize module-loader output to a module record. Values already carrying\n * the `__esModule` marker pass through (module provenance makes the marker\n * trustworthy); everything else is wrapped via createModuleRecord.\n *\n * https://2ality.com/2017/01/babel-esm-spec-mode.html\n */\nexport function toModuleRecord(\n data: unknown,\n) {\n if (isESModule(data)) {\n // @see https://github.com/testing-library/user-event/issues/813\n // @see https://stackoverflow.com/questions/62717394/export-default-class-exports-double-nested-default\n if (\n isESModule(data.default) &&\n data.default.default\n ) {\n return brand({\n ...data,\n default: data.default.default,\n });\n }\n\n // best-effort: module namespace objects are non-extensible and\n // stay unbranded — they have no writable format anyway\n return brand(data);\n }\n\n return createModuleRecord(data);\n}\n\nexport function getModuleExport(\n data: Record<string, any>,\n filterFn: ModuleExportFilterFn,\n): ModuleExport | undefined {\n const keys = Object.keys(data);\n for (const key of keys) {\n if (filterFn(key as string, data[key as string])) {\n return {\n key: key as string,\n value: data[key as string],\n };\n }\n }\n\n return undefined;\n}\n","/*\n * Copyright (c) 2022-2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { parse as parseYAML } from 'yaml';\nimport { TextFileReader } from '../../text-file';\n\nexport class YAMLReader extends TextFileReader {\n parse(content: string) {\n return parseYAML(content);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { Document, ToStringOptions, YAMLMap } from 'yaml';\nimport {\n isMap,\n isNode,\n isScalar,\n parseDocument,\n stringify as stringifyYAML,\n} from 'yaml';\nimport { hasOwnProperty, isObject } from '../../../utils';\nimport { TextFileWriter } from '../../text-file';\n\nexport type YAMLWriterOptions = ToStringOptions;\n\nfunction pairKey(key: unknown) : string {\n return isScalar(key) ? String(key.value) : String(key);\n}\n\n/**\n * Merge a plain object into an existing YAML map node: added/changed keys\n * are set, absent keys are deleted, and nested objects recurse — so\n * comments, anchors, and formatting attached to surviving keys are\n * preserved. Arrays, scalars, and type changes replace the node wholesale\n * (comments inside the replaced subtree are lost).\n */\nfunction graftMap(doc: Document, node: YAMLMap, value: Record<string, unknown>) : void {\n for (const pair of [...node.items]) {\n if (!hasOwnProperty(value, pairKey(pair.key))) {\n node.delete(pair.key);\n }\n }\n\n for (const key of Object.keys(value)) {\n const entry = value[key];\n const current = node.get(key, true);\n\n if (isMap(current) && isObject(entry)) {\n graftMap(doc, current, entry);\n continue;\n }\n\n const replacement = doc.createNode(entry);\n if (isNode(current)) {\n // keep comments anchored to the value node itself\n // (`key: value # trailing`, standalone lines above the value)\n replacement.commentBefore = current.commentBefore;\n replacement.comment = current.comment;\n replacement.spaceBefore = current.spaceBefore;\n }\n\n node.set(doc.createNode(key), replacement);\n }\n}\n\n/**\n * Writes YAML preserving hand-edited structure where possible: when the\n * target file already exists, the new value is grafted into its parsed\n * document, so comments and anchors attached to surviving keys survive\n * the write-back. New files are plain `yaml.stringify` output. An\n * existing file that fails to parse throws (wrapped as LocterWriteError)\n * instead of being silently overwritten.\n */\nexport class YAMLWriter extends TextFileWriter {\n protected options : YAMLWriterOptions;\n\n constructor(options: YAMLWriterOptions = {}) {\n super();\n this.options = options;\n }\n\n protected override get usesExistingContent() : boolean {\n return true;\n }\n\n stringify(value: unknown, existing?: string) : string {\n if (typeof existing === 'undefined') {\n return stringifyYAML(value, this.options);\n }\n\n // widen from Document.Parsed: contents is replaced with\n // freshly created (non-parsed) nodes while grafting\n const doc : Document = parseDocument(existing);\n if (doc.errors.length > 0) {\n throw doc.errors[0];\n }\n\n if (isMap(doc.contents) && isObject(value)) {\n graftMap(doc, doc.contents, value);\n } else {\n doc.contents = doc.createNode(value);\n }\n\n return doc.toString(this.options);\n }\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { FormatPreset } from '../registry/type';\nimport type { IWriter } from '../type';\nimport { ConfReader, ConfWriter } from './conf';\nimport { JSONReader, JSONWriter } from './json';\nimport { ModuleReader } from './module';\nimport { MODULE_FILE_EXTENSIONS } from './module/constants';\nimport { YAMLReader, YAMLWriter } from './yaml';\n\n/**\n * Every built-in format, in one place. Keys are the format ids; each entry\n * couples routing and construction. The id union, the extension → format\n * table, lazy caching, and the typed `builtInReader()` accessor are all\n * DERIVED from this object. Adding a format = adding one entry.\n *\n * Intentionally NOT re-exported from any barrel (internal API).\n */\nexport const BUILT_IN_PRESETS = {\n module: { extensions: MODULE_FILE_EXTENSIONS, reader: () => new ModuleReader() },\n conf: {\n extensions: ['.conf'],\n reader: () => new ConfReader(),\n writer: () => new ConfWriter(),\n },\n json: {\n extensions: ['.json'],\n reader: () => new JSONReader(),\n writer: () => new JSONWriter(),\n },\n yaml: {\n extensions: ['.yml', '.yaml'],\n reader: () => new YAMLReader(),\n writer: () => new YAMLWriter(),\n },\n} as const satisfies Record<string, FormatPreset>;\n\nexport type BuiltInFormatId = keyof typeof BUILT_IN_PRESETS;\n\nexport type BuiltInReaderOf<K extends BuiltInFormatId> = ReturnType<(typeof BUILT_IN_PRESETS)[K]['reader']>;\n\n/**\n * Built-in format ids whose preset declares a writer — derived at the type\n * level, so builtInWriter('module') is a compile error, not a runtime one.\n */\nexport type WritableBuiltInFormatId = {\n [K in BuiltInFormatId]: (typeof BUILT_IN_PRESETS)[K] extends { writer: () => IWriter } ? K : never\n}[BuiltInFormatId];\n\nexport type BuiltInWriterOf<K extends WritableBuiltInFormatId> = ReturnType<(typeof BUILT_IN_PRESETS)[K]['writer']>;\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport {\n LocterError,\n LocterUnknownExtensionError,\n LocterWriteError,\n wrapLoaderError,\n wrapWriteError,\n} from '../../errors';\nimport type { LocatorInfo } from '../../locator';\nimport { buildFilePath, pathToLocatorInfo } from '../../locator';\nimport { hasOwnProperty, isFilePath } from '../../utils';\nimport type { TwinBody } from '../../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../../utils/twin';\nimport {\n ModuleReader, \n createModuleRecord, \n isModuleRecord, \n toModuleRecord,\n} from '../built-in';\nimport type {\n BuiltInFormatId,\n BuiltInReaderOf,\n BuiltInWriterOf,\n WritableBuiltInFormatId,\n} from '../built-in/registry';\nimport { BUILT_IN_PRESETS } from '../built-in/registry';\nimport type { IReader, IWriter } from '../type';\nimport type {\n FormatRegistration,\n Rule,\n} from './type';\n\nexport type FormatRegistryOptions = {\n /**\n * Seed user rules (matched before built-ins, in array order).\n */\n rules?: Rule[]\n};\n\n/**\n * A rule compiled to memoizing per-slot accessors. Caller-owned Rule\n * objects are never mutated; factory caching lives in the closures.\n */\ntype CompiledRule = {\n id: string,\n test: RegExp | string[],\n getReader?: () => IReader,\n getWriter?: () => IWriter\n};\n\nfunction compileSlot<T>(slot: T | (() => T) | undefined) : (() => T) | undefined {\n if (typeof slot === 'undefined') {\n return undefined;\n }\n\n if (typeof slot !== 'function') {\n return () => slot;\n }\n\n const factory = slot as () => T;\n let cached : T | undefined;\n return () => {\n if (!cached) {\n cached = factory();\n }\n\n return cached;\n };\n}\n\nexport class FormatRegistry {\n /**\n * User rules only — built-ins live in the extension table instead.\n */\n protected rules : CompiledRule[];\n\n /**\n * Lazy per-instance cache of built-in reader instances.\n */\n protected builtInReaderCache : Map<BuiltInFormatId, IReader>;\n\n /**\n * Lazy per-instance cache of built-in writer instances.\n */\n protected builtInWriterCache : Map<BuiltInFormatId, IWriter>;\n\n /**\n * extension → built-in format id, precomputed once from BUILT_IN_PRESETS.\n */\n protected builtInExtensions : Map<string, BuiltInFormatId>;\n\n protected ruleCounter : number;\n\n constructor(options: FormatRegistryOptions = {}) {\n this.rules = [];\n this.builtInReaderCache = new Map();\n this.builtInWriterCache = new Map();\n this.builtInExtensions = new Map();\n this.ruleCounter = 0;\n\n const ids = Object.keys(BUILT_IN_PRESETS) as BuiltInFormatId[];\n for (const id of ids) {\n for (const extension of BUILT_IN_PRESETS[id].extensions) {\n const existing = this.builtInExtensions.get(extension);\n if (existing) {\n throw new LocterError({ message: `Extension ${extension} is claimed by two built-in formats: ${existing}, ${id}.` });\n }\n\n this.builtInExtensions.set(extension, id);\n }\n }\n\n if (options.rules) {\n for (const rule of options.rules) {\n this.register(rule);\n }\n }\n }\n\n register(rule: Rule) : FormatRegistration {\n if (\n typeof rule.id !== 'undefined' &&\n hasOwnProperty(BUILT_IN_PRESETS, rule.id)\n ) {\n throw new LocterError({ message: `The id ${rule.id} is reserved by a built-in format.` });\n }\n\n if (\n typeof rule.reader === 'undefined' &&\n typeof rule.writer === 'undefined'\n ) {\n throw new LocterError({ message: 'A rule requires at least one of: reader, writer.' });\n }\n\n const id = rule.id ?? this.generateRuleId();\n const entry = this.compile(id, rule);\n\n const index = this.rules.findIndex((item) => item.id === id);\n if (index === -1) {\n this.rules.push(entry);\n } else {\n // replace in place: position preserved, cached instance evicted\n this.rules[index] = entry;\n }\n\n return {\n id,\n test: rule.test,\n builtIn: false,\n };\n }\n\n /**\n * Remove a user-registered rule by id. Built-in ids cannot be\n * unregistered (returns false).\n */\n unregister(id: string) : boolean {\n const index = this.rules.findIndex((item) => item.id === id);\n if (index === -1) {\n return false;\n }\n\n this.rules.splice(index, 1);\n return true;\n }\n\n has(id: string) : boolean {\n if (this.rules.some((item) => item.id === id)) {\n return true;\n }\n\n return hasOwnProperty(BUILT_IN_PRESETS, id);\n }\n\n /**\n * All registrations in effective match order: user rules\n * (registration order) first, then the built-ins.\n */\n entries() : FormatRegistration[] {\n const output : FormatRegistration[] = this.rules.map(\n (item) => ({\n id: item.id,\n test: item.test,\n builtIn: false,\n }),\n );\n\n const ids = Object.keys(BUILT_IN_PRESETS) as BuiltInFormatId[];\n for (const id of ids) {\n output.push({\n id,\n test: [...BUILT_IN_PRESETS[id].extensions],\n builtIn: true,\n });\n }\n\n return output;\n }\n\n /**\n * Restore the registry to its construction state: drop all user rules\n * and evict every cached reader instance (including a module reader\n * configured via setModuleReader / configure).\n */\n reset() : void {\n this.rules = [];\n this.builtInReaderCache.clear();\n this.builtInWriterCache.clear();\n this.ruleCounter = 0;\n }\n\n /**\n * Read a file/module RAW: the plain parsed value for data formats\n * (mutable, round-trip-symmetric with write); for modules the\n * normalized module record — a module IS a record, and the\n * normalization only irons out the CJS/ESM interop divergence so\n * both twin variants agree on one shape.\n */\n async read(input: LocatorInfo | string) : Promise<any> {\n return runTwinAsync(this.readBody(input));\n }\n\n readSync(input: LocatorInfo | string) : any {\n return runTwinSync(this.readBody(input));\n }\n\n /**\n * Read a file/module and present the result as a normalized module\n * record — the uniform, frozen shape regardless of format:\n * `.default` always holds the loaded value, top-level keys are\n * re-exposed as named exports.\n */\n async readAsModule(input: LocatorInfo | string) : Promise<any> {\n return runTwinAsync(this.readAsModuleBody(input));\n }\n\n readAsModuleSync(input: LocatorInfo | string) : any {\n return runTwinSync(this.readAsModuleBody(input));\n }\n\n protected* readBody(input: LocatorInfo | string) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input);\n if (reader instanceof ModuleReader) {\n return toModuleRecord(output);\n }\n\n return output;\n }\n\n protected* readAsModuleBody(input: LocatorInfo | string) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input);\n return this.toRecord(output, reader);\n }\n\n /**\n * Shared dispatch + execution of both read bodies: resolve the\n * reader, run it, wrap errors. Normalization is the caller's call.\n */\n protected* executeBody(\n input: LocatorInfo | string,\n ) : TwinBody<{ output: unknown, reader: IReader }> {\n const filePath = buildFilePath(input);\n const reader = this.findReader(filePath);\n if (!reader) {\n throw this.unknownExtensionError(filePath);\n }\n\n try {\n const output = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n return { output, reader };\n } catch (e) {\n throw wrapLoaderError(e, filePath);\n }\n }\n\n async write(input: LocatorInfo | string, value: unknown) : Promise<void> {\n return runTwinAsync(this.writeBody(input, value));\n }\n\n writeSync(input: LocatorInfo | string, value: unknown) : void {\n runTwinSync(this.writeBody(input, value));\n }\n\n /**\n * Shared body of write/writeSync: dispatch, unwrap records, write, wrap.\n * The inverse boundary of readAsModuleBody: a record produced by\n * readAsModule() (brand detected) is unwrapped to its `.default` value;\n * anything else is written as-is.\n */\n protected* writeBody(input: LocatorInfo | string, value: unknown) : TwinBody<void> {\n const filePath = buildFilePath(input);\n if (!isFilePath(filePath)) {\n throw new LocterWriteError({\n message: `Cannot write to a bare module specifier: ${filePath}`,\n path: filePath,\n });\n }\n\n const writer = this.findWriter(filePath);\n if (!writer) {\n if (this.findReader(filePath)) {\n const info = pathToLocatorInfo(filePath);\n throw new LocterWriteError({\n message: `The format of extension ${info.extension} is read-only.`,\n path: filePath,\n });\n }\n\n throw this.unknownExtensionError(filePath);\n }\n\n const plain = isModuleRecord(value) ? value.default : value;\n\n try {\n yield* op(\n () => writer.write(filePath, plain),\n () => writer.writeSync(filePath, plain),\n );\n } catch (e) {\n throw wrapWriteError(e, filePath);\n }\n }\n\n /**\n * The single normalization boundary: every readAsModule result becomes a module\n * record (`.default` is always the loaded value, top-level keys stay\n * accessible as named exports). Provenance decides how: module-reader\n * output may legitimately already be a record (`__esModule` is meaningful\n * there); any other reader returns arbitrary parsed data, which is always\n * wrapped — even if it happens to contain an `__esModule` key.\n */\n protected toRecord(output: unknown, reader: IReader) : any {\n if (reader instanceof ModuleReader) {\n return toModuleRecord(output);\n }\n\n return createModuleRecord(output);\n }\n\n /**\n * Typed accessor for the LIVE built-in reader instance (lazy, cached).\n */\n builtInReader<K extends BuiltInFormatId>(id: K) : BuiltInReaderOf<K> {\n let reader = this.builtInReaderCache.get(id);\n if (!reader) {\n reader = BUILT_IN_PRESETS[id].reader();\n this.builtInReaderCache.set(id, reader);\n }\n\n return reader as BuiltInReaderOf<K>;\n }\n\n /**\n * Typed accessor for the LIVE built-in writer instance (lazy, cached).\n * Only writable format ids are accepted — read-only formats (module)\n * are a compile error.\n */\n builtInWriter<K extends WritableBuiltInFormatId>(id: K) : BuiltInWriterOf<K> {\n let writer = this.builtInWriterCache.get(id);\n if (!writer) {\n writer = BUILT_IN_PRESETS[id].writer();\n this.builtInWriterCache.set(id, writer);\n }\n\n return writer as BuiltInWriterOf<K>;\n }\n\n /**\n * Dispatch order:\n * 1. bare specifier (no extension) → module reader, always\n * 2. user rules, registration order → first match wins (can override built-ins)\n * 3. built-in extension table\n * 4. undefined → read/readSync throw LocterUnknownExtensionError\n */\n findReader(input: string) : IReader | undefined {\n if (!isFilePath(input)) {\n return this.builtInReader('module');\n }\n\n const rule = this.findRule(input, (item) => typeof item.getReader !== 'undefined');\n if (rule && rule.getReader) {\n return rule.getReader();\n }\n\n const id = this.findBuiltInId(input);\n if (id) {\n return this.builtInReader(id);\n }\n\n return undefined;\n }\n\n /**\n * Write-side dispatch. No bare-specifier step (there is nothing to\n * write to); only rules with a writer slot participate, then built-in\n * presets that declare a writer.\n */\n findWriter(input: string) : IWriter | undefined {\n if (!isFilePath(input)) {\n return undefined;\n }\n\n const rule = this.findRule(input, (item) => typeof item.getWriter !== 'undefined');\n if (rule && rule.getWriter) {\n return rule.getWriter();\n }\n\n const id = this.findBuiltInId(input);\n if (id && 'writer' in BUILT_IN_PRESETS[id]) {\n return this.builtInWriter(id as WritableBuiltInFormatId);\n }\n\n return undefined;\n }\n\n protected findRule(\n input: string,\n filter: (rule: CompiledRule) => boolean,\n ) : CompiledRule | undefined {\n const info = pathToLocatorInfo(input);\n\n for (const rule of this.rules) {\n if (!filter(rule)) {\n continue;\n }\n\n const { test } = rule;\n if (Array.isArray(test)) {\n if (\n info.extension &&\n test.includes(info.extension)\n ) {\n return rule;\n }\n } else {\n // reset before AND after: a g/y regex mutates lastIndex on\n // test(), which would make repeated dispatch alternate and\n // leak state back into the caller-owned RegExp\n test.lastIndex = 0;\n const matched = test.test(buildFilePath(info));\n test.lastIndex = 0;\n if (matched) {\n return rule;\n }\n }\n }\n\n return undefined;\n }\n\n protected findBuiltInId(input: string) : BuiltInFormatId | undefined {\n const info = pathToLocatorInfo(input);\n if (!info.extension) {\n return undefined;\n }\n\n return this.builtInExtensions.get(info.extension);\n }\n\n protected unknownExtensionError(input: string) : LocterUnknownExtensionError {\n const info = pathToLocatorInfo(input);\n return new LocterUnknownExtensionError({\n message: `No format registered for extension: ${info.extension ?? 'unknown'}`,\n path: input,\n });\n }\n\n protected compile(id: string, rule: Rule) : CompiledRule {\n return {\n id,\n test: rule.test,\n getReader: compileSlot<IReader>(rule.reader),\n getWriter: compileSlot<IWriter>(rule.writer),\n };\n }\n\n protected generateRuleId() : string {\n let id : string;\n do {\n this.ruleCounter++;\n id = `rule:${this.ruleCounter}`;\n } while (this.rules.some((item) => item.id === id));\n\n return id;\n }\n}\n","/*\n * Copyright (c) 2023.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { FormatRegistry } from './module';\n\nlet instance : FormatRegistry;\nexport function useFormatRegistry() {\n if (typeof instance !== 'undefined') {\n return instance;\n }\n\n instance = new FormatRegistry();\n\n return instance;\n}\n","/*\n * Copyright (c) 2022.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport type { LocatorInfo } from '../locator';\nimport type { ModuleReaderOptions } from './built-in/module/type';\nimport {\n type FormatRegistration,\n type Rule,\n useFormatRegistry,\n} from './registry';\n\nexport function registerFormat(rule: Rule) : FormatRegistration {\n return useFormatRegistry().register(rule);\n}\n\n/**\n * Remove a rule from the process-global registry by its id\n * (as returned by registerFormat). Built-in ids cannot be unregistered.\n */\nexport function unregisterFormat(id: string) : boolean {\n return useFormatRegistry().unregister(id);\n}\n\n/**\n * Read a file/module RAW: the plain parsed value for data formats\n * (json/yaml/conf and custom readers — mutable, round-trip-symmetric\n * with write); for modules the normalized module record (a module IS a\n * record; normalization only irons out CJS/ESM interop divergence).\n */\nexport async function read(input: LocatorInfo | string) : Promise<any> {\n return useFormatRegistry().read(input);\n}\n\nexport function readSync(input: LocatorInfo | string) : any {\n return useFormatRegistry().readSync(input);\n}\n\n/**\n * Read a file/module and present the result as a normalized module\n * record — the uniform, frozen shape regardless of format: `.default`\n * always holds the loaded value, top-level keys are re-exposed as\n * named exports.\n */\nexport async function readAsModule(input: LocatorInfo | string) : Promise<any> {\n return useFormatRegistry().readAsModule(input);\n}\n\nexport function readAsModuleSync(input: LocatorInfo | string) : any {\n return useFormatRegistry().readAsModuleSync(input);\n}\n\nexport async function write(input: LocatorInfo | string, value: unknown) : Promise<void> {\n return useFormatRegistry().write(input, value);\n}\n\nexport function writeSync(input: LocatorInfo | string, value: unknown) : void {\n useFormatRegistry().writeSync(input, value);\n}\n\n/**\n * Override the built-in module reader's `import` / `require` calls.\n *\n * Useful for test runners (e.g. Vitest) where the dynamic `import()` inside\n * `node_modules/locter` would bypass the runner's module graph. Calling this\n * from user code (e.g. a Vitest setup file) lets the runner rewrite the\n * `import()` so loaded modules share identity with statically imported ones.\n *\n * Returns a restore function that re-applies the previous configuration —\n * handy for scoped overrides (e.g. test teardown). The restore function is\n * scoped to the exact reader instance it configured: after a registry\n * reset() (which discards that instance) it becomes a no-op instead of\n * re-applying stale configuration to the fresh instance.\n *\n * @example\n * ```ts\n * // vitest setup file\n * import { setModuleReader } from 'locter';\n *\n * setModuleReader({\n * load: (id) => import(id),\n * });\n * ```\n */\nexport function setModuleReader(options: ModuleReaderOptions) : () => void {\n const reader = useFormatRegistry().builtInReader('module');\n const previous = reader.configure(options);\n\n return () => {\n reader.configure(previous);\n };\n}\n","/*\n * Copyright (c) 2026.\n * Author Peter Placzek (tada5hi)\n * For the full copyright and license information,\n * view the LICENSE file that was distributed with this source code.\n */\n\nimport { LocterError, LocterNotFoundError, LocterWriteError } from '../errors';\nimport type { LocatorInfo } from '../locator';\nimport {\n buildFilePath,\n locate,\n locateSync,\n locateUp,\n locateUpSync,\n} from '../locator';\nimport { hasOwnProperty, isObject, isSafeObjectKey } from '../utils';\nimport type { TwinBody } from '../utils/twin';\nimport { op, runTwinAsync, runTwinSync } from '../utils/twin';\nimport { JSONWriter } from './built-in';\nimport { useFormatRegistry } from './registry';\n\nexport type ReadPackageFieldOptions = {\n cwd?: string,\n walkUp?: boolean,\n stopAt?: string,\n};\n\nexport type WritePackageFieldOptions = ReadPackageFieldOptions;\n\nfunction extractField<T>(pkg: unknown, field: string) : T | undefined {\n if (!isObject(pkg) || !hasOwnProperty(pkg, field)) {\n return undefined;\n }\n return pkg[field] as T;\n}\n\nfunction* locatePackageBody(\n options: ReadPackageFieldOptions,\n) : TwinBody<LocatorInfo | undefined> {\n if (options.walkUp) {\n return yield* op(\n () => locateUp('package.json', { cwd: options.cwd, stopAt: options.stopAt }),\n () => locateUpSync('package.json', { cwd: options.cwd, stopAt: options.stopAt }),\n );\n }\n\n return yield* op(\n () => locate('package.json', { cwd: options.cwd }),\n () => locateSync('package.json', { cwd: options.cwd }),\n );\n}\n\nfunction* readPackageFieldBody<T>(\n field: string,\n options: ReadPackageFieldOptions,\n) : TwinBody<T | undefined> {\n const info = yield* locatePackageBody(options);\n if (!info) {\n return undefined;\n }\n\n // Read the raw parsed package.json via the built-in JSON reader —\n // not the normalized record read() returns — so synthetic record\n // keys (`default`, `__esModule`) can never resolve as package fields.\n const reader = useFormatRegistry().builtInReader('json');\n const filePath = buildFilePath(info);\n\n try {\n const pkg = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n return extractField<T>(pkg, field);\n } catch (e) {\n if (e instanceof LocterNotFoundError) {\n return undefined;\n }\n throw e;\n }\n}\n\nexport async function readPackageField<T = unknown>(\n field: string,\n options: ReadPackageFieldOptions = {},\n) : Promise<T | undefined> {\n return runTwinAsync(readPackageFieldBody<T>(field, options));\n}\n\nexport function readPackageFieldSync<T = unknown>(\n field: string,\n options: ReadPackageFieldOptions = {},\n) : T | undefined {\n return runTwinSync(readPackageFieldBody<T>(field, options));\n}\n\nfunction* writePackageFieldBody(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions,\n) : TwinBody<void> {\n if (!isSafeObjectKey(field)) {\n throw new LocterError({ message: `The field ${field} is not a safe object key.` });\n }\n\n const info = yield* locatePackageBody(options);\n if (!info) {\n // unlike the reader, there is nothing sensible to return —\n // a write without a target is an error\n throw new LocterNotFoundError({ message: 'No package.json could be located.' });\n }\n\n const reader = useFormatRegistry().builtInReader('json');\n const filePath = buildFilePath(info);\n\n const pkg = yield* op(\n () => reader.read(filePath),\n () => reader.readSync(filePath),\n );\n\n if (!isObject(pkg)) {\n throw new LocterWriteError({\n message: 'The located package.json does not contain an object.',\n path: filePath,\n });\n }\n\n pkg[field] = value;\n\n // dedicated writer instance: keeps the indentation (and the built-in\n // registry writer's configuration untouched)\n const writer = new JSONWriter({ indent: 'auto' });\n yield* op(\n () => writer.write(filePath, pkg),\n () => writer.writeSync(filePath, pkg),\n );\n}\n\n/**\n * Set a top-level field of the nearest `package.json` (same locate\n * semantics as readPackageField) and write it back, preserving the\n * file's existing indentation. Passing `undefined` removes the field.\n * Throws LocterNotFoundError when no package.json could be located.\n */\nexport async function writePackageField(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : Promise<void> {\n return runTwinAsync(writePackageFieldBody(field, value, options));\n}\n\nexport function writePackageFieldSync(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : void {\n runTwinSync(writePackageFieldBody(field, value, options));\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locter",
3
- "version": "4.0.0-beta.0",
3
+ "version": "4.0.0-beta.1",
4
4
  "type": "module",
5
5
  "description": "A library to locate files/modules by criteria, read them and write them back!",
6
6
  "author": {