locter 4.0.0-beta.0 → 4.0.0-beta.2
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 +74 -51
- package/dist/index.d.mts +45 -6
- package/dist/index.mjs +69 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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`);
|
|
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.
|
|
@@ -173,57 +173,71 @@ If both flags are set, `onlyDirectories: true` takes precedence over `onlyFiles`
|
|
|
173
173
|
|
|
174
174
|
`locateUp` / `locateUpSync` take the same options except `cwd` must be a single `string`, and additionally accept `stopAt?: string` (inclusive ceiling for the walk).
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
**File-name helpers**
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
Either a string or the output of the locate/locateSync method can be passed as argument.
|
|
178
|
+
Two small helpers for working with the extensions locter routes on:
|
|
180
179
|
|
|
181
180
|
```typescript
|
|
182
|
-
import {
|
|
183
|
-
|
|
184
|
-
(async () => {
|
|
185
|
-
const file = await locate(
|
|
186
|
-
'files/example.{js,.ts}'
|
|
187
|
-
);
|
|
181
|
+
import { getFileNameExtension, removeFileNameExtension } from 'locter';
|
|
188
182
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// ...
|
|
183
|
+
getFileNameExtension('seed.ts'); // '.ts'
|
|
184
|
+
getFileNameExtension('seed.ts', ['.js', '.mjs']); // undefined (not allowed)
|
|
192
185
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
// ...
|
|
196
|
-
})
|
|
186
|
+
removeFileNameExtension('seed.ts'); // 'seed'
|
|
187
|
+
removeFileNameExtension('seed.ts', ['.js']); // 'seed.ts' (not matched)
|
|
197
188
|
```
|
|
198
189
|
|
|
199
|
-
|
|
190
|
+
### Reader
|
|
191
|
+
|
|
192
|
+
Two verbs, two shapes:
|
|
193
|
+
|
|
194
|
+
- **`read`** — *raw*: the plain parsed value for data formats (JSON/YAML/Conf
|
|
195
|
+
and custom readers) — mutable and round-trip-symmetric with `write`. For
|
|
196
|
+
modules it returns the normalized module record: a module *is* a record,
|
|
197
|
+
and the normalization only irons out the CJS/ESM interop divergence so
|
|
198
|
+
`read` and `readSync` agree on one shape.
|
|
199
|
+
- **`readAsModule`** — everything as a *module record*: the uniform, frozen
|
|
200
|
+
record shape regardless of format — for export inspection, interop, and
|
|
201
|
+
uniform handling of mixed-extension config.
|
|
202
|
+
|
|
203
|
+
Either a string or the output of the locate/locateSync method can be passed
|
|
204
|
+
as argument; both verbs have `*Sync` twins.
|
|
200
205
|
|
|
201
206
|
```typescript
|
|
202
|
-
import {
|
|
207
|
+
import { locate, read, readSync } from 'locter';
|
|
208
|
+
|
|
209
|
+
(async () => {
|
|
210
|
+
const config = await read('config.yml');
|
|
211
|
+
// → the plain parsed value: { port: 3000, ... } — mutable,
|
|
212
|
+
// round-trip-symmetric with write()
|
|
203
213
|
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
214
|
+
const settings = await read('trapi.config.ts');
|
|
215
|
+
// → the module as a normalized record; unwrap explicitly:
|
|
216
|
+
// settings.default
|
|
207
217
|
|
|
208
|
-
const
|
|
218
|
+
const file = await locate('files/example.{js,.ts}');
|
|
219
|
+
const content = readSync(file); // sync twin
|
|
220
|
+
})
|
|
209
221
|
```
|
|
210
222
|
|
|
211
223
|
Bare module specifiers (no file extension) are routed to the module reader, so
|
|
212
224
|
`read('yaml')` behaves like `import('yaml')` — note that reading a module
|
|
213
225
|
**executes** it.
|
|
214
226
|
|
|
215
|
-
**Module records
|
|
227
|
+
**Module records — `readAsModule`**
|
|
216
228
|
|
|
217
|
-
Every `
|
|
218
|
-
null-prototype object shaped like an ES module namespace: `default`
|
|
219
|
-
holds the loaded value, and when that value is an object, its
|
|
220
|
-
are re-exposed as named exports.
|
|
229
|
+
Every `readAsModule` / `readAsModuleSync` result is a **module record** — a
|
|
230
|
+
frozen, null-prototype object shaped like an ES module namespace: `default`
|
|
231
|
+
always holds the loaded value, and when that value is an object, its
|
|
232
|
+
top-level keys are re-exposed as named exports. For modules, `read` and
|
|
233
|
+
`readAsModule` agree; for data formats, `read` returns what
|
|
234
|
+
`readAsModule(...).default` holds.
|
|
221
235
|
|
|
222
236
|
```typescript
|
|
223
|
-
import {
|
|
237
|
+
import { readAsModule } from 'locter';
|
|
224
238
|
|
|
225
239
|
(async () => {
|
|
226
|
-
const pkg = await
|
|
240
|
+
const pkg = await readAsModule('package.json');
|
|
227
241
|
|
|
228
242
|
console.log(pkg.default); // the full parsed JSON value
|
|
229
243
|
console.log(pkg.version); // top-level keys are named exports
|
|
@@ -233,21 +247,23 @@ import { read } from 'locter';
|
|
|
233
247
|
For JavaScript/TypeScript files the module's own namespace passes through
|
|
234
248
|
unchanged; the output of every other reader (built-in JSON/YAML/Conf and
|
|
235
249
|
user-registered ones) is always wrapped — even if the parsed data happens to
|
|
236
|
-
contain an `__esModule` key
|
|
237
|
-
data
|
|
250
|
+
contain an `__esModule` key (`read` of such data likewise returns it
|
|
251
|
+
untouched — a literal `__esModule` key never turns data into a module).
|
|
252
|
+
The record is read-only: to mutate the loaded data, work with `.default`
|
|
253
|
+
(for data records that is the same object `read` returns).
|
|
238
254
|
|
|
239
255
|
Records additionally carry a private, non-forgeable brand: `isModuleRecord`
|
|
240
|
-
tells records produced by `
|
|
256
|
+
tells records produced by `readAsModule()` apart from arbitrary data, and
|
|
241
257
|
[`write`](#writer) uses the brand to unwrap `.default` automatically on
|
|
242
258
|
write-back.
|
|
243
259
|
|
|
244
260
|
To pick an export by predicate, the `getModuleExport` helper is available:
|
|
245
261
|
|
|
246
262
|
```typescript
|
|
247
|
-
import { getModuleExport,
|
|
263
|
+
import { getModuleExport, readAsModule } from 'locter';
|
|
248
264
|
|
|
249
265
|
(async () => {
|
|
250
|
-
const record = await
|
|
266
|
+
const record = await readAsModule('files/example.ts');
|
|
251
267
|
|
|
252
268
|
const found = getModuleExport(record, (key) => key === 'myExport');
|
|
253
269
|
// → { key: 'myExport', value: ... }, or undefined if no key matches
|
|
@@ -286,15 +302,19 @@ The `write` method serializes a value to a file, dispatched by extension like
|
|
|
286
302
|
application:
|
|
287
303
|
|
|
288
304
|
```typescript
|
|
289
|
-
import { read, write } from 'locter';
|
|
305
|
+
import { read, readAsModule, write } from 'locter';
|
|
290
306
|
|
|
291
307
|
(async () => {
|
|
308
|
+
// read → modify → write, fully symmetric
|
|
292
309
|
const config = await read('config.yml');
|
|
293
|
-
config.
|
|
310
|
+
config.port = 8080;
|
|
311
|
+
await write('config.yml', config);
|
|
294
312
|
|
|
295
|
-
// records produced by
|
|
313
|
+
// records produced by readAsModule() are unwrapped automatically —
|
|
296
314
|
// the file receives the plain value, not the record wrapper
|
|
297
|
-
await
|
|
315
|
+
const record = await readAsModule('config.yml');
|
|
316
|
+
record.default.port = 8080;
|
|
317
|
+
await write('config.yml', record);
|
|
298
318
|
|
|
299
319
|
// plain values work just as well
|
|
300
320
|
await write('generated/settings.json', { port: 8080 });
|
|
@@ -307,7 +327,7 @@ Write semantics:
|
|
|
307
327
|
|
|
308
328
|
- **Missing parent directories are created** (`mkdir -p`).
|
|
309
329
|
- Output always ends with a single trailing newline.
|
|
310
|
-
- Values that are records produced by `
|
|
330
|
+
- Values that are records produced by `readAsModule()` (detected via the private
|
|
311
331
|
brand — an `__esModule` key in plain data does **not** count) are unwrapped
|
|
312
332
|
to their `.default` value before serialization.
|
|
313
333
|
- Module formats (`.js`, `.ts`, …) are **read-only**: `write('config.ts', …)`
|
|
@@ -576,7 +596,7 @@ The list below is exhaustive — no other public APIs changed.
|
|
|
576
596
|
|
|
577
597
|
| 3.x | 4.x |
|
|
578
598
|
|--------------------------------------|--------------------------------------------|
|
|
579
|
-
| `load` / `loadSync`
|
|
599
|
+
| `load` / `loadSync` | `read` / `readSync` (raw: plain data values / module records) or `readAsModule` / `readAsModuleSync` (everything as a module record) |
|
|
580
600
|
| `registerLoader` / `unregisterLoader`| `registerFormat` / `unregisterFormat` |
|
|
581
601
|
| `LoaderManager` | `FormatRegistry` |
|
|
582
602
|
| `useLoader` | `useFormatRegistry` |
|
|
@@ -612,17 +632,20 @@ The list below is exhaustive — no other public APIs changed.
|
|
|
612
632
|
+ registry.findReader('file.json'); // IReader | undefined
|
|
613
633
|
+ registry.builtInReader('module'); // statically typed as ModuleReader
|
|
614
634
|
|
|
615
|
-
// 4.
|
|
616
|
-
//
|
|
617
|
-
//
|
|
618
|
-
//
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
635
|
+
// 4. Two verbs replace 3.x load(): read() is RAW (the plain parsed
|
|
636
|
+
// value for data — 3.x data loads map to read() nearly 1:1 — and
|
|
637
|
+
// the normalized record for modules), while readAsModule() returns
|
|
638
|
+
// a frozen, null-prototype module record for EVERY format (see
|
|
639
|
+
// "Module records" above).
|
|
640
|
+
const value = await read('package.json');
|
|
641
|
+
value.version; // the plain parsed JSON
|
|
642
|
+
|
|
643
|
+
const pkg = await readAsModule('package.json');
|
|
644
|
+
pkg.version; // top-level keys as named exports
|
|
622
645
|
+ pkg.default; // the full parsed value
|
|
623
646
|
+ // The record is frozen and null-prototype: code that mutates the
|
|
624
647
|
+ // result, relies on Object.prototype, or enumerates/serializes it
|
|
625
|
-
+ //
|
|
648
|
+
+ // must use pkg.default (or read()) instead.
|
|
626
649
|
|
|
627
650
|
// 5. ModuleReader.read() / readSync() return the raw module value;
|
|
628
651
|
// normalization happens exactly once, at the registry boundary. Only
|
|
@@ -635,8 +658,8 @@ The list below is exhaustive — no other public APIs changed.
|
|
|
635
658
|
**Removed from the public surface** (internal plumbing that leaked through the old `export *` barrels; the package now exports a curated, snapshot-tested list):
|
|
636
659
|
|
|
637
660
|
- Locator internals: `buildLocatorPatterns`, `buildLocatorOptions`, `pathToLocatorInfo`, `buildFilePathWithoutExtension` (deleted — it had no callers). `buildFilePath` and `isLocatorInfo` stay public.
|
|
638
|
-
- Record internals: `isESModule`, `toModuleRecord`, `createModuleRecord`. Use `
|
|
639
|
-
- Generic helpers: `isObject`, `isSafeObjectKey`, `hasOwnProperty`, `hasStringProperty`, `toArray`, `isFilePath`, `getFileNameExtension
|
|
661
|
+
- Record internals: `isESModule`, `toModuleRecord`, `createModuleRecord`. Use `readAsModule()` (which normalizes) / `read()` (raw) and the public `getModuleExport` / `isModuleRecord`.
|
|
662
|
+
- Generic helpers: `isObject`, `isSafeObjectKey`, `hasOwnProperty`, `hasStringProperty`, `toArray`, `isFilePath`, `isTypeScriptError`. The domain helpers stay public: `getFileNameExtension` / `removeFileNameExtension` (see [File-name helpers](#file-name-helpers)) and the runtime detection helpers (`isJestRuntimeEnvironment`, `isVitestRuntimeEnvironment`, `isTsNodeRuntimeEnvironment`, `isTsxRuntimeEnvironment`).
|
|
640
663
|
|
|
641
664
|
**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).
|
|
642
665
|
|
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
|
-
*
|
|
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
|
|
454
|
-
* detected) is unwrapped to its `.default` value;
|
|
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
|
|
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
|
/**
|
|
@@ -553,11 +588,15 @@ declare function readPackageFieldSync<T = unknown>(field: string, options?: Read
|
|
|
553
588
|
declare function writePackageField(field: string, value: unknown, options?: WritePackageFieldOptions): Promise<void>;
|
|
554
589
|
declare function writePackageFieldSync(field: string, value: unknown, options?: WritePackageFieldOptions): void;
|
|
555
590
|
//#endregion
|
|
591
|
+
//#region src/utils/file-name.d.ts
|
|
592
|
+
declare function getFileNameExtension(input: string, allowed?: string[]): string | undefined;
|
|
593
|
+
declare function removeFileNameExtension(input: string, extensions?: string[]): string;
|
|
594
|
+
//#endregion
|
|
556
595
|
//#region src/utils/runtime.d.ts
|
|
557
596
|
declare function isJestRuntimeEnvironment(): boolean;
|
|
558
597
|
declare function isVitestRuntimeEnvironment(): boolean;
|
|
559
598
|
declare function isTsNodeRuntimeEnvironment(): boolean;
|
|
560
599
|
declare function isTsxRuntimeEnvironment(): boolean;
|
|
561
600
|
//#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 };
|
|
601
|
+
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, getFileNameExtension, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, removeFileNameExtension, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
|
|
563
602
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -62,6 +62,18 @@ var LocterUnknownExtensionError = class extends LocterError {
|
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
//#endregion
|
|
65
|
+
//#region src/utils/file-name.ts
|
|
66
|
+
function getFileNameExtension(input, allowed) {
|
|
67
|
+
const extension = path.extname(input);
|
|
68
|
+
if (extension === "" || extension === ".") return;
|
|
69
|
+
if (typeof allowed === "undefined" || allowed.includes(extension)) return extension;
|
|
70
|
+
}
|
|
71
|
+
function removeFileNameExtension(input, extensions) {
|
|
72
|
+
const extension = getFileNameExtension(input, extensions);
|
|
73
|
+
if (extension) return input.substring(0, input.length - extension.length);
|
|
74
|
+
return input;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
65
77
|
//#region src/utils/has-property.ts
|
|
66
78
|
function hasOwnProperty(obj, prop) {
|
|
67
79
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
@@ -876,6 +888,13 @@ var FormatRegistry = class {
|
|
|
876
888
|
this.builtInWriterCache.clear();
|
|
877
889
|
this.ruleCounter = 0;
|
|
878
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* Read a file/module RAW: the plain parsed value for data formats
|
|
893
|
+
* (mutable, round-trip-symmetric with write); for modules the
|
|
894
|
+
* normalized module record — a module IS a record, and the
|
|
895
|
+
* normalization only irons out the CJS/ESM interop divergence so
|
|
896
|
+
* both twin variants agree on one shape.
|
|
897
|
+
*/
|
|
879
898
|
async read(input) {
|
|
880
899
|
return runTwinAsync(this.readBody(input));
|
|
881
900
|
}
|
|
@@ -883,15 +902,39 @@ var FormatRegistry = class {
|
|
|
883
902
|
return runTwinSync(this.readBody(input));
|
|
884
903
|
}
|
|
885
904
|
/**
|
|
886
|
-
*
|
|
905
|
+
* Read a file/module and present the result as a normalized module
|
|
906
|
+
* record — the uniform, frozen shape regardless of format:
|
|
907
|
+
* `.default` always holds the loaded value, top-level keys are
|
|
908
|
+
* re-exposed as named exports.
|
|
887
909
|
*/
|
|
910
|
+
async readAsModule(input) {
|
|
911
|
+
return runTwinAsync(this.readAsModuleBody(input));
|
|
912
|
+
}
|
|
913
|
+
readAsModuleSync(input) {
|
|
914
|
+
return runTwinSync(this.readAsModuleBody(input));
|
|
915
|
+
}
|
|
888
916
|
*readBody(input) {
|
|
917
|
+
const { output, reader } = yield* this.executeBody(input);
|
|
918
|
+
if (reader instanceof ModuleReader) return toModuleRecord(output);
|
|
919
|
+
return output;
|
|
920
|
+
}
|
|
921
|
+
*readAsModuleBody(input) {
|
|
922
|
+
const { output, reader } = yield* this.executeBody(input);
|
|
923
|
+
return this.toRecord(output, reader);
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Shared dispatch + execution of both read bodies: resolve the
|
|
927
|
+
* reader, run it, wrap errors. Normalization is the caller's call.
|
|
928
|
+
*/
|
|
929
|
+
*executeBody(input) {
|
|
889
930
|
const filePath = buildFilePath(input);
|
|
890
931
|
const reader = this.findReader(filePath);
|
|
891
932
|
if (!reader) throw this.unknownExtensionError(filePath);
|
|
892
933
|
try {
|
|
893
|
-
|
|
894
|
-
|
|
934
|
+
return {
|
|
935
|
+
output: yield* op(() => reader.read(filePath), () => reader.readSync(filePath)),
|
|
936
|
+
reader
|
|
937
|
+
};
|
|
895
938
|
} catch (e) {
|
|
896
939
|
throw wrapLoaderError(e, filePath);
|
|
897
940
|
}
|
|
@@ -904,9 +947,9 @@ var FormatRegistry = class {
|
|
|
904
947
|
}
|
|
905
948
|
/**
|
|
906
949
|
* Shared body of write/writeSync: dispatch, unwrap records, write, wrap.
|
|
907
|
-
* The inverse boundary of
|
|
908
|
-
* detected) is unwrapped to its `.default` value;
|
|
909
|
-
* written as-is.
|
|
950
|
+
* The inverse boundary of readAsModuleBody: a record produced by
|
|
951
|
+
* readAsModule() (brand detected) is unwrapped to its `.default` value;
|
|
952
|
+
* anything else is written as-is.
|
|
910
953
|
*/
|
|
911
954
|
*writeBody(input, value) {
|
|
912
955
|
const filePath = buildFilePath(input);
|
|
@@ -930,7 +973,7 @@ var FormatRegistry = class {
|
|
|
930
973
|
}
|
|
931
974
|
}
|
|
932
975
|
/**
|
|
933
|
-
* The single normalization boundary: every
|
|
976
|
+
* The single normalization boundary: every readAsModule result becomes a module
|
|
934
977
|
* record (`.default` is always the loaded value, top-level keys stay
|
|
935
978
|
* accessible as named exports). Provenance decides how: module-reader
|
|
936
979
|
* output may legitimately already be a record (`__esModule` is meaningful
|
|
@@ -1054,12 +1097,30 @@ function registerFormat(rule) {
|
|
|
1054
1097
|
function unregisterFormat(id) {
|
|
1055
1098
|
return useFormatRegistry().unregister(id);
|
|
1056
1099
|
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Read a file/module RAW: the plain parsed value for data formats
|
|
1102
|
+
* (json/yaml/conf and custom readers — mutable, round-trip-symmetric
|
|
1103
|
+
* with write); for modules the normalized module record (a module IS a
|
|
1104
|
+
* record; normalization only irons out CJS/ESM interop divergence).
|
|
1105
|
+
*/
|
|
1057
1106
|
async function read(input) {
|
|
1058
1107
|
return useFormatRegistry().read(input);
|
|
1059
1108
|
}
|
|
1060
1109
|
function readSync(input) {
|
|
1061
1110
|
return useFormatRegistry().readSync(input);
|
|
1062
1111
|
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Read a file/module and present the result as a normalized module
|
|
1114
|
+
* record — the uniform, frozen shape regardless of format: `.default`
|
|
1115
|
+
* always holds the loaded value, top-level keys are re-exposed as
|
|
1116
|
+
* named exports.
|
|
1117
|
+
*/
|
|
1118
|
+
async function readAsModule(input) {
|
|
1119
|
+
return useFormatRegistry().readAsModule(input);
|
|
1120
|
+
}
|
|
1121
|
+
function readAsModuleSync(input) {
|
|
1122
|
+
return useFormatRegistry().readAsModuleSync(input);
|
|
1123
|
+
}
|
|
1063
1124
|
async function write(input, value) {
|
|
1064
1125
|
return useFormatRegistry().write(input, value);
|
|
1065
1126
|
}
|
|
@@ -1159,6 +1220,6 @@ function writePackageFieldSync(field, value, options = {}) {
|
|
|
1159
1220
|
runTwinSync(writePackageFieldBody(field, value, options));
|
|
1160
1221
|
}
|
|
1161
1222
|
//#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 };
|
|
1223
|
+
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, getFileNameExtension, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, removeFileNameExtension, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
|
|
1163
1224
|
|
|
1164
1225
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -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":"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"}
|
|
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/file-name.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","/*\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';\n\nexport function getFileNameExtension(\n input: string,\n allowed?: string[],\n) : string | undefined {\n const extension = path.extname(input);\n if (extension === '' || extension === '.') {\n return undefined;\n }\n\n if (\n typeof allowed === 'undefined' ||\n allowed.includes(extension)\n ) {\n return extension;\n }\n\n return undefined;\n}\n\nexport function removeFileNameExtension(\n input: string,\n extensions?: string[],\n) {\n const extension = getFileNameExtension(input, extensions);\n if (extension) {\n return input.substring(0, input.length - extension.length);\n }\n\n return input;\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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"}
|