locter 4.1.0 → 4.1.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/dist/index.d.mts +1 -88
- package/dist/index.mjs +58 -119
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseError, ErrorOptions } from "@ebec/core";
|
|
2
|
+
import { TwinBody } from "twinop";
|
|
2
3
|
import { createJiti } from "jiti";
|
|
3
4
|
import { ToStringOptions } from "yaml";
|
|
4
|
-
//#region src/errors/base.d.ts
|
|
5
5
|
type LocterErrorOptions = ErrorOptions & {
|
|
6
6
|
path?: string;
|
|
7
7
|
};
|
|
@@ -12,40 +12,28 @@ declare class LocterError extends BaseError {
|
|
|
12
12
|
readonly path?: string;
|
|
13
13
|
constructor(input?: LocterErrorInput);
|
|
14
14
|
}
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/errors/load.d.ts
|
|
17
15
|
declare const LOCTER_LOAD_ERROR_MARKER: unique symbol;
|
|
18
16
|
declare class LoadError extends LocterError {
|
|
19
17
|
static [Symbol.hasInstance](input: unknown): boolean;
|
|
20
18
|
constructor(input?: LocterErrorInput);
|
|
21
19
|
}
|
|
22
|
-
//#endregion
|
|
23
|
-
//#region src/errors/not-found.d.ts
|
|
24
20
|
declare const LOCTER_NOT_FOUND_ERROR_MARKER: unique symbol;
|
|
25
21
|
declare class NotFoundError extends LocterError {
|
|
26
22
|
static [Symbol.hasInstance](input: unknown): boolean;
|
|
27
23
|
constructor(input?: LocterErrorInput);
|
|
28
24
|
}
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/errors/unknown-extension.d.ts
|
|
31
25
|
declare const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER: unique symbol;
|
|
32
26
|
declare class UnknownExtensionError extends LocterError {
|
|
33
27
|
static [Symbol.hasInstance](input: unknown): boolean;
|
|
34
28
|
constructor(input?: LocterErrorInput);
|
|
35
29
|
}
|
|
36
|
-
//#endregion
|
|
37
|
-
//#region src/errors/wrap.d.ts
|
|
38
30
|
declare function wrapLoaderError(input: unknown, path: string): LocterError;
|
|
39
31
|
declare function wrapWriteError(input: unknown, path: string): LocterError;
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region src/errors/write.d.ts
|
|
42
32
|
declare const LOCTER_WRITE_ERROR_MARKER: unique symbol;
|
|
43
33
|
declare class WriteError extends LocterError {
|
|
44
34
|
static [Symbol.hasInstance](input: unknown): boolean;
|
|
45
35
|
constructor(input?: LocterErrorInput);
|
|
46
36
|
}
|
|
47
|
-
//#endregion
|
|
48
|
-
//#region src/locator/types.d.ts
|
|
49
37
|
type LocatorInfo = {
|
|
50
38
|
directory: string;
|
|
51
39
|
name: string;
|
|
@@ -63,46 +51,18 @@ type LocatorOptionsInput = Partial<Omit<LocatorOptions, 'cwd' | 'ignore'>> & {
|
|
|
63
51
|
cwd?: string | string[];
|
|
64
52
|
ignore?: string | string[];
|
|
65
53
|
};
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/locator/async.d.ts
|
|
68
54
|
declare function locateMany(pattern: string | string[], options?: LocatorOptionsInput): Promise<LocatorInfo[]>;
|
|
69
55
|
declare function locate(pattern: string | string[], options?: LocatorOptionsInput): Promise<LocatorInfo | undefined>;
|
|
70
|
-
//#endregion
|
|
71
|
-
//#region src/locator/sync.d.ts
|
|
72
56
|
declare function locateManySync(pattern: string | string[], options?: LocatorOptionsInput): LocatorInfo[];
|
|
73
57
|
declare function locateSync(pattern: string | string[], options?: LocatorOptionsInput): LocatorInfo | undefined;
|
|
74
|
-
//#endregion
|
|
75
|
-
//#region src/locator/up.d.ts
|
|
76
58
|
type LocatorUpOptionsInput = Omit<LocatorOptionsInput, 'cwd'> & {
|
|
77
59
|
cwd?: string;
|
|
78
60
|
stopAt?: string;
|
|
79
61
|
};
|
|
80
62
|
declare function locateUp(pattern: string | string[], options?: LocatorUpOptionsInput): Promise<LocatorInfo | undefined>;
|
|
81
63
|
declare function locateUpSync(pattern: string | string[], options?: LocatorUpOptionsInput): LocatorInfo | undefined;
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/locator/utils.d.ts
|
|
84
64
|
declare function isLocatorInfo(input: unknown): input is LocatorInfo;
|
|
85
65
|
declare function buildFilePath(input: LocatorInfo | string): string;
|
|
86
|
-
//#endregion
|
|
87
|
-
//#region src/utils/twin.d.ts
|
|
88
|
-
/**
|
|
89
|
-
* Internal protocol to derive the parallel sync + async public surfaces
|
|
90
|
-
* from one shared body. A body is a generator that yields effect pairs —
|
|
91
|
-
* an async and a sync thunk for the same operation — and the two drivers
|
|
92
|
-
* (runTwinAsync / runTwinSync) execute the side they stand for. Effect
|
|
93
|
-
* errors are re-entered into the body via `Generator.throw`, so try/catch
|
|
94
|
-
* inside a body behaves identically in both variants.
|
|
95
|
-
*
|
|
96
|
-
* Deliberately NOT exported from the utils barrel — this is internal
|
|
97
|
-
* plumbing, not public API.
|
|
98
|
-
*/
|
|
99
|
-
type TwinOp<T = unknown> = {
|
|
100
|
-
async: () => Promise<T>;
|
|
101
|
-
sync: () => T;
|
|
102
|
-
};
|
|
103
|
-
type TwinBody<R> = Generator<TwinOp<any>, R, any>;
|
|
104
|
-
//#endregion
|
|
105
|
-
//#region src/format/type.d.ts
|
|
106
66
|
interface IReader {
|
|
107
67
|
read: (input: string) => Promise<any>;
|
|
108
68
|
readSync: (input: string) => any;
|
|
@@ -111,8 +71,6 @@ interface IWriter {
|
|
|
111
71
|
write: (path: string, value: unknown) => Promise<void>;
|
|
112
72
|
writeSync: (path: string, value: unknown) => void;
|
|
113
73
|
}
|
|
114
|
-
//#endregion
|
|
115
|
-
//#region src/format/text-file/reader.d.ts
|
|
116
74
|
/**
|
|
117
75
|
* Base class for readers of text-based file formats: reads the file as
|
|
118
76
|
* UTF-8, delegates to `parse`, and wraps I/O and parse errors in typed
|
|
@@ -125,8 +83,6 @@ declare abstract class TextFileReader implements IReader {
|
|
|
125
83
|
readSync(input: string): any;
|
|
126
84
|
protected body(input: string): TwinBody<any>;
|
|
127
85
|
}
|
|
128
|
-
//#endregion
|
|
129
|
-
//#region src/format/text-file/writer.d.ts
|
|
130
86
|
/**
|
|
131
87
|
* Base class for writers of text-based file formats: serializes via
|
|
132
88
|
* `stringify`, creates missing parent directories, writes the file as
|
|
@@ -147,13 +103,9 @@ declare abstract class TextFileWriter implements IWriter {
|
|
|
147
103
|
writeSync(input: string, value: unknown): void;
|
|
148
104
|
protected body(input: string, value: unknown): TwinBody<void>;
|
|
149
105
|
}
|
|
150
|
-
//#endregion
|
|
151
|
-
//#region src/format/built-in/conf/reader.d.ts
|
|
152
106
|
declare class ConfReader extends TextFileReader {
|
|
153
107
|
parse(contents: string): Record<string, any>;
|
|
154
108
|
}
|
|
155
|
-
//#endregion
|
|
156
|
-
//#region src/format/built-in/conf/writer.d.ts
|
|
157
109
|
/**
|
|
158
110
|
* Serializes an object to `key=value` lines (the inverse of ConfReader):
|
|
159
111
|
* nested objects become dot-separated keys, arrays become repeated
|
|
@@ -165,13 +117,9 @@ declare class ConfReader extends TextFileReader {
|
|
|
165
117
|
declare class ConfWriter extends TextFileWriter {
|
|
166
118
|
stringify(value: unknown): string;
|
|
167
119
|
}
|
|
168
|
-
//#endregion
|
|
169
|
-
//#region src/format/built-in/json/reader.d.ts
|
|
170
120
|
declare class JSONReader extends TextFileReader {
|
|
171
121
|
parse(content: string): any;
|
|
172
122
|
}
|
|
173
|
-
//#endregion
|
|
174
|
-
//#region src/format/built-in/json/writer.d.ts
|
|
175
123
|
type JSONWriterOptions = {
|
|
176
124
|
/**
|
|
177
125
|
* Indentation of the emitted JSON. A number of spaces, a literal
|
|
@@ -188,15 +136,11 @@ declare class JSONWriter extends TextFileWriter {
|
|
|
188
136
|
protected get usesExistingContent(): boolean;
|
|
189
137
|
stringify(value: unknown, existing?: string): string;
|
|
190
138
|
}
|
|
191
|
-
//#endregion
|
|
192
|
-
//#region src/format/built-in/module/constants.d.ts
|
|
193
139
|
/**
|
|
194
140
|
* Single source of truth for the extensions handled by the module loader:
|
|
195
141
|
* consumed by BOTH the built-in routing registry and the jiti config.
|
|
196
142
|
*/
|
|
197
143
|
declare const MODULE_FILE_EXTENSIONS: readonly [".js", ".mjs", ".mts", ".cjs", ".cts", ".ts"];
|
|
198
|
-
//#endregion
|
|
199
|
-
//#region src/format/built-in/module/type.d.ts
|
|
200
144
|
type ModuleExportFilterFn = (key: string, value: unknown) => boolean;
|
|
201
145
|
type ModuleExport = {
|
|
202
146
|
key: string;
|
|
@@ -222,8 +166,6 @@ type ModuleReaderOptions = {
|
|
|
222
166
|
*/
|
|
223
167
|
loadSync?: ModuleLoadSyncFn;
|
|
224
168
|
};
|
|
225
|
-
//#endregion
|
|
226
|
-
//#region src/format/built-in/module/reader.d.ts
|
|
227
169
|
type Jiti = ReturnType<typeof createJiti>;
|
|
228
170
|
declare class ModuleReader implements IReader {
|
|
229
171
|
protected instance: Jiti;
|
|
@@ -253,8 +195,6 @@ declare class ModuleReader implements IReader {
|
|
|
253
195
|
loadSync(data: LocatorInfo | string, options?: ModuleLoadOptions): unknown;
|
|
254
196
|
private build;
|
|
255
197
|
}
|
|
256
|
-
//#endregion
|
|
257
|
-
//#region src/format/built-in/module/utils.d.ts
|
|
258
198
|
/**
|
|
259
199
|
* True when the value is a record produced by locter's read()/toModuleRecord.
|
|
260
200
|
* Detection is brand-based; a plain object with an `__esModule` key is NOT
|
|
@@ -262,8 +202,6 @@ declare class ModuleReader implements IReader {
|
|
|
262
202
|
*/
|
|
263
203
|
declare function isModuleRecord(input: unknown): input is Record<string, any>;
|
|
264
204
|
declare function getModuleExport(data: Record<string, any>, filterFn: ModuleExportFilterFn): ModuleExport | undefined;
|
|
265
|
-
//#endregion
|
|
266
|
-
//#region src/format/built-in/text/reader.d.ts
|
|
267
205
|
/**
|
|
268
206
|
* Raw text: the file content, as-is. No value coercion — a .txt
|
|
269
207
|
* containing '123' reads as the string '123' (use deserializeValue
|
|
@@ -272,8 +210,6 @@ declare function getModuleExport(data: Record<string, any>, filterFn: ModuleExpo
|
|
|
272
210
|
declare class TextReader extends TextFileReader {
|
|
273
211
|
parse(content: string): string;
|
|
274
212
|
}
|
|
275
|
-
//#endregion
|
|
276
|
-
//#region src/format/built-in/text/writer.d.ts
|
|
277
213
|
/**
|
|
278
214
|
* Raw text: accepts strings only — coercing arbitrary values would be
|
|
279
215
|
* lossy ([object Object]); serialize explicitly (e.g. serializeValue)
|
|
@@ -283,13 +219,9 @@ declare class TextReader extends TextFileReader {
|
|
|
283
219
|
declare class TextWriter extends TextFileWriter {
|
|
284
220
|
stringify(value: unknown): string;
|
|
285
221
|
}
|
|
286
|
-
//#endregion
|
|
287
|
-
//#region src/format/built-in/yaml/reader.d.ts
|
|
288
222
|
declare class YAMLReader extends TextFileReader {
|
|
289
223
|
parse(content: string): any;
|
|
290
224
|
}
|
|
291
|
-
//#endregion
|
|
292
|
-
//#region src/format/built-in/yaml/writer.d.ts
|
|
293
225
|
type YAMLWriterOptions = ToStringOptions;
|
|
294
226
|
/**
|
|
295
227
|
* Writes YAML preserving hand-edited structure where possible: when the
|
|
@@ -305,8 +237,6 @@ declare class YAMLWriter extends TextFileWriter {
|
|
|
305
237
|
protected get usesExistingContent(): boolean;
|
|
306
238
|
stringify(value: unknown, existing?: string): string;
|
|
307
239
|
}
|
|
308
|
-
//#endregion
|
|
309
|
-
//#region src/format/built-in/registry.d.ts
|
|
310
240
|
/**
|
|
311
241
|
* Every built-in format, in one place. Keys are the format ids; each entry
|
|
312
242
|
* couples routing and construction. The id union, the extension → format
|
|
@@ -351,8 +281,6 @@ type WritableBuiltInFormatId = { [K in BuiltInFormatId]: (typeof BUILT_IN_PRESET
|
|
|
351
281
|
writer: () => IWriter;
|
|
352
282
|
} ? K : never; }[BuiltInFormatId];
|
|
353
283
|
type BuiltInWriterOf<K extends WritableBuiltInFormatId> = ReturnType<(typeof BUILT_IN_PRESETS)[K]['writer']>;
|
|
354
|
-
//#endregion
|
|
355
|
-
//#region src/format/registry/type.d.ts
|
|
356
284
|
/**
|
|
357
285
|
* Lazy reader construction. Invoked on the first input that matches the
|
|
358
286
|
* rule it was registered for; the first successfully constructed reader
|
|
@@ -438,8 +366,6 @@ type FormatPreset = {
|
|
|
438
366
|
/** Lazy writer factory — invoked at most once per FormatRegistry instance. */
|
|
439
367
|
writer?: () => IWriter;
|
|
440
368
|
};
|
|
441
|
-
//#endregion
|
|
442
|
-
//#region src/format/registry/module.d.ts
|
|
443
369
|
type FormatRegistryOptions = {
|
|
444
370
|
/**
|
|
445
371
|
* Seed user rules (matched before built-ins, in array order).
|
|
@@ -594,11 +520,7 @@ declare class FormatRegistry {
|
|
|
594
520
|
protected compile(id: string, rule: Rule): CompiledRule;
|
|
595
521
|
protected generateRuleId(): string;
|
|
596
522
|
}
|
|
597
|
-
//#endregion
|
|
598
|
-
//#region src/format/registry/singleton.d.ts
|
|
599
523
|
declare function useFormatRegistry(): FormatRegistry;
|
|
600
|
-
//#endregion
|
|
601
|
-
//#region src/format/helpers.d.ts
|
|
602
524
|
declare function registerFormat(rule: Rule): FormatRegistration;
|
|
603
525
|
/**
|
|
604
526
|
* Remove a rule from the process-global registry by its id
|
|
@@ -657,8 +579,6 @@ declare function writeSync(input: LocatorInfo | string, value: unknown, options?
|
|
|
657
579
|
* ```
|
|
658
580
|
*/
|
|
659
581
|
declare function setModuleReader(options: ModuleReaderOptions): () => void;
|
|
660
|
-
//#endregion
|
|
661
|
-
//#region src/format/package-field.d.ts
|
|
662
582
|
type ReadPackageFieldOptions = {
|
|
663
583
|
cwd?: string;
|
|
664
584
|
walkUp?: boolean;
|
|
@@ -675,8 +595,6 @@ declare function readPackageFieldSync<T = unknown>(field: string, options?: Read
|
|
|
675
595
|
*/
|
|
676
596
|
declare function writePackageField(field: string, value: unknown, options?: WritePackageFieldOptions): Promise<void>;
|
|
677
597
|
declare function writePackageFieldSync(field: string, value: unknown, options?: WritePackageFieldOptions): void;
|
|
678
|
-
//#endregion
|
|
679
|
-
//#region src/format/value.d.ts
|
|
680
598
|
/**
|
|
681
599
|
* Lenient VALUE codec (env-var / key-value philosophy): primitives
|
|
682
600
|
* serialize to their bare string form, RegExp and BigInt to their
|
|
@@ -691,16 +609,11 @@ declare function serializeValue(input: unknown): string;
|
|
|
691
609
|
* to returning the raw string — it never throws.
|
|
692
610
|
*/
|
|
693
611
|
declare function deserializeValue<T = any>(input: string): T;
|
|
694
|
-
//#endregion
|
|
695
|
-
//#region src/utils/file-name.d.ts
|
|
696
612
|
declare function getFileNameExtension(input: string, allowed?: string[]): string | undefined;
|
|
697
613
|
declare function removeFileNameExtension(input: string, extensions?: string[]): string;
|
|
698
|
-
//#endregion
|
|
699
|
-
//#region src/utils/runtime.d.ts
|
|
700
614
|
declare function isJestRuntimeEnvironment(): boolean;
|
|
701
615
|
declare function isVitestRuntimeEnvironment(): boolean;
|
|
702
616
|
declare function isTsNodeRuntimeEnvironment(): boolean;
|
|
703
617
|
declare function isTsxRuntimeEnvironment(): boolean;
|
|
704
|
-
//#endregion
|
|
705
618
|
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, LoadError, type LocatorInfo, type LocatorOptions, type LocatorOptionsInput, type LocatorUpOptionsInput, LocterError, type LocterErrorInput, type LocterErrorOptions, MODULE_FILE_EXTENSIONS, type ModuleExport, type ModuleExportFilterFn, type ModuleLoadFn, type ModuleLoadOptions, type ModuleLoadSyncFn, ModuleReader, type ModuleReaderOptions, NotFoundError, type ReadOptions, type ReadPackageFieldOptions, type ReaderFactory, type Rule, TextFileReader, TextFileWriter, TextReader, TextWriter, UnknownExtensionError, WriteError, type WriteOptions, type WritePackageFieldOptions, type WriterFactory, YAMLReader, YAMLWriter, type YAMLWriterOptions, buildFilePath, deserializeValue, getFileNameExtension, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, removeFileNameExtension, serializeValue, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
|
|
706
619
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { BaseError, hasInstanceof, markInstanceof } from "@ebec/core";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { op, runTwinAsync, runTwinSync } from "twinop";
|
|
4
5
|
import fg from "fast-glob";
|
|
5
6
|
import { destr } from "destr";
|
|
6
7
|
import { flatten, unflatten } from "flat";
|
|
@@ -8,7 +9,7 @@ import fs from "node:fs";
|
|
|
8
9
|
import { createJiti } from "jiti";
|
|
9
10
|
import { pathToFileURL } from "node:url";
|
|
10
11
|
import { isMap, isNode, isScalar, parse, parseDocument, stringify } from "yaml";
|
|
11
|
-
|
|
12
|
+
// src/errors/base.ts
|
|
12
13
|
const LOCTER_ERROR_MARKER = Symbol.for("@locter/error");
|
|
13
14
|
var LocterError = class extends BaseError {
|
|
14
15
|
static [Symbol.hasInstance](input) {
|
|
@@ -25,8 +26,7 @@ var LocterError = class extends BaseError {
|
|
|
25
26
|
markInstanceof(this, LOCTER_ERROR_MARKER);
|
|
26
27
|
}
|
|
27
28
|
};
|
|
28
|
-
|
|
29
|
-
//#region src/errors/load.ts
|
|
29
|
+
// src/errors/load.ts
|
|
30
30
|
const LOCTER_LOAD_ERROR_MARKER = Symbol.for("@locter/load-error");
|
|
31
31
|
var LoadError = class extends LocterError {
|
|
32
32
|
static [Symbol.hasInstance](input) {
|
|
@@ -37,8 +37,7 @@ var LoadError = class extends LocterError {
|
|
|
37
37
|
markInstanceof(this, LOCTER_LOAD_ERROR_MARKER);
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
-
|
|
41
|
-
//#region src/errors/not-found.ts
|
|
40
|
+
// src/errors/not-found.ts
|
|
42
41
|
const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for("@locter/not-found-error");
|
|
43
42
|
var NotFoundError = class extends LocterError {
|
|
44
43
|
static [Symbol.hasInstance](input) {
|
|
@@ -49,8 +48,7 @@ var NotFoundError = class extends LocterError {
|
|
|
49
48
|
markInstanceof(this, LOCTER_NOT_FOUND_ERROR_MARKER);
|
|
50
49
|
}
|
|
51
50
|
};
|
|
52
|
-
|
|
53
|
-
//#region src/errors/unknown-extension.ts
|
|
51
|
+
// src/errors/unknown-extension.ts
|
|
54
52
|
const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for("@locter/unknown-extension-error");
|
|
55
53
|
var UnknownExtensionError = class extends LocterError {
|
|
56
54
|
static [Symbol.hasInstance](input) {
|
|
@@ -61,8 +59,7 @@ var UnknownExtensionError = class extends LocterError {
|
|
|
61
59
|
markInstanceof(this, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);
|
|
62
60
|
}
|
|
63
61
|
};
|
|
64
|
-
|
|
65
|
-
//#region src/utils/file-name.ts
|
|
62
|
+
// src/utils/file-name.ts
|
|
66
63
|
function getFileNameExtension(input, allowed) {
|
|
67
64
|
const extension = path.extname(input);
|
|
68
65
|
if (extension === "" || extension === ".") return;
|
|
@@ -73,60 +70,67 @@ function removeFileNameExtension(input, extensions) {
|
|
|
73
70
|
if (extension) return input.substring(0, input.length - extension.length);
|
|
74
71
|
return input;
|
|
75
72
|
}
|
|
76
|
-
|
|
77
|
-
//#region src/utils/has-property.ts
|
|
73
|
+
// src/utils/has-property.ts
|
|
78
74
|
function hasOwnProperty(obj, prop) {
|
|
79
75
|
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
80
76
|
}
|
|
81
77
|
function hasStringProperty(obj, prop) {
|
|
82
78
|
return hasOwnProperty(obj, prop) && typeof obj[prop] === "string";
|
|
83
79
|
}
|
|
84
|
-
|
|
85
|
-
//#region src/utils/object.ts
|
|
80
|
+
// src/utils/object.ts
|
|
86
81
|
function isObject(item) {
|
|
87
82
|
return !!item && typeof item === "object" && !Array.isArray(item);
|
|
88
83
|
}
|
|
89
84
|
function isSafeObjectKey(key) {
|
|
90
85
|
return key !== "__proto__" && key !== "prototype" && key !== "constructor";
|
|
91
86
|
}
|
|
92
|
-
|
|
93
|
-
//#region src/utils/to-array.ts
|
|
87
|
+
// src/utils/to-array.ts
|
|
94
88
|
function toArray(input) {
|
|
95
89
|
return Array.isArray(input) ? input : [input];
|
|
96
90
|
}
|
|
97
|
-
|
|
98
|
-
//#region src/utils/file-path.ts
|
|
91
|
+
// src/utils/file-path.ts
|
|
99
92
|
function isFilePath(input) {
|
|
100
93
|
const extension = path.extname(input);
|
|
101
94
|
return extension && extension !== "";
|
|
102
95
|
}
|
|
103
|
-
|
|
104
|
-
//#region src/utils/runtime.ts
|
|
96
|
+
// src/utils/runtime.ts
|
|
105
97
|
function isJestRuntimeEnvironment() {
|
|
106
98
|
return process.env && process.env.JEST_WORKER_ID !== void 0;
|
|
107
99
|
}
|
|
108
100
|
function isVitestRuntimeEnvironment() {
|
|
109
101
|
return typeof process !== "undefined" && process.env.VITEST === "true";
|
|
110
102
|
}
|
|
103
|
+
const MODULE_OPTION_REGEX = /^(?:-r|--require|--import|--(?:experimental-)?loader)(?:=(.*))?$/;
|
|
104
|
+
function matchesProcessMarker(regex) {
|
|
105
|
+
if (typeof process === "undefined") return false;
|
|
106
|
+
const { execArgv } = process;
|
|
107
|
+
if (Array.isArray(execArgv)) for (let i = 0; i < execArgv.length; i++) {
|
|
108
|
+
const arg = execArgv[i];
|
|
109
|
+
if (typeof arg !== "string") continue;
|
|
110
|
+
const option = MODULE_OPTION_REGEX.exec(arg);
|
|
111
|
+
if (!option) continue;
|
|
112
|
+
const value = typeof option[1] === "string" ? option[1] : execArgv[i + 1];
|
|
113
|
+
if (typeof value === "string" && regex.test(value)) return true;
|
|
114
|
+
}
|
|
115
|
+
const { _preload_modules: preloadModules } = process;
|
|
116
|
+
return Array.isArray(preloadModules) && preloadModules.some((el) => regex.test(el));
|
|
117
|
+
}
|
|
118
|
+
const TS_NODE_MARKER_REGEX = /(?:^|=|[\\/"'])ts-node(?:$|[\\/"'])/;
|
|
111
119
|
function isTsNodeRuntimeEnvironment() {
|
|
112
|
-
|
|
120
|
+
if (process[Symbol.for("ts-node.register.instance")]) return true;
|
|
121
|
+
return matchesProcessMarker(TS_NODE_MARKER_REGEX);
|
|
113
122
|
}
|
|
114
|
-
const TSX_MARKER_REGEX = /(?:^|=|[\\/])tsx(?:$|[\\/])/;
|
|
123
|
+
const TSX_MARKER_REGEX = /(?:^|=|[\\/"'])tsx(?:$|[\\/"'])/;
|
|
115
124
|
function isTsxRuntimeEnvironment() {
|
|
116
|
-
|
|
117
|
-
if (Array.isArray(process.execArgv) && process.execArgv.some((arg) => TSX_MARKER_REGEX.test(arg))) return true;
|
|
118
|
-
const { _preload_modules: preloadModules } = process;
|
|
119
|
-
return Array.isArray(preloadModules) && preloadModules.some((el) => TSX_MARKER_REGEX.test(el));
|
|
125
|
+
return matchesProcessMarker(TSX_MARKER_REGEX);
|
|
120
126
|
}
|
|
121
|
-
|
|
122
|
-
//#region src/utils/typescript.ts
|
|
127
|
+
// src/utils/typescript.ts
|
|
123
128
|
function isTypeScriptError(input) {
|
|
124
129
|
if (!isObject(input)) return false;
|
|
125
130
|
if (typeof input.diagnosticCodes !== "undefined") return true;
|
|
126
131
|
return typeof input.message === "string" && /TS\d+/.test(input.message);
|
|
127
132
|
}
|
|
128
|
-
|
|
129
|
-
//#region src/errors/write.ts
|
|
133
|
+
// src/errors/write.ts
|
|
130
134
|
const LOCTER_WRITE_ERROR_MARKER = Symbol.for("@locter/write-error");
|
|
131
135
|
var WriteError = class extends LocterError {
|
|
132
136
|
static [Symbol.hasInstance](input) {
|
|
@@ -137,8 +141,7 @@ var WriteError = class extends LocterError {
|
|
|
137
141
|
markInstanceof(this, LOCTER_WRITE_ERROR_MARKER);
|
|
138
142
|
}
|
|
139
143
|
};
|
|
140
|
-
|
|
141
|
-
//#region src/errors/wrap.ts
|
|
144
|
+
// src/errors/wrap.ts
|
|
142
145
|
const NOT_FOUND_CODES = /* @__PURE__ */ new Set([
|
|
143
146
|
"ENOENT",
|
|
144
147
|
"MODULE_NOT_FOUND",
|
|
@@ -171,47 +174,7 @@ function wrapWriteError(input, path) {
|
|
|
171
174
|
path
|
|
172
175
|
});
|
|
173
176
|
}
|
|
174
|
-
|
|
175
|
-
//#region src/utils/twin.ts
|
|
176
|
-
/**
|
|
177
|
-
* Perform one effect inside a twin body: `const x = yield* op(a, s)`.
|
|
178
|
-
*/
|
|
179
|
-
function* op(asyncFn, syncFn) {
|
|
180
|
-
return yield {
|
|
181
|
-
async: asyncFn,
|
|
182
|
-
sync: syncFn
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
async function runTwinAsync(body) {
|
|
186
|
-
let step = body.next();
|
|
187
|
-
while (!step.done) {
|
|
188
|
-
let result;
|
|
189
|
-
try {
|
|
190
|
-
result = await step.value.async();
|
|
191
|
-
} catch (e) {
|
|
192
|
-
step = body.throw(e);
|
|
193
|
-
continue;
|
|
194
|
-
}
|
|
195
|
-
step = body.next(result);
|
|
196
|
-
}
|
|
197
|
-
return step.value;
|
|
198
|
-
}
|
|
199
|
-
function runTwinSync(body) {
|
|
200
|
-
let step = body.next();
|
|
201
|
-
while (!step.done) {
|
|
202
|
-
let result;
|
|
203
|
-
try {
|
|
204
|
-
result = step.value.sync();
|
|
205
|
-
} catch (e) {
|
|
206
|
-
step = body.throw(e);
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
step = body.next(result);
|
|
210
|
-
}
|
|
211
|
-
return step.value;
|
|
212
|
-
}
|
|
213
|
-
//#endregion
|
|
214
|
-
//#region src/locator/utils.ts
|
|
177
|
+
// src/locator/utils.ts
|
|
215
178
|
function buildLocatorPatterns(pattern) {
|
|
216
179
|
return Array.isArray(pattern) ? pattern : [pattern];
|
|
217
180
|
}
|
|
@@ -248,8 +211,7 @@ function buildFilePath(input) {
|
|
|
248
211
|
if (typeof input === "string") return input;
|
|
249
212
|
return input.path;
|
|
250
213
|
}
|
|
251
|
-
|
|
252
|
-
//#region src/locator/core.ts
|
|
214
|
+
// src/locator/core.ts
|
|
253
215
|
function buildGlobJobs(pattern, options) {
|
|
254
216
|
const patterns = buildLocatorPatterns(pattern);
|
|
255
217
|
const opts = buildLocatorOptions(options);
|
|
@@ -284,24 +246,21 @@ function* locateManyBody(pattern, options) {
|
|
|
284
246
|
}
|
|
285
247
|
return items;
|
|
286
248
|
}
|
|
287
|
-
|
|
288
|
-
//#region src/locator/async.ts
|
|
249
|
+
// src/locator/async.ts
|
|
289
250
|
async function locateMany(pattern, options) {
|
|
290
251
|
return runTwinAsync(locateManyBody(pattern, options));
|
|
291
252
|
}
|
|
292
253
|
async function locate(pattern, options) {
|
|
293
254
|
return runTwinAsync(locateBody(pattern, options));
|
|
294
255
|
}
|
|
295
|
-
|
|
296
|
-
//#region src/locator/sync.ts
|
|
256
|
+
// src/locator/sync.ts
|
|
297
257
|
function locateManySync(pattern, options) {
|
|
298
258
|
return runTwinSync(locateManyBody(pattern, options));
|
|
299
259
|
}
|
|
300
260
|
function locateSync(pattern, options) {
|
|
301
261
|
return runTwinSync(locateBody(pattern, options));
|
|
302
262
|
}
|
|
303
|
-
|
|
304
|
-
//#region src/locator/up.ts
|
|
263
|
+
// src/locator/up.ts
|
|
305
264
|
function startWalk(options) {
|
|
306
265
|
const { cwd, stopAt, ...baseOptions } = options;
|
|
307
266
|
const current = path.resolve(cwd ?? process.cwd());
|
|
@@ -339,8 +298,7 @@ async function locateUp(pattern, options = {}) {
|
|
|
339
298
|
function locateUpSync(pattern, options = {}) {
|
|
340
299
|
return runTwinSync(locateUpBody(pattern, options));
|
|
341
300
|
}
|
|
342
|
-
|
|
343
|
-
//#region src/format/text-file/reader.ts
|
|
301
|
+
// src/format/text-file/reader.ts
|
|
344
302
|
/**
|
|
345
303
|
* Base class for readers of text-based file formats: reads the file as
|
|
346
304
|
* UTF-8, delegates to `parse`, and wraps I/O and parse errors in typed
|
|
@@ -363,8 +321,7 @@ var TextFileReader = class {
|
|
|
363
321
|
}
|
|
364
322
|
}
|
|
365
323
|
};
|
|
366
|
-
|
|
367
|
-
//#region src/format/text-file/writer.ts
|
|
324
|
+
// src/format/text-file/writer.ts
|
|
368
325
|
function isNotFound(e) {
|
|
369
326
|
return e instanceof Error && "code" in e && e.code === "ENOENT";
|
|
370
327
|
}
|
|
@@ -420,8 +377,7 @@ var TextFileWriter = class {
|
|
|
420
377
|
}
|
|
421
378
|
}
|
|
422
379
|
};
|
|
423
|
-
|
|
424
|
-
//#region src/format/built-in/conf/reader.ts
|
|
380
|
+
// src/format/built-in/conf/reader.ts
|
|
425
381
|
var ConfReader = class extends TextFileReader {
|
|
426
382
|
parse(contents) {
|
|
427
383
|
const config = {};
|
|
@@ -443,8 +399,7 @@ var ConfReader = class extends TextFileReader {
|
|
|
443
399
|
return unflatten(config, { overwrite: true });
|
|
444
400
|
}
|
|
445
401
|
};
|
|
446
|
-
|
|
447
|
-
//#region src/format/value.ts
|
|
402
|
+
// src/format/value.ts
|
|
448
403
|
/**
|
|
449
404
|
* Lenient VALUE codec (env-var / key-value philosophy): primitives
|
|
450
405
|
* serialize to their bare string form, RegExp and BigInt to their
|
|
@@ -474,8 +429,7 @@ function serializeValue(input) {
|
|
|
474
429
|
function deserializeValue(input) {
|
|
475
430
|
return destr(input);
|
|
476
431
|
}
|
|
477
|
-
|
|
478
|
-
//#region src/format/built-in/conf/writer.ts
|
|
432
|
+
// src/format/built-in/conf/writer.ts
|
|
479
433
|
/**
|
|
480
434
|
* Serializes an object to `key=value` lines (the inverse of ConfReader):
|
|
481
435
|
* nested objects become dot-separated keys, arrays become repeated
|
|
@@ -501,15 +455,13 @@ var ConfWriter = class extends TextFileWriter {
|
|
|
501
455
|
return lines.join("\n");
|
|
502
456
|
}
|
|
503
457
|
};
|
|
504
|
-
|
|
505
|
-
//#region src/format/built-in/json/reader.ts
|
|
458
|
+
// src/format/built-in/json/reader.ts
|
|
506
459
|
var JSONReader = class extends TextFileReader {
|
|
507
460
|
parse(content) {
|
|
508
461
|
return JSON.parse(content);
|
|
509
462
|
}
|
|
510
463
|
};
|
|
511
|
-
|
|
512
|
-
//#region src/format/built-in/json/writer.ts
|
|
464
|
+
// src/format/built-in/json/writer.ts
|
|
513
465
|
function detectIndent(content) {
|
|
514
466
|
const match = /^([ \t]+)\S/m.exec(content);
|
|
515
467
|
return match ? match[1] : void 0;
|
|
@@ -533,8 +485,7 @@ var JSONWriter = class extends TextFileWriter {
|
|
|
533
485
|
return output;
|
|
534
486
|
}
|
|
535
487
|
};
|
|
536
|
-
|
|
537
|
-
//#region src/format/built-in/module/constants.ts
|
|
488
|
+
// src/format/built-in/module/constants.ts
|
|
538
489
|
/**
|
|
539
490
|
* Single source of truth for the extensions handled by the module loader:
|
|
540
491
|
* consumed by BOTH the built-in routing registry and the jiti config.
|
|
@@ -547,8 +498,7 @@ const MODULE_FILE_EXTENSIONS = [
|
|
|
547
498
|
".cts",
|
|
548
499
|
".ts"
|
|
549
500
|
];
|
|
550
|
-
|
|
551
|
-
//#region src/format/built-in/module/reader.ts
|
|
501
|
+
// src/format/built-in/module/reader.ts
|
|
552
502
|
const require = createRequire(import.meta.url);
|
|
553
503
|
function originalPath(data) {
|
|
554
504
|
return typeof data === "string" ? data : buildFilePath(data);
|
|
@@ -640,8 +590,7 @@ var ModuleReader = class {
|
|
|
640
590
|
return data;
|
|
641
591
|
}
|
|
642
592
|
};
|
|
643
|
-
|
|
644
|
-
//#region src/format/built-in/module/utils.ts
|
|
593
|
+
// src/format/built-in/module/utils.ts
|
|
645
594
|
/**
|
|
646
595
|
* Brand carried by every record locter's read() produces. Deliberately a
|
|
647
596
|
* module-private Symbol (NOT Symbol.for) so arbitrary parsed data cannot
|
|
@@ -721,8 +670,7 @@ function getModuleExport(data, filterFn) {
|
|
|
721
670
|
value: data[key]
|
|
722
671
|
};
|
|
723
672
|
}
|
|
724
|
-
|
|
725
|
-
//#region src/format/built-in/text/reader.ts
|
|
673
|
+
// src/format/built-in/text/reader.ts
|
|
726
674
|
/**
|
|
727
675
|
* Raw text: the file content, as-is. No value coercion — a .txt
|
|
728
676
|
* containing '123' reads as the string '123' (use deserializeValue
|
|
@@ -733,8 +681,7 @@ var TextReader = class extends TextFileReader {
|
|
|
733
681
|
return content;
|
|
734
682
|
}
|
|
735
683
|
};
|
|
736
|
-
|
|
737
|
-
//#region src/format/built-in/text/writer.ts
|
|
684
|
+
// src/format/built-in/text/writer.ts
|
|
738
685
|
/**
|
|
739
686
|
* Raw text: accepts strings only — coercing arbitrary values would be
|
|
740
687
|
* lossy ([object Object]); serialize explicitly (e.g. serializeValue)
|
|
@@ -747,15 +694,13 @@ var TextWriter = class extends TextFileWriter {
|
|
|
747
694
|
return value;
|
|
748
695
|
}
|
|
749
696
|
};
|
|
750
|
-
|
|
751
|
-
//#region src/format/built-in/yaml/reader.ts
|
|
697
|
+
// src/format/built-in/yaml/reader.ts
|
|
752
698
|
var YAMLReader = class extends TextFileReader {
|
|
753
699
|
parse(content) {
|
|
754
700
|
return parse(content);
|
|
755
701
|
}
|
|
756
702
|
};
|
|
757
|
-
|
|
758
|
-
//#region src/format/built-in/yaml/writer.ts
|
|
703
|
+
// src/format/built-in/yaml/writer.ts
|
|
759
704
|
function pairKey(key) {
|
|
760
705
|
return isScalar(key) ? String(key.value) : String(key);
|
|
761
706
|
}
|
|
@@ -810,8 +755,7 @@ var YAMLWriter = class extends TextFileWriter {
|
|
|
810
755
|
return doc.toString(this.options);
|
|
811
756
|
}
|
|
812
757
|
};
|
|
813
|
-
|
|
814
|
-
//#region src/format/built-in/registry.ts
|
|
758
|
+
// src/format/built-in/registry.ts
|
|
815
759
|
/**
|
|
816
760
|
* Every built-in format, in one place. Keys are the format ids; each entry
|
|
817
761
|
* couples routing and construction. The id union, the extension → format
|
|
@@ -846,8 +790,7 @@ const BUILT_IN_PRESETS = {
|
|
|
846
790
|
writer: () => new TextWriter()
|
|
847
791
|
}
|
|
848
792
|
};
|
|
849
|
-
|
|
850
|
-
//#region src/format/registry/module.ts
|
|
793
|
+
// src/format/registry/module.ts
|
|
851
794
|
function compileSlot(slot) {
|
|
852
795
|
if (typeof slot === "undefined") return;
|
|
853
796
|
if (typeof slot !== "function") return () => slot;
|
|
@@ -1195,16 +1138,14 @@ var FormatRegistry = class {
|
|
|
1195
1138
|
return id;
|
|
1196
1139
|
}
|
|
1197
1140
|
};
|
|
1198
|
-
|
|
1199
|
-
//#region src/format/registry/singleton.ts
|
|
1141
|
+
// src/format/registry/singleton.ts
|
|
1200
1142
|
let instance;
|
|
1201
1143
|
function useFormatRegistry() {
|
|
1202
1144
|
if (typeof instance !== "undefined") return instance;
|
|
1203
1145
|
instance = new FormatRegistry();
|
|
1204
1146
|
return instance;
|
|
1205
1147
|
}
|
|
1206
|
-
|
|
1207
|
-
//#region src/format/helpers.ts
|
|
1148
|
+
// src/format/helpers.ts
|
|
1208
1149
|
function registerFormat(rule) {
|
|
1209
1150
|
return useFormatRegistry().register(rule);
|
|
1210
1151
|
}
|
|
@@ -1285,8 +1226,7 @@ function setModuleReader(options) {
|
|
|
1285
1226
|
reader.configure(previous);
|
|
1286
1227
|
};
|
|
1287
1228
|
}
|
|
1288
|
-
|
|
1289
|
-
//#region src/format/package-field.ts
|
|
1229
|
+
// src/format/package-field.ts
|
|
1290
1230
|
function extractField(pkg, field) {
|
|
1291
1231
|
if (!isObject(pkg) || !hasOwnProperty(pkg, field)) return;
|
|
1292
1232
|
return pkg[field];
|
|
@@ -1346,7 +1286,6 @@ async function writePackageField(field, value, options = {}) {
|
|
|
1346
1286
|
function writePackageFieldSync(field, value, options = {}) {
|
|
1347
1287
|
runTwinSync(writePackageFieldBody(field, value, options));
|
|
1348
1288
|
}
|
|
1349
|
-
//#endregion
|
|
1350
1289
|
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, LoadError, LocterError, MODULE_FILE_EXTENSIONS, ModuleReader, NotFoundError, TextFileReader, TextFileWriter, TextReader, TextWriter, UnknownExtensionError, WriteError, YAMLReader, YAMLWriter, buildFilePath, deserializeValue, getFileNameExtension, getModuleExport, isJestRuntimeEnvironment, isLocatorInfo, isModuleRecord, isTsNodeRuntimeEnvironment, isTsxRuntimeEnvironment, isVitestRuntimeEnvironment, locate, locateMany, locateManySync, locateSync, locateUp, locateUpSync, read, readAsModule, readAsModuleSync, readPackageField, readPackageFieldSync, readSync, registerFormat, removeFileNameExtension, serializeValue, setModuleReader, unregisterFormat, useFormatRegistry, wrapLoaderError, wrapWriteError, write, writePackageField, writePackageFieldSync, writeSync };
|
|
1351
1290
|
|
|
1352
1291
|
//# 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/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/value.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/text/reader.ts","../src/format/built-in/text/writer.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 LoadError 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 NotFoundError 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 UnknownExtensionError 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 WriteError 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 { LoadError } from './load';\nimport { NotFoundError } from './not-found';\nimport { WriteError } 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 NotFoundError({\n message,\n code,\n cause: input,\n path,\n });\n }\n\n return new LoadError({\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 WriteError({\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 WriteError. 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\nimport { destr } from 'destr';\n\n/**\n * Lenient VALUE codec (env-var / key-value philosophy): primitives\n * serialize to their bare string form, RegExp and BigInt to their\n * string representation (also nested), everything else to JSON.\n * The counterpart of deserializeValue — used per value by the conf\n * format, and exported for consumers building lenient custom formats.\n */\nexport function serializeValue(input: unknown) : string {\n if (typeof input === 'string') {\n return input;\n }\n\n if (typeof input === 'undefined') {\n return 'undefined';\n }\n\n if (input === null) {\n return 'null';\n }\n\n if (typeof input === 'boolean') {\n return input ? 'true' : 'false';\n }\n\n if (typeof input === 'number') {\n return `${input}`;\n }\n\n if (typeof input === 'bigint') {\n return input.toString();\n }\n\n if (input instanceof RegExp) {\n return input.toString();\n }\n\n const output = JSON.stringify(input, (_key, item) => {\n if (item instanceof RegExp) {\n return item.toString();\n }\n\n if (typeof item === 'bigint') {\n return item.toString();\n }\n\n return item;\n });\n\n // JSON.stringify yields undefined for top-level Symbol/Function and\n // toJSON() returning undefined — a lenient codec still returns a string\n return output ?? String(input);\n}\n\n/**\n * Lenient parse of a serialized value: coerces 'true'/'123'/'null'/\n * 'undefined' to their primitive, parses JSON payloads, and falls back\n * to returning the raw string — it never throws.\n */\nexport function deserializeValue<T = any>(input: string) : T {\n return destr(input);\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';\nimport { serializeValue } from '../../value';\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) 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 { TextFileReader } from '../../text-file';\n\n/**\n * Raw text: the file content, as-is. No value coercion — a .txt\n * containing '123' reads as the string '123' (use deserializeValue\n * for lenient value semantics).\n */\nexport class TextReader extends TextFileReader {\n parse(content: string) {\n return 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\n/**\n * Raw text: accepts strings only — coercing arbitrary values would be\n * lossy ([object Object]); serialize explicitly (e.g. serializeValue)\n * before writing. Output ends with a single trailing newline, like\n * every text writer.\n */\nexport class TextWriter extends TextFileWriter {\n stringify(value: unknown) : string {\n if (typeof value !== 'string') {\n throw new Error('The value must be a string for the text format.');\n }\n\n return value;\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 { 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 WriteError)\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 { TextReader, TextWriter } from './text';\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 text: {\n extensions: ['.txt'],\n reader: () => new TextReader(),\n writer: () => new TextWriter(),\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 UnknownExtensionError,\n WriteError,\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 ReadOptions,\n Rule,\n WriteOptions,\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 * options.format names a registered format id to use instead of\n * extension dispatch (e.g. { format: 'text' } reads module source\n * without evaluating it).\n */\n async read(input: LocatorInfo | string, options: ReadOptions = {}) : Promise<any> {\n return runTwinAsync(this.readBody(input, options));\n }\n\n readSync(input: LocatorInfo | string, options: ReadOptions = {}) : any {\n return runTwinSync(this.readBody(input, options));\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, options: ReadOptions = {}) : Promise<any> {\n return runTwinAsync(this.readAsModuleBody(input, options));\n }\n\n readAsModuleSync(input: LocatorInfo | string, options: ReadOptions = {}) : any {\n return runTwinSync(this.readAsModuleBody(input, options));\n }\n\n protected* readBody(input: LocatorInfo | string, options: ReadOptions) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input, options);\n if (reader instanceof ModuleReader) {\n return toModuleRecord(output);\n }\n\n return output;\n }\n\n protected* readAsModuleBody(input: LocatorInfo | string, options: ReadOptions) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input, options);\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 options: ReadOptions,\n ) : TwinBody<{ output: unknown, reader: IReader }> {\n const filePath = buildFilePath(input);\n\n let reader : IReader | undefined;\n if (typeof options.format === 'undefined') {\n reader = this.findReader(filePath);\n } else {\n reader = this.resolveReader(options.format);\n }\n\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 /**\n * options.format names a registered format id to use instead of\n * extension dispatch — see writeBody for the boundary semantics.\n */\n async write(input: LocatorInfo | string, value: unknown, options: WriteOptions = {}) : Promise<void> {\n return runTwinAsync(this.writeBody(input, value, options));\n }\n\n writeSync(input: LocatorInfo | string, value: unknown, options: WriteOptions = {}) : void {\n runTwinSync(this.writeBody(input, value, options));\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 * An explicit options.format skips extension dispatch entirely —\n * including the bare-specifier guard: naming the format resolves the\n * ambiguity the guard exists for, so extensionless paths become\n * writable.\n */\n protected* writeBody(\n input: LocatorInfo | string,\n value: unknown,\n options: WriteOptions,\n ) : TwinBody<void> {\n const filePath = buildFilePath(input);\n\n let writer : IWriter;\n if (typeof options.format === 'undefined') {\n if (!isFilePath(filePath)) {\n throw new WriteError({\n message: `Cannot write to a bare module specifier: ${filePath}`,\n path: filePath,\n });\n }\n\n const found = this.findWriter(filePath);\n if (!found) {\n if (this.findReader(filePath)) {\n const info = pathToLocatorInfo(filePath);\n throw new WriteError({\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 writer = found;\n } else {\n writer = this.resolveWriter(options.format, 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 UnknownExtensionError\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 /**\n * Resolve a reader by EXPLICIT format id (the per-call override) —\n * a user rule id or a built-in id — bypassing extension dispatch.\n * Unknown ids and writer-only rules throw.\n */\n protected resolveReader(id: string) : IReader {\n const rule = this.rules.find((item) => item.id === id);\n if (rule) {\n if (rule.getReader) {\n return rule.getReader();\n }\n\n throw new LocterError({ message: `The format ${id} has no reader.` });\n }\n\n if (hasOwnProperty(BUILT_IN_PRESETS, id)) {\n return this.builtInReader(id as BuiltInFormatId);\n }\n\n throw this.unknownFormatError(id);\n }\n\n /**\n * Write-side counterpart of resolveReader. Reader-only rules and\n * read-only built-ins (module) throw WriteError, mirroring\n * what extension dispatch throws for read-only extensions.\n */\n protected resolveWriter(id: string, path: string) : IWriter {\n const rule = this.rules.find((item) => item.id === id);\n if (rule) {\n if (rule.getWriter) {\n return rule.getWriter();\n }\n\n throw new WriteError({\n message: `The format ${id} is read-only.`,\n path,\n });\n }\n\n if (hasOwnProperty(BUILT_IN_PRESETS, id)) {\n if ('writer' in BUILT_IN_PRESETS[id as BuiltInFormatId]) {\n return this.builtInWriter(id as WritableBuiltInFormatId);\n }\n\n throw new WriteError({\n message: `The format ${id} is read-only.`,\n path,\n });\n }\n\n throw this.unknownFormatError(id);\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) : UnknownExtensionError {\n const info = pathToLocatorInfo(input);\n return new UnknownExtensionError({\n message: `No format registered for extension: ${info.extension ?? 'unknown'}`,\n path: input,\n });\n }\n\n protected unknownFormatError(id: string) : LocterError {\n return new LocterError({ message: `No format registered with id: ${id}` });\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 ReadOptions,\n type Rule,\n type WriteOptions,\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 *\n * options.format forces a registered format id instead of extension\n * dispatch — e.g. { format: 'text' } reads a module file's source\n * WITHOUT evaluating it.\n */\nexport async function read(input: LocatorInfo | string, options?: ReadOptions) : Promise<any> {\n return useFormatRegistry().read(input, options);\n}\n\nexport function readSync(input: LocatorInfo | string, options?: ReadOptions) : any {\n return useFormatRegistry().readSync(input, options);\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, options?: ReadOptions) : Promise<any> {\n return useFormatRegistry().readAsModule(input, options);\n}\n\nexport function readAsModuleSync(input: LocatorInfo | string, options?: ReadOptions) : any {\n return useFormatRegistry().readAsModuleSync(input, options);\n}\n\n/**\n * options.format forces a registered format id instead of extension\n * dispatch — this also lifts the bare-specifier guard (extensionless\n * paths) and the read-only block on module extensions.\n */\nexport async function write(input: LocatorInfo | string, value: unknown, options?: WriteOptions) : Promise<void> {\n return useFormatRegistry().write(input, value, options);\n}\n\nexport function writeSync(input: LocatorInfo | string, value: unknown, options?: WriteOptions) : void {\n useFormatRegistry().writeSync(input, value, options);\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, NotFoundError, WriteError } 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 NotFoundError) {\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 NotFoundError({ 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 WriteError({\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 NotFoundError 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/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/value.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/text/reader.ts","../src/format/built-in/text/writer.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 LoadError 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 NotFoundError 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 UnknownExtensionError 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\n// Module-loading options whose VALUE names a loader: --require (-r),\n// --import, --loader / --experimental-loader; both the `=` and the\n// separated form. Only their values are tested against a marker, so an\n// unrelated option carrying the same string (a custom export condition\n// like --conditions=ts-node) never counts as an active runtime.\nconst MODULE_OPTION_REGEX = /^(?:-r|--require|--import|--(?:experimental-)?loader)(?:=(.*))?$/;\n\n// A loader marker in a module-loading option value: the bare specifier\n// (node --import tsx, node --loader ts-node/esm), optionally with a\n// subpath (tsx/esm, ts-node/register), a resolved path into the package\n// (.../node_modules/tsx/dist/loader.mjs), or the specifier quoted inside a\n// data: URL (node --import 'data:text/javascript,...register(\"ts-node/esm\")').\nfunction matchesProcessMarker(regex: RegExp) : boolean {\n if (typeof process === 'undefined') {\n return false;\n }\n\n const { execArgv } = process;\n if (Array.isArray(execArgv)) {\n for (let i = 0; i < execArgv.length; i++) {\n const arg = execArgv[i];\n if (typeof arg !== 'string') {\n continue;\n }\n\n const option = MODULE_OPTION_REGEX.exec(arg);\n if (!option) {\n continue;\n }\n\n const value = typeof option[1] === 'string' ? option[1] : execArgv[i + 1];\n if (typeof value === 'string' && regex.test(value)) {\n return true;\n }\n }\n }\n\n const { _preload_modules: preloadModules } = process as unknown as { _preload_modules?: string[] };\n\n return Array.isArray(preloadModules) &&\n preloadModules.some((el) => regex.test(el));\n}\n\nconst TS_NODE_MARKER_REGEX = /(?:^|=|[\\\\/\"'])ts-node(?:$|[\\\\/\"'])/;\n\nexport function isTsNodeRuntimeEnvironment(): boolean {\n // The bare `ts-node` bin and `--require ts-node/register` set this on the\n // main thread. The ESM hooks (`--loader ts-node/esm`, or\n // `module.register('ts-node/esm')` via `--import`) run on a separate\n // loader thread since Node 20, so they set it on THAT thread's process\n // object and the main thread has to read the arguments instead.\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (process[Symbol.for('ts-node.register.instance')]) {\n return true;\n }\n\n return matchesProcessMarker(TS_NODE_MARKER_REGEX);\n}\n\nconst TSX_MARKER_REGEX = /(?:^|=|[\\\\/\"'])tsx(?:$|[\\\\/\"'])/;\n\nexport function isTsxRuntimeEnvironment() : boolean {\n return matchesProcessMarker(TSX_MARKER_REGEX);\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 WriteError 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 { LoadError } from './load';\nimport { NotFoundError } from './not-found';\nimport { WriteError } 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 NotFoundError({\n message,\n code,\n cause: input,\n path,\n });\n }\n\n return new LoadError({\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 WriteError({\n message,\n code,\n cause: input,\n path,\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';\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 'twinop';\nimport { op } from 'twinop';\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 'twinop';\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 'twinop';\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 'twinop';\nimport { runTwinAsync, runTwinSync } from 'twinop';\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 'twinop';\nimport { op, runTwinAsync, runTwinSync } from 'twinop';\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 'twinop';\nimport { op, runTwinAsync, runTwinSync } from 'twinop';\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 WriteError. 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\nimport { destr } from 'destr';\n\n/**\n * Lenient VALUE codec (env-var / key-value philosophy): primitives\n * serialize to their bare string form, RegExp and BigInt to their\n * string representation (also nested), everything else to JSON.\n * The counterpart of deserializeValue — used per value by the conf\n * format, and exported for consumers building lenient custom formats.\n */\nexport function serializeValue(input: unknown) : string {\n if (typeof input === 'string') {\n return input;\n }\n\n if (typeof input === 'undefined') {\n return 'undefined';\n }\n\n if (input === null) {\n return 'null';\n }\n\n if (typeof input === 'boolean') {\n return input ? 'true' : 'false';\n }\n\n if (typeof input === 'number') {\n return `${input}`;\n }\n\n if (typeof input === 'bigint') {\n return input.toString();\n }\n\n if (input instanceof RegExp) {\n return input.toString();\n }\n\n const output = JSON.stringify(input, (_key, item) => {\n if (item instanceof RegExp) {\n return item.toString();\n }\n\n if (typeof item === 'bigint') {\n return item.toString();\n }\n\n return item;\n });\n\n // JSON.stringify yields undefined for top-level Symbol/Function and\n // toJSON() returning undefined — a lenient codec still returns a string\n return output ?? String(input);\n}\n\n/**\n * Lenient parse of a serialized value: coerces 'true'/'123'/'null'/\n * 'undefined' to their primitive, parses JSON payloads, and falls back\n * to returning the raw string — it never throws.\n */\nexport function deserializeValue<T = any>(input: string) : T {\n return destr(input);\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';\nimport { serializeValue } from '../../value';\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) 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 { TextFileReader } from '../../text-file';\n\n/**\n * Raw text: the file content, as-is. No value coercion — a .txt\n * containing '123' reads as the string '123' (use deserializeValue\n * for lenient value semantics).\n */\nexport class TextReader extends TextFileReader {\n parse(content: string) {\n return 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\n/**\n * Raw text: accepts strings only — coercing arbitrary values would be\n * lossy ([object Object]); serialize explicitly (e.g. serializeValue)\n * before writing. Output ends with a single trailing newline, like\n * every text writer.\n */\nexport class TextWriter extends TextFileWriter {\n stringify(value: unknown) : string {\n if (typeof value !== 'string') {\n throw new Error('The value must be a string for the text format.');\n }\n\n return value;\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 { 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 WriteError)\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 { TextReader, TextWriter } from './text';\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 text: {\n extensions: ['.txt'],\n reader: () => new TextReader(),\n writer: () => new TextWriter(),\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 UnknownExtensionError,\n WriteError,\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 'twinop';\nimport { op, runTwinAsync, runTwinSync } from 'twinop';\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 ReadOptions,\n Rule,\n WriteOptions,\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 * options.format names a registered format id to use instead of\n * extension dispatch (e.g. { format: 'text' } reads module source\n * without evaluating it).\n */\n async read(input: LocatorInfo | string, options: ReadOptions = {}) : Promise<any> {\n return runTwinAsync(this.readBody(input, options));\n }\n\n readSync(input: LocatorInfo | string, options: ReadOptions = {}) : any {\n return runTwinSync(this.readBody(input, options));\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, options: ReadOptions = {}) : Promise<any> {\n return runTwinAsync(this.readAsModuleBody(input, options));\n }\n\n readAsModuleSync(input: LocatorInfo | string, options: ReadOptions = {}) : any {\n return runTwinSync(this.readAsModuleBody(input, options));\n }\n\n protected* readBody(input: LocatorInfo | string, options: ReadOptions) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input, options);\n if (reader instanceof ModuleReader) {\n return toModuleRecord(output);\n }\n\n return output;\n }\n\n protected* readAsModuleBody(input: LocatorInfo | string, options: ReadOptions) : TwinBody<any> {\n const { output, reader } = yield* this.executeBody(input, options);\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 options: ReadOptions,\n ) : TwinBody<{ output: unknown, reader: IReader }> {\n const filePath = buildFilePath(input);\n\n let reader : IReader | undefined;\n if (typeof options.format === 'undefined') {\n reader = this.findReader(filePath);\n } else {\n reader = this.resolveReader(options.format);\n }\n\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 /**\n * options.format names a registered format id to use instead of\n * extension dispatch — see writeBody for the boundary semantics.\n */\n async write(input: LocatorInfo | string, value: unknown, options: WriteOptions = {}) : Promise<void> {\n return runTwinAsync(this.writeBody(input, value, options));\n }\n\n writeSync(input: LocatorInfo | string, value: unknown, options: WriteOptions = {}) : void {\n runTwinSync(this.writeBody(input, value, options));\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 * An explicit options.format skips extension dispatch entirely —\n * including the bare-specifier guard: naming the format resolves the\n * ambiguity the guard exists for, so extensionless paths become\n * writable.\n */\n protected* writeBody(\n input: LocatorInfo | string,\n value: unknown,\n options: WriteOptions,\n ) : TwinBody<void> {\n const filePath = buildFilePath(input);\n\n let writer : IWriter;\n if (typeof options.format === 'undefined') {\n if (!isFilePath(filePath)) {\n throw new WriteError({\n message: `Cannot write to a bare module specifier: ${filePath}`,\n path: filePath,\n });\n }\n\n const found = this.findWriter(filePath);\n if (!found) {\n if (this.findReader(filePath)) {\n const info = pathToLocatorInfo(filePath);\n throw new WriteError({\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 writer = found;\n } else {\n writer = this.resolveWriter(options.format, 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 UnknownExtensionError\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 /**\n * Resolve a reader by EXPLICIT format id (the per-call override) —\n * a user rule id or a built-in id — bypassing extension dispatch.\n * Unknown ids and writer-only rules throw.\n */\n protected resolveReader(id: string) : IReader {\n const rule = this.rules.find((item) => item.id === id);\n if (rule) {\n if (rule.getReader) {\n return rule.getReader();\n }\n\n throw new LocterError({ message: `The format ${id} has no reader.` });\n }\n\n if (hasOwnProperty(BUILT_IN_PRESETS, id)) {\n return this.builtInReader(id as BuiltInFormatId);\n }\n\n throw this.unknownFormatError(id);\n }\n\n /**\n * Write-side counterpart of resolveReader. Reader-only rules and\n * read-only built-ins (module) throw WriteError, mirroring\n * what extension dispatch throws for read-only extensions.\n */\n protected resolveWriter(id: string, path: string) : IWriter {\n const rule = this.rules.find((item) => item.id === id);\n if (rule) {\n if (rule.getWriter) {\n return rule.getWriter();\n }\n\n throw new WriteError({\n message: `The format ${id} is read-only.`,\n path,\n });\n }\n\n if (hasOwnProperty(BUILT_IN_PRESETS, id)) {\n if ('writer' in BUILT_IN_PRESETS[id as BuiltInFormatId]) {\n return this.builtInWriter(id as WritableBuiltInFormatId);\n }\n\n throw new WriteError({\n message: `The format ${id} is read-only.`,\n path,\n });\n }\n\n throw this.unknownFormatError(id);\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) : UnknownExtensionError {\n const info = pathToLocatorInfo(input);\n return new UnknownExtensionError({\n message: `No format registered for extension: ${info.extension ?? 'unknown'}`,\n path: input,\n });\n }\n\n protected unknownFormatError(id: string) : LocterError {\n return new LocterError({ message: `No format registered with id: ${id}` });\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 ReadOptions,\n type Rule,\n type WriteOptions,\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 *\n * options.format forces a registered format id instead of extension\n * dispatch — e.g. { format: 'text' } reads a module file's source\n * WITHOUT evaluating it.\n */\nexport async function read(input: LocatorInfo | string, options?: ReadOptions) : Promise<any> {\n return useFormatRegistry().read(input, options);\n}\n\nexport function readSync(input: LocatorInfo | string, options?: ReadOptions) : any {\n return useFormatRegistry().readSync(input, options);\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, options?: ReadOptions) : Promise<any> {\n return useFormatRegistry().readAsModule(input, options);\n}\n\nexport function readAsModuleSync(input: LocatorInfo | string, options?: ReadOptions) : any {\n return useFormatRegistry().readAsModuleSync(input, options);\n}\n\n/**\n * options.format forces a registered format id instead of extension\n * dispatch — this also lifts the bare-specifier guard (extensionless\n * paths) and the read-only block on module extensions.\n */\nexport async function write(input: LocatorInfo | string, value: unknown, options?: WriteOptions) : Promise<void> {\n return useFormatRegistry().write(input, value, options);\n}\n\nexport function writeSync(input: LocatorInfo | string, value: unknown, options?: WriteOptions) : void {\n useFormatRegistry().writeSync(input, value, options);\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, NotFoundError, WriteError } 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 'twinop';\nimport { op, runTwinAsync, runTwinSync } from 'twinop';\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 NotFoundError) {\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 NotFoundError({ 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 WriteError({\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 NotFoundError when no package.json could be located.\n */\nexport async function writePackageField(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : Promise<void> {\n return runTwinAsync(writePackageFieldBody(field, value, options));\n}\n\nexport function writePackageFieldSync(\n field: string,\n value: unknown,\n options: WritePackageFieldOptions = {},\n) : void {\n runTwinSync(writePackageFieldBody(field, value, options));\n}\n"],"mappings":";;;;;;;;;;;;AAoBA,MAAa,sBAAsB,OAAO,IAAI,eAAe;AAE7D,IAAa,cAAb,cAAiC,UAAU;CACvC,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,mBAAmB;CACnD;CAEA;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,IAAI,OAAO,UAAU,UACjB,MAAM,KAAK;OACR;GACH,MAAM,EAAE,MAAM,GAAG,SAAS;GAC1B,MAAM,IAAI;GACV,KAAK,OAAO;EAChB;EAEA,eAAe,MAAM,mBAAmB;CAC5C;AACJ;;AC9BA,MAAa,2BAA2B,OAAO,IAAI,oBAAoB;AAEvE,IAAa,YAAb,cAA+B,YAAY;CACvC,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,wBAAwB;CACxD;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,wBAAwB;CACjD;AACJ;;ACXA,MAAa,gCAAgC,OAAO,IAAI,yBAAyB;AAEjF,IAAa,gBAAb,cAAmC,YAAY;CAC3C,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,6BAA6B;CAC7D;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,6BAA6B;CACtD;AACJ;;ACXA,MAAa,wCAAwC,OAAO,IAAI,iCAAiC;AAEjG,IAAa,wBAAb,cAA2C,YAAY;CACnD,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,qCAAqC;CACrE;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,qCAAqC;CAC9D;AACJ;;ACZA,SAAgB,qBACZ,OACA,SACmB;CACnB,MAAM,YAAY,KAAK,QAAQ,KAAK;CACpC,IAAI,cAAc,MAAM,cAAc,KAClC;CAGJ,IACI,OAAO,YAAY,eACnB,QAAQ,SAAS,SAAS,GAE1B,OAAO;AAIf;AAEA,SAAgB,wBACZ,OACA,YACF;CACE,MAAM,YAAY,qBAAqB,OAAO,UAAU;CACxD,IAAI,WACA,OAAO,MAAM,UAAU,GAAG,MAAM,SAAS,UAAU,MAAM;CAG7D,OAAO;AACX;;ACtCA,SAAgB,eAAqE,KAAQ,MAAwC;CACjI,OAAO,OAAO,UAAU,eAAe,KAAK,KAAK,IAAI;AACzD;AAEA,SAAgB,kBAAwE,KAAQ,MAAuC;CACnI,OAAO,eAAe,KAAK,IAAI,KAAK,OAAO,IAAI,UAAU;AAC7D;;ACCA,SAAgB,SAAS,MAA6C;CAClE,OACI,CAAC,CAAC,QACF,OAAO,SAAS,YAChB,CAAC,MAAM,QAAQ,IAAI;AAE3B;AAEA,SAAgB,gBAAgB,KAAuB;CACnD,OAAO,QAAQ,eACX,QAAQ,eACR,QAAQ;AAChB;;ACZA,SAAgB,QAAQ,OAAqC;CACzD,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAChD;;ACDA,SAAgB,WAAW,OAAe;CACtC,MAAM,YAAY,KAAK,QAAQ,KAAK;CACpC,OAAO,aAAa,cAAc;AACtC;;ACJA,SAAgB,2BAAqC;CACjD,OAAO,QAAQ,OACX,QAAQ,IAAI,mBAAmB,KAAA;AACvC;AAEA,SAAgB,6BAAuC;CACnD,OAAO,OAAO,YAAY,eACtB,QAAQ,IAAI,WAAW;AAC/B;AAOA,MAAM,sBAAsB;AAO5B,SAAS,qBAAqB,OAAyB;CACnD,IAAI,OAAO,YAAY,aACnB,OAAO;CAGX,MAAM,EAAE,aAAa;CACrB,IAAI,MAAM,QAAQ,QAAQ,GACtB,KAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;EACtC,MAAM,MAAM,SAAS;EACrB,IAAI,OAAO,QAAQ,UACf;EAGJ,MAAM,SAAS,oBAAoB,KAAK,GAAG;EAC3C,IAAI,CAAC,QACD;EAGJ,MAAM,QAAQ,OAAO,OAAO,OAAO,WAAW,OAAO,KAAK,SAAS,IAAI;EACvE,IAAI,OAAO,UAAU,YAAY,MAAM,KAAK,KAAK,GAC7C,OAAO;CAEf;CAGJ,MAAM,EAAE,kBAAkB,mBAAmB;CAE7C,OAAO,MAAM,QAAQ,cAAc,KAC/B,eAAe,MAAM,OAAO,MAAM,KAAK,EAAE,CAAC;AAClD;AAEA,MAAM,uBAAuB;AAE7B,SAAgB,6BAAsC;CAQlD,IAAI,QAAQ,OAAO,IAAI,2BAA2B,IAC9C,OAAO;CAGX,OAAO,qBAAqB,oBAAoB;AACpD;AAEA,MAAM,mBAAmB;AAEzB,SAAgB,0BAAoC;CAChD,OAAO,qBAAqB,gBAAgB;AAChD;;ACxEA,SAAgB,kBAAkB,OAAiC;CAC/D,IAAI,CAAC,SAAS,KAAK,GACf,OAAO;CAGX,IAAI,OAAO,MAAM,oBAAoB,aACjC,OAAO;CAGX,OAAO,OAAO,MAAM,YAAY,YAC5B,QAAQ,KAAK,MAAM,OAAO;AAClC;;ACVA,MAAa,4BAA4B,OAAO,IAAI,qBAAqB;AAEzE,IAAa,aAAb,cAAgC,YAAY;CACxC,QAAiB,OAAO,aAAa,OAA0B;EAC3D,OAAO,cAAc,OAAO,yBAAyB;CACzD;CAEA,YAAY,QAA0B,CAAC,GAAG;EACtC,MAAM,KAAK;EACX,eAAe,MAAM,yBAAyB;CAClD;AACJ;;ACRA,MAAM,kCAAkB,IAAI,IAAI;CAC5B;CACA;CACA;AACJ,CAAC;AAED,SAAgB,gBAAgB,OAAgB,MAA4B;CACxE,IAAI,iBAAiB,aACjB,OAAO;CAGX,MAAM,OAAO,SAAS,KAAK,KAAK,kBAAkB,OAAO,MAAM,IAC3D,MAAM,OACN,KAAA;CAEJ,MAAM,UAAU,SAAS,KAAK,KAAK,kBAAkB,OAAO,SAAS,IACjE,MAAM,UACN,mBAAmB;CAEvB,IAAI,QAAQ,gBAAgB,IAAI,IAAI,GAChC,OAAO,IAAI,cAAc;EACrB;EACA;EACA,OAAO;EACP;CACJ,CAAC;CAGL,OAAO,IAAI,UAAU;EACjB;EACA;EACA,OAAO;EACP;CACJ,CAAC;AACL;AAEA,SAAgB,eAAe,OAAgB,MAA4B;CACvE,IAAI,iBAAiB,aACjB,OAAO;CAGX,MAAM,OAAO,SAAS,KAAK,KAAK,kBAAkB,OAAO,MAAM,IAC3D,MAAM,OACN,KAAA;CAMJ,OAAO,IAAI,WAAW;EAClB,SALY,SAAS,KAAK,KAAK,kBAAkB,OAAO,SAAS,IACjE,MAAM,UACN,oBAAoB;EAIpB;EACA,OAAO;EACP;CACJ,CAAC;AACL;;ACzDA,SAAgB,qBAAqB,SAAuC;CACxE,OAAO,MAAM,QAAQ,OAAO,IACxB,UACA,CAAC,OAAO;AAChB;AAEA,SAAgB,oBAAoB,UAA+B,CAAC,GAAoB;CACpF,MAAM,MAAM,QAAQ,MAChB,QAAQ,QAAQ,GAAG,IACnB,CAAC;CAEL,MAAM,SAAS,QAAQ,SACnB,QAAQ,QAAQ,MAAM,IACtB,CAAC;CAEL,IAAI,IAAI,WAAW,GACf,IAAI,KAAK,QAAQ,IAAI,CAAC;CAK1B,MAAM,kBAAkB,QAAQ,mBAAmB;CAKnD,OAAO;EACH;EACA;EACA;EACA,WARc,kBACd,QACA,QAAQ,aAAa;EAOrB,KAAK,QAAQ,OAAO;CACxB;AACJ;AAEA,SAAgB,kBACZ,OACA,aACY;CACZ,IACI,CAAC,eACD,CAAC,KAAK,WAAW,KAAK,GAEtB,QAAQ,KAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;CAG7C,MAAM,OAAO,KAAK,MAAM,KAAK;CAC7B,MAAM,YAAY,KAAK,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG;CACnD,MAAM,YAAY,KAAK,MAAM,KAAK,MAAM,KAAA;CACxC,MAAM,WAAW,YACb,KAAK,KAAK,WAAW,KAAK,IAAI,IAAI,YAClC,KAAK,KAAK,WAAW,KAAK,IAAI;CAElC,OAAO;EACH;EACA,MAAM,KAAK;EACX;EACA,MAAM;CACV;AACJ;AAEA,SAAgB,cACZ,OACqB;CACrB,OAAO,SAAS,KAAK,KACjB,OAAO,MAAM,cAAc,YAC3B,OAAO,MAAM,SAAS,aACrB,OAAO,MAAM,cAAc,eAAe,OAAO,MAAM,cAAc,aACtE,OAAO,MAAM,SAAS;AAC9B;AAEA,SAAgB,cAAc,OAA6B;CACvD,IAAI,OAAO,UAAU,UACjB,OAAO;CAGX,OAAO,MAAM;AACjB;;ACtEA,SAAS,cACL,SACA,SACU;CACV,MAAM,WAAW,qBAAqB,OAAO;CAC7C,MAAM,OAAO,oBAAoB,OAAO;CAExC,MAAM,OAAmB,CAAC;CAC1B,KAAK,MAAM,KAAK,UACZ,KAAK,MAAM,OAAO,KAAK,KACnB,KAAK,KAAK;EACN,SAAS;EACT,SAAS;GACL,UAAU;GACV;GACA,QAAQ,KAAK;GACb,WAAW,KAAK;GAChB,iBAAiB,KAAK;GACtB,KAAK,KAAK;EACd;CACJ,CAAC;CAIT,OAAO;AACX;AAEA,UAAU,KAAK,KAA8C;CACzD,OAAO,OAAO,SACJ,GAAG,IAAI,SAAS,IAAI,OAAO,SAC3B,GAAG,KAAK,IAAI,SAAS,IAAI,OAAO,CAC1C;AACJ;AAEA,UAAiB,WACb,SACA,SACkC;CAClC,KAAK,MAAM,OAAO,cAAc,SAAS,OAAO,GAAG;EAG/C,MAAM,WAAU,OAFK,KAAK,GAAG,EAAA,CAEP,MAAM;EAC5B,IAAI,SACA,OAAO,kBAAkB,SAAS,IAAI;CAE9C;AAGJ;AAEA,UAAiB,eACb,SACA,SACwB;CACxB,MAAM,QAAwB,CAAC;CAE/B,KAAK,MAAM,OAAO,cAAc,SAAS,OAAO,GAAG;EAC/C,MAAM,QAAQ,OAAO,KAAK,GAAG;EAE7B,KAAK,MAAM,QAAQ,OACf,MAAM,KAAK,kBAAkB,MAAM,IAAI,CAAC;CAEhD;CAEA,OAAO;AACX;;ACxEA,eAAsB,WAClB,SACA,SACuB;CACvB,OAAO,aAAa,eAAe,SAAS,OAAO,CAAC;AACxD;AAEA,eAAsB,OAClB,SACA,SACiC;CACjC,OAAO,aAAa,WAAW,SAAS,OAAO,CAAC;AACpD;;ACZA,SAAgB,eACZ,SACA,SACc;CACd,OAAO,YAAY,eAAe,SAAS,OAAO,CAAC;AACvD;AAEA,SAAgB,WACZ,SACA,SACwB;CACxB,OAAO,YAAY,WAAW,SAAS,OAAO,CAAC;AACnD;;ACCA,SAAS,UAAU,SAA2C;CAC1D,MAAM,EACF,KACA,QACA,GAAG,gBACH;CACJ,MAAM,UAAU,KAAK,QAAQ,OAAO,QAAQ,IAAI,CAAC;CAKjD,OAAO;EACH;EACA,QANY,SACZ,KAAK,QAAQ,SAAS,MAAM,IAC5B,KAAK,MAAM,OAAO,CAAC,CAAC;EAKpB;CACJ;AACJ;AAEA,SAAS,cAAc,SAAiB,QAAqC;CACzE,IAAI,YAAY,QACZ;CAGJ,MAAM,SAAS,KAAK,QAAQ,OAAO;CACnC,IAAI,WAAW,SACX;CAGJ,OAAO;AACX;AAEA,UAAU,aACN,SACA,SACkC;CAClC,IAAI,OAAO,UAAU,OAAO;CAE5B,OAAO,MAAM;EACT,MAAM,QAAQ,OAAO,WAAW,SAAS;GAAE,GAAG,KAAK;GAAa,KAAK,KAAK;EAAQ,CAAC;EACnF,IAAI,OACA,OAAO;EAGX,MAAM,OAAO,cAAc,KAAK,SAAS,KAAK,MAAM;EACpD,IAAI,CAAC,MACD;EAGJ,OAAO;GAAE,GAAG;GAAM,SAAS;EAAK;CACpC;AACJ;AAEA,eAAsB,SAClB,SACA,UAAiC,CAAC,GACD;CACjC,OAAO,aAAa,aAAa,SAAS,OAAO,CAAC;AACtD;AAEA,SAAgB,aACZ,SACA,UAAiC,CAAC,GACV;CACxB,OAAO,YAAY,aAAa,SAAS,OAAO,CAAC;AACrD;;;;;;;;ACrEA,IAAsB,iBAAtB,MAAwD;CAGpD,MAAM,KAAK,OAA8B;EACrC,OAAO,aAAa,KAAK,KAAK,KAAK,CAAC;CACxC;CAEA,SAAS,OAAqB;EAC1B,OAAO,YAAY,KAAK,KAAK,KAAK,CAAC;CACvC;CAEA,CAAW,KAAK,OAA+B;EAC3C,IAAI;GACA,MAAM,UAAU,OAAO,SACb,GAAG,SAAS,SAAS,OAAO,EAAE,UAAU,QAAQ,CAAC,SACjD,GAAG,aAAa,OAAO,EAAE,UAAU,QAAQ,CAAC,CACtD;GAEA,OAAO,KAAK,MAAM,OAAO;EAC7B,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,KAAK;EAClC;CACJ;AACJ;;AC5BA,SAAS,WAAW,GAAsB;CACtC,OAAO,aAAa,SAAS,UAAU,KAAK,EAAE,SAAS;AAC3D;;;;;;;;AASA,IAAsB,iBAAtB,MAAwD;;;;;;;CAOpD,IAAc,sBAAgC;EAC1C,OAAO;CACX;CAIA,MAAM,MAAM,OAAe,OAAgC;EACvD,OAAO,aAAa,KAAK,KAAK,OAAO,KAAK,CAAC;CAC/C;CAEA,UAAU,OAAe,OAAuB;EAC5C,YAAY,KAAK,KAAK,OAAO,KAAK,CAAC;CACvC;CAEA,CAAW,KAAK,OAAe,OAAiC;EAC5D,MAAM,WAAW;EAEjB,IAAI;GACA,IAAI;GACJ,IAAI,KAAK,qBACL,WAAW,OAAO,SACR,GAAG,SAAS,SAAS,UAAU,EAAE,UAAU,QAAQ,CAAC,CAAC,CACtD,OAAO,MAAM;IACV,IAAI,WAAW,CAAC,GACZ;IAEJ,MAAM;GACV,CAAC,SACC;IACF,IAAI;KACA,OAAO,GAAG,aAAa,UAAU,EAAE,UAAU,QAAQ,CAAC;IAC1D,SAAS,GAAG;KACR,IAAI,WAAW,CAAC,GACZ;KAEJ,MAAM;IACV;GACJ,CACJ;GAGJ,IAAI,UAAU,KAAK,UAAU,OAAO,QAAQ;GAC5C,IAAI,CAAC,QAAQ,SAAS,IAAI,GACtB,WAAW;GAGf,MAAM,YAAY,KAAK,QAAQ,QAAQ;GACvC,OAAO,GACH,YAAY;IACR,MAAM,GAAG,SAAS,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;GAC1D,SACM;IACF,GAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;GAC/C,CACJ;GAEA,OAAO,SACG,GAAG,SAAS,UAAU,UAAU,SAAS,EAAE,UAAU,QAAQ,CAAC,SAC9D,GAAG,cAAc,UAAU,SAAS,EAAE,UAAU,QAAQ,CAAC,CACnE;EACJ,SAAS,GAAG;GACR,MAAM,eAAe,GAAG,QAAQ;EACpC;CACJ;AACJ;;AClFA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,UAAuC;EACzC,MAAM,SAA8B,CAAC;EAErC,MAAM,QAAQ,SAAS,MAAM,YAAY;EAEzC,KAAK,MAAM,QAAQ,OAAO;GACtB,MAAM,QAAQ,KAAK,MAAM,+BAA+B;GACxD,IAAI,CAAC,OACD;GAGJ,MAAM,MAAM,MAAM;GAClB,MAAM,WAAW,MAAM;GAEvB,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,GAC5B;GAGJ,MAAM,QAAQ,MAAM,WAAW,SAAS,KAAK,IAAI,EAAE;GAEnD,IAAI,IAAI,SAAS,IAAI,GAAG;IACpB,MAAM,SAAS,IAAI,MAAM,GAAG,KAAK,IAAI,GAAG,IAAI,SAAS,CAAC,CAAC;IACvD,OAAO,WAAW,OAAO,WAAW,CAAC,EAAA,CAAG,OAAO,KAAK;IACpD;GACJ;GAEA,OAAO,OAAO;EAClB;EAEA,OAAO,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;CAChD;AACJ;;;;;;;;;AC9BA,SAAgB,eAAe,OAAyB;CACpD,IAAI,OAAO,UAAU,UACjB,OAAO;CAGX,IAAI,OAAO,UAAU,aACjB,OAAO;CAGX,IAAI,UAAU,MACV,OAAO;CAGX,IAAI,OAAO,UAAU,WACjB,OAAO,QAAQ,SAAS;CAG5B,IAAI,OAAO,UAAU,UACjB,OAAO,GAAG;CAGd,IAAI,OAAO,UAAU,UACjB,OAAO,MAAM,SAAS;CAG1B,IAAI,iBAAiB,QACjB,OAAO,MAAM,SAAS;CAiB1B,OAde,KAAK,UAAU,QAAQ,MAAM,SAAS;EACjD,IAAI,gBAAgB,QAChB,OAAO,KAAK,SAAS;EAGzB,IAAI,OAAO,SAAS,UAChB,OAAO,KAAK,SAAS;EAGzB,OAAO;CACX,CAIY,KAAK,OAAO,KAAK;AACjC;;;;;;AAOA,SAAgB,iBAA0B,OAAmB;CACzD,OAAO,MAAM,KAAK;AACtB;;;;;;;;;;AC/CA,IAAa,aAAb,cAAgC,eAAe;CAC3C,UAAU,OAAyB;EAC/B,IAAI,CAAC,SAAS,KAAK,GACf,MAAM,IAAI,MAAM,kDAAkD;EAGtE,MAAM,OAAiC,QAAQ,OAAO,EAAE,MAAM,KAAK,CAAC;EAEpE,MAAM,QAAmB,CAAC;EAC1B,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAAG;GACjC,MAAM,QAAQ,KAAK;GACnB,IAAI,OAAO,UAAU,aACjB;GAGJ,IAAI,MAAM,QAAQ,KAAK,GAAG;IACtB,KAAK,MAAM,QAAQ,OACf,MAAM,KAAK,GAAG,IAAI,KAAK,eAAe,IAAI,GAAG;IAEjD;GACJ;GAEA,MAAM,KAAK,GAAG,IAAI,GAAG,eAAe,KAAK,GAAG;EAChD;EAEA,OAAO,MAAM,KAAK,IAAI;CAC1B;AACJ;;ACxCA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,SAAiB;EACnB,OAAO,KAAK,MAAM,OAAO;CAC7B;AACJ;;ACOA,SAAS,aAAa,SAAsC;CACxD,MAAM,QAAQ,eAAe,KAAK,OAAO;CACzC,OAAO,QAAQ,MAAM,KAAK,KAAA;AAC9B;AAEA,IAAa,aAAb,cAAgC,eAAe;CAC3C;CAEA,YAAY,UAA6B,CAAC,GAAG;EACzC,MAAM;EACN,KAAK,UAAU;CACnB;CAEA,IAAuB,sBAAgC;EACnD,OAAO,KAAK,QAAQ,WAAW;CACnC;CAEA,UAAU,OAAgB,UAA4B;EAClD,IAAI;EACJ,IAAI,KAAK,QAAQ,WAAW,QACxB,SAAS,WAAW,aAAa,QAAQ,IAAI,KAAA;OAE7C,SAAS,KAAK,QAAQ;EAG1B,SAAS,UAAU;EAEnB,MAAM,SAAS,KAAK,UAAU,OAAO,MAAM,MAAM;EACjD,IAAI,OAAO,WAAW,aAClB,MAAM,IAAI,MAAM,qCAAqC;EAGzD,OAAO;CACX;AACJ;;;;;;AC3CA,MAAa,yBAAyB;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAQ;AAAK;;ACsBnF,MAAM,UAAU,cAAc,YAAY,GAAG;AAI7C,SAAS,aAAa,MAAqC;CACvD,OAAO,OAAO,SAAS,WAAW,OAAO,cAAc,IAAI;AAC/D;AAEA,SAAS,qBAAqB,OAA0B;CACpD,MAAM,aAAa,iBAAiB,cAAc,MAAM,QAAQ;CAChE,OAAO,sBAAsB,eACzB,sBAAsB,kBACtB,kBAAkB,UAAU;AACpC;AAEA,IAAa,eAAb,MAA6C;CACzC;CAEA;CAEA;CAEA,YAAY,UAA+B,CAAC,GAAG;EAG3C,KAAK,WAAW,WAAW,KAAA,GAAW,EAAE,YAAY,CAAC,GAAG,sBAAsB,EAAE,CAAC;EACjF,KAAK,SAAS,QAAQ;EACtB,KAAK,aAAa,QAAQ;CAC9B;;;;CAKA,UAAU,SAAoD;EAC1D,MAAM,WAAiC;GACnC,MAAM,KAAK;GACX,UAAU,KAAK;EACnB;EAEA,IAAI,UAAU,SACV,KAAK,SAAS,QAAQ;EAE1B,IAAI,cAAc,SACd,KAAK,aAAa,QAAQ;EAG9B,OAAO;CACX;;;;;;;;;;;;;;CAeA,MAAM,KAAK,OAAe;EACtB,IAAI;GACA,OAAO,MAAM,KAAK,KAAK,KAAK;EAChC,SAAS,GAAG;GACR,IAAI,qBAAqB,CAAC,GACtB,MAAM;GAKV,IAAI,2BAA2B,GAC3B,OAAO,KAAK,SAAS,KAAK;GAG9B,OAAO,KAAK,SAAS,KAAK;EAC9B;CACJ;CAEA,SAAS,OAAe;EACpB,IAAI;GACA,OAAO,KAAK,SAAS,KAAK;EAC9B,SAAS,GAAG;GACR,IAAI,qBAAqB,CAAC,GACtB,MAAM;GAGV,OAAO,KAAK,SAAS,KAAK;EAC9B;CACJ;CAIA,MAAM,KACF,MACA,UAA6B,CAAC,GACb;EACjB,MAAM,KAAK,KAAK,MAAM,MAAM,OAAO;EAEnC,IAAI;GACA,IAAI,KAAK,QACL,OAAO,MAAM,KAAK,OAAO,EAAE;GAK/B,IAAI,yBAAyB,GACzB,OAAO,QAAQ,EAAE;GAGrB,OAAO,MAAM,OAAO;EACxB,SAAS,GAAG;;GAER,IACI,CAAC,QAAQ,kBACT,SAAS,CAAC,KACV,kBAAkB,GAAG,MAAM,MAEvB,EAAE,SAAS,oCACX,EAAE,SAAS,+BAGf,OAAO,KAAK,KAAK,MAAM;IACnB,GAAG;IACH,gBAAgB;GACpB,CAAC;GAGL,MAAM,gBAAgB,GAAG,aAAa,IAAI,CAAC;EAC/C;CACJ;CAEA,SACI,MACA,UAA6B,CAAC,GACtB;EACR,MAAM,KAAK,KAAK,MAAM,MAAM,OAAO;EAEnC,IAAI;GACA,IAAI,KAAK,YACL,OAAO,KAAK,WAAW,EAAE;GAG7B,OAAO,QAAQ,EAAE;EACrB,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,aAAa,IAAI,CAAC;EAC/C;CACJ;CAEA,MACI,MACA,UAA6B,CAAC,GACvB;EACP,IAAI,cAAc,IAAI,KAAK,WAAW,IAAI,GAAG;GACzC,IAAI,OAAO,SAAS,UAChB,OAAO,cAAc,IAAI;GAG7B,IAAI,QAAQ,gBACR,OAAO,cAAc,IAAI,CAAC,CAAC;EAEnC;EAEA,OAAO;CACX;AACJ;;;;;;;;ACrLA,MAAM,gBAAgB,OAAO,eAAe;;;;;;AAO5C,SAAgB,eAAe,OAA+C;CAC1E,OAAO,SAAS,KAAK,KAAK,iBAAiB;AAC/C;AAEA,SAAS,MAAS,OAAc;CAC5B,IAAI,SAAS,KAAK,KAAK,OAAO,aAAa,KAAK,GAC5C,OAAO,eAAe,OAAO,eAAe,EAAE,OAAO,KAAK,CAAC;CAG/D,OAAO;AACX;;;;;;;AAQA,SAAgB,WAAW,OAAoC;CAC3D,OAAO,SAAS,KAAK,KACjB,OAAO,MAAM,eAAe;AACpC;;;;;AAMA,SAAgB,mBAAmB,MAAe;CAC9C,MAAM,SAAS,OAAO,OAAO,MAAM;EAC/B,YAAY,EAAE,OAAO,KAAK;GACzB,OAAO,cAAc,EAAE,OAAO,SAAS;GACvC,gBAAgB,EAAE,OAAO,KAAK;CACnC,CAAC;CAED,IAAI,SAAS,IAAI,GACb,KAAK,MAAM,OAAO,MAAM;EACpB,IAAI,eAAe,QAAQ,GAAG,GAC1B;EAGJ,IAAI,aAAa,OAAO,yBAAyB,MAAM,GAAG;EAC1D,IACI,CAAC,cACA,SAAS,cAAc,WAAW,YAAY,WAAW,cAE1D,aAAa;GACT,YAAY;GACZ,MAAM;IACF,OAAO,KAAK;GAChB;EACJ;EAGJ,OAAO,eAAe,QAAQ,KAAK,UAAU;CACjD;CAGJ,IAAI,CAAC,eAAe,QAAQ,SAAS,GACjC,OAAO,eAAe,QAAQ,WAAW;EACrC,OAAO;EACP,YAAY;CAChB,CAAC;CAGL,OAAO,OAAO,OAAO,MAAM;AAC/B;;;;;;;;AASA,SAAgB,eACZ,MACF;CACE,IAAI,WAAW,IAAI,GAAG;EAGlB,IACI,WAAW,KAAK,OAAO,KACvB,KAAK,QAAQ,SAEb,OAAO,MAAM;GACT,GAAG;GACH,SAAS,KAAK,QAAQ;EAC1B,CAAC;EAKL,OAAO,MAAM,IAAI;CACrB;CAEA,OAAO,mBAAmB,IAAI;AAClC;AAEA,SAAgB,gBACZ,MACA,UACwB;CACxB,MAAM,OAAO,OAAO,KAAK,IAAI;CAC7B,KAAK,MAAM,OAAO,MACd,IAAI,SAAS,KAAe,KAAK,IAAc,GAC3C,OAAO;EACE;EACL,OAAO,KAAK;CAChB;AAKZ;;;;;;;AC5HA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,SAAiB;EACnB,OAAO;CACX;AACJ;;;;;;;;ACHA,IAAa,aAAb,cAAgC,eAAe;CAC3C,UAAU,OAAyB;EAC/B,IAAI,OAAO,UAAU,UACjB,MAAM,IAAI,MAAM,iDAAiD;EAGrE,OAAO;CACX;AACJ;;ACbA,IAAa,aAAb,cAAgC,eAAe;CAC3C,MAAM,SAAiB;EACnB,OAAOA,MAAU,OAAO;CAC5B;AACJ;;ACMA,SAAS,QAAQ,KAAuB;CACpC,OAAO,SAAS,GAAG,IAAI,OAAO,IAAI,KAAK,IAAI,OAAO,GAAG;AACzD;;;;;;;;AASA,SAAS,SAAS,KAAe,MAAe,OAAuC;CACnF,KAAK,MAAM,QAAQ,CAAC,GAAG,KAAK,KAAK,GAC7B,IAAI,CAAC,eAAe,OAAO,QAAQ,KAAK,GAAG,CAAC,GACxC,KAAK,OAAO,KAAK,GAAG;CAI5B,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EAClC,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,KAAK,IAAI,KAAK,IAAI;EAElC,IAAI,MAAM,OAAO,KAAK,SAAS,KAAK,GAAG;GACnC,SAAS,KAAK,SAAS,KAAK;GAC5B;EACJ;EAEA,MAAM,cAAc,IAAI,WAAW,KAAK;EACxC,IAAI,OAAO,OAAO,GAAG;GAGjB,YAAY,gBAAgB,QAAQ;GACpC,YAAY,UAAU,QAAQ;GAC9B,YAAY,cAAc,QAAQ;EACtC;EAEA,KAAK,IAAI,IAAI,WAAW,GAAG,GAAG,WAAW;CAC7C;AACJ;;;;;;;;;AAUA,IAAa,aAAb,cAAgC,eAAe;CAC3C;CAEA,YAAY,UAA6B,CAAC,GAAG;EACzC,MAAM;EACN,KAAK,UAAU;CACnB;CAEA,IAAuB,sBAAgC;EACnD,OAAO;CACX;CAEA,UAAU,OAAgB,UAA4B;EAClD,IAAI,OAAO,aAAa,aACpB,OAAOC,UAAc,OAAO,KAAK,OAAO;EAK5C,MAAM,MAAiB,cAAc,QAAQ;EAC7C,IAAI,IAAI,OAAO,SAAS,GACpB,MAAM,IAAI,OAAO;EAGrB,IAAI,MAAM,IAAI,QAAQ,KAAK,SAAS,KAAK,GACrC,SAAS,KAAK,IAAI,UAAU,KAAK;OAEjC,IAAI,WAAW,IAAI,WAAW,KAAK;EAGvC,OAAO,IAAI,SAAS,KAAK,OAAO;CACpC;AACJ;;;;;;;;;;AC5EA,MAAa,mBAAmB;CAC5B,QAAQ;EAAE,YAAY;EAAwB,cAAc,IAAI,aAAa;CAAE;CAC/E,MAAM;EACF,YAAY,CAAC,OAAO;EACpB,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;CACA,MAAM;EACF,YAAY,CAAC,OAAO;EACpB,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;CACA,MAAM;EACF,YAAY,CAAC,QAAQ,OAAO;EAC5B,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;CACA,MAAM;EACF,YAAY,CAAC,MAAM;EACnB,cAAc,IAAI,WAAW;EAC7B,cAAc,IAAI,WAAW;CACjC;AACJ;;ACYA,SAAS,YAAe,MAAyD;CAC7E,IAAI,OAAO,SAAS,aAChB;CAGJ,IAAI,OAAO,SAAS,YAChB,aAAa;CAGjB,MAAM,UAAU;CAChB,IAAI;CACJ,aAAa;EACT,IAAI,CAAC,QACD,SAAS,QAAQ;EAGrB,OAAO;CACX;AACJ;AAEA,IAAa,iBAAb,MAA4B;;;;CAIxB;;;;CAKA;;;;CAKA;;;;CAKA;CAEA;CAEA,YAAY,UAAiC,CAAC,GAAG;EAC7C,KAAK,QAAQ,CAAC;EACd,KAAK,qCAAqB,IAAI,IAAI;EAClC,KAAK,qCAAqB,IAAI,IAAI;EAClC,KAAK,oCAAoB,IAAI,IAAI;EACjC,KAAK,cAAc;EAEnB,MAAM,MAAM,OAAO,KAAK,gBAAgB;EACxC,KAAK,MAAM,MAAM,KACb,KAAK,MAAM,aAAa,iBAAiB,GAAG,CAAC,YAAY;GACrD,MAAM,WAAW,KAAK,kBAAkB,IAAI,SAAS;GACrD,IAAI,UACA,MAAM,IAAI,YAAY,EAAE,SAAS,aAAa,UAAU,uCAAuC,SAAS,IAAI,GAAG,GAAG,CAAC;GAGvH,KAAK,kBAAkB,IAAI,WAAW,EAAE;EAC5C;EAGJ,IAAI,QAAQ,OACR,KAAK,MAAM,QAAQ,QAAQ,OACvB,KAAK,SAAS,IAAI;CAG9B;CAEA,SAAS,MAAiC;EACtC,IACI,OAAO,KAAK,OAAO,eACnB,eAAe,kBAAkB,KAAK,EAAE,GAExC,MAAM,IAAI,YAAY,EAAE,SAAS,UAAU,KAAK,GAAG,oCAAoC,CAAC;EAG5F,IACI,OAAO,KAAK,WAAW,eACvB,OAAO,KAAK,WAAW,aAEvB,MAAM,IAAI,YAAY,EAAE,SAAS,mDAAmD,CAAC;EAGzF,MAAM,KAAK,KAAK,MAAM,KAAK,eAAe;EAC1C,MAAM,QAAQ,KAAK,QAAQ,IAAI,IAAI;EAEnC,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,UAAU,IACV,KAAK,MAAM,KAAK,KAAK;OAGrB,KAAK,MAAM,SAAS;EAGxB,OAAO;GACH;GACA,MAAM,KAAK;GACX,SAAS;EACb;CACJ;;;;;CAMA,WAAW,IAAsB;EAC7B,MAAM,QAAQ,KAAK,MAAM,WAAW,SAAS,KAAK,OAAO,EAAE;EAC3D,IAAI,UAAU,IACV,OAAO;EAGX,KAAK,MAAM,OAAO,OAAO,CAAC;EAC1B,OAAO;CACX;CAEA,IAAI,IAAsB;EACtB,IAAI,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE,GACxC,OAAO;EAGX,OAAO,eAAe,kBAAkB,EAAE;CAC9C;;;;;CAMA,UAAiC;EAC7B,MAAM,SAAgC,KAAK,MAAM,KAC5C,UAAU;GACP,IAAI,KAAK;GACT,MAAM,KAAK;GACX,SAAS;EACb,EACJ;EAEA,MAAM,MAAM,OAAO,KAAK,gBAAgB;EACxC,KAAK,MAAM,MAAM,KACb,OAAO,KAAK;GACR;GACA,MAAM,CAAC,GAAG,iBAAiB,GAAG,CAAC,UAAU;GACzC,SAAS;EACb,CAAC;EAGL,OAAO;CACX;;;;;;CAOA,QAAe;EACX,KAAK,QAAQ,CAAC;EACd,KAAK,mBAAmB,MAAM;EAC9B,KAAK,mBAAmB,MAAM;EAC9B,KAAK,cAAc;CACvB;;;;;;;;;;;;CAaA,MAAM,KAAK,OAA6B,UAAuB,CAAC,GAAkB;EAC9E,OAAO,aAAa,KAAK,SAAS,OAAO,OAAO,CAAC;CACrD;CAEA,SAAS,OAA6B,UAAuB,CAAC,GAAS;EACnE,OAAO,YAAY,KAAK,SAAS,OAAO,OAAO,CAAC;CACpD;;;;;;;CAQA,MAAM,aAAa,OAA6B,UAAuB,CAAC,GAAkB;EACtF,OAAO,aAAa,KAAK,iBAAiB,OAAO,OAAO,CAAC;CAC7D;CAEA,iBAAiB,OAA6B,UAAuB,CAAC,GAAS;EAC3E,OAAO,YAAY,KAAK,iBAAiB,OAAO,OAAO,CAAC;CAC5D;CAEA,CAAW,SAAS,OAA6B,SAAsC;EACnF,MAAM,EAAE,QAAQ,WAAW,OAAO,KAAK,YAAY,OAAO,OAAO;EACjE,IAAI,kBAAkB,cAClB,OAAO,eAAe,MAAM;EAGhC,OAAO;CACX;CAEA,CAAW,iBAAiB,OAA6B,SAAsC;EAC3F,MAAM,EAAE,QAAQ,WAAW,OAAO,KAAK,YAAY,OAAO,OAAO;EACjE,OAAO,KAAK,SAAS,QAAQ,MAAM;CACvC;;;;;CAMA,CAAW,YACP,OACA,SAC+C;EAC/C,MAAM,WAAW,cAAc,KAAK;EAEpC,IAAI;EACJ,IAAI,OAAO,QAAQ,WAAW,aAC1B,SAAS,KAAK,WAAW,QAAQ;OAEjC,SAAS,KAAK,cAAc,QAAQ,MAAM;EAG9C,IAAI,CAAC,QACD,MAAM,KAAK,sBAAsB,QAAQ;EAG7C,IAAI;GAMA,OAAO;IAAE,QAAA,OALa,SACZ,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC;IAEiB;GAAO;EAC5B,SAAS,GAAG;GACR,MAAM,gBAAgB,GAAG,QAAQ;EACrC;CACJ;;;;;CAMA,MAAM,MAAM,OAA6B,OAAgB,UAAwB,CAAC,GAAmB;EACjG,OAAO,aAAa,KAAK,UAAU,OAAO,OAAO,OAAO,CAAC;CAC7D;CAEA,UAAU,OAA6B,OAAgB,UAAwB,CAAC,GAAU;EACtF,YAAY,KAAK,UAAU,OAAO,OAAO,OAAO,CAAC;CACrD;;;;;;;;;;;;CAaA,CAAW,UACP,OACA,OACA,SACe;EACf,MAAM,WAAW,cAAc,KAAK;EAEpC,IAAI;EACJ,IAAI,OAAO,QAAQ,WAAW,aAAa;GACvC,IAAI,CAAC,WAAW,QAAQ,GACpB,MAAM,IAAI,WAAW;IACjB,SAAS,4CAA4C;IACrD,MAAM;GACV,CAAC;GAGL,MAAM,QAAQ,KAAK,WAAW,QAAQ;GACtC,IAAI,CAAC,OAAO;IACR,IAAI,KAAK,WAAW,QAAQ,GAExB,MAAM,IAAI,WAAW;KACjB,SAAS,2BAFA,kBAAkB,QAES,CAAA,CAAK,UAAU;KACnD,MAAM;IACV,CAAC;IAGL,MAAM,KAAK,sBAAsB,QAAQ;GAC7C;GAEA,SAAS;EACb,OACI,SAAS,KAAK,cAAc,QAAQ,QAAQ,QAAQ;EAGxD,MAAM,QAAQ,eAAe,KAAK,IAAI,MAAM,UAAU;EAEtD,IAAI;GACA,OAAO,SACG,OAAO,MAAM,UAAU,KAAK,SAC5B,OAAO,UAAU,UAAU,KAAK,CAC1C;EACJ,SAAS,GAAG;GACR,MAAM,eAAe,GAAG,QAAQ;EACpC;CACJ;;;;;;;;;CAUA,SAAmB,QAAiB,QAAuB;EACvD,IAAI,kBAAkB,cAClB,OAAO,eAAe,MAAM;EAGhC,OAAO,mBAAmB,MAAM;CACpC;;;;CAKA,cAAyC,IAA4B;EACjE,IAAI,SAAS,KAAK,mBAAmB,IAAI,EAAE;EAC3C,IAAI,CAAC,QAAQ;GACT,SAAS,iBAAiB,GAAG,CAAC,OAAO;GACrC,KAAK,mBAAmB,IAAI,IAAI,MAAM;EAC1C;EAEA,OAAO;CACX;;;;;;CAOA,cAAiD,IAA4B;EACzE,IAAI,SAAS,KAAK,mBAAmB,IAAI,EAAE;EAC3C,IAAI,CAAC,QAAQ;GACT,SAAS,iBAAiB,GAAG,CAAC,OAAO;GACrC,KAAK,mBAAmB,IAAI,IAAI,MAAM;EAC1C;EAEA,OAAO;CACX;;;;;;;;CASA,WAAW,OAAqC;EAC5C,IAAI,CAAC,WAAW,KAAK,GACjB,OAAO,KAAK,cAAc,QAAQ;EAGtC,MAAM,OAAO,KAAK,SAAS,QAAQ,SAAS,OAAO,KAAK,cAAc,WAAW;EACjF,IAAI,QAAQ,KAAK,WACb,OAAO,KAAK,UAAU;EAG1B,MAAM,KAAK,KAAK,cAAc,KAAK;EACnC,IAAI,IACA,OAAO,KAAK,cAAc,EAAE;CAIpC;;;;;;CAOA,WAAW,OAAqC;EAC5C,IAAI,CAAC,WAAW,KAAK,GACjB;EAGJ,MAAM,OAAO,KAAK,SAAS,QAAQ,SAAS,OAAO,KAAK,cAAc,WAAW;EACjF,IAAI,QAAQ,KAAK,WACb,OAAO,KAAK,UAAU;EAG1B,MAAM,KAAK,KAAK,cAAc,KAAK;EACnC,IAAI,MAAM,YAAY,iBAAiB,KACnC,OAAO,KAAK,cAAc,EAA6B;CAI/D;;;;;;CAOA,cAAwB,IAAsB;EAC1C,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;EACrD,IAAI,MAAM;GACN,IAAI,KAAK,WACL,OAAO,KAAK,UAAU;GAG1B,MAAM,IAAI,YAAY,EAAE,SAAS,cAAc,GAAG,iBAAiB,CAAC;EACxE;EAEA,IAAI,eAAe,kBAAkB,EAAE,GACnC,OAAO,KAAK,cAAc,EAAqB;EAGnD,MAAM,KAAK,mBAAmB,EAAE;CACpC;;;;;;CAOA,cAAwB,IAAY,MAAwB;EACxD,MAAM,OAAO,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;EACrD,IAAI,MAAM;GACN,IAAI,KAAK,WACL,OAAO,KAAK,UAAU;GAG1B,MAAM,IAAI,WAAW;IACjB,SAAS,cAAc,GAAG;IAC1B;GACJ,CAAC;EACL;EAEA,IAAI,eAAe,kBAAkB,EAAE,GAAG;GACtC,IAAI,YAAY,iBAAiB,KAC7B,OAAO,KAAK,cAAc,EAA6B;GAG3D,MAAM,IAAI,WAAW;IACjB,SAAS,cAAc,GAAG;IAC1B;GACJ,CAAC;EACL;EAEA,MAAM,KAAK,mBAAmB,EAAE;CACpC;CAEA,SACI,OACA,QACyB;EACzB,MAAM,OAAO,kBAAkB,KAAK;EAEpC,KAAK,MAAM,QAAQ,KAAK,OAAO;GAC3B,IAAI,CAAC,OAAO,IAAI,GACZ;GAGJ,MAAM,EAAE,SAAS;GACjB,IAAI,MAAM,QAAQ,IAAI,GAEd;QAAA,KAAK,aACL,KAAK,SAAS,KAAK,SAAS,GAE5B,OAAO;GAAA,OAER;IAIH,KAAK,YAAY;IACjB,MAAM,UAAU,KAAK,KAAK,cAAc,IAAI,CAAC;IAC7C,KAAK,YAAY;IACjB,IAAI,SACA,OAAO;GAEf;EACJ;CAGJ;CAEA,cAAwB,OAA6C;EACjE,MAAM,OAAO,kBAAkB,KAAK;EACpC,IAAI,CAAC,KAAK,WACN;EAGJ,OAAO,KAAK,kBAAkB,IAAI,KAAK,SAAS;CACpD;CAEA,sBAAgC,OAAuC;EAEnE,OAAO,IAAI,sBAAsB;GAC7B,SAAS,uCAFA,kBAAkB,KAEqB,CAAA,CAAK,aAAa;GAClE,MAAM;EACV,CAAC;CACL;CAEA,mBAA6B,IAA0B;EACnD,OAAO,IAAI,YAAY,EAAE,SAAS,iCAAiC,KAAK,CAAC;CAC7E;CAEA,QAAkB,IAAY,MAA2B;EACrD,OAAO;GACH;GACA,MAAM,KAAK;GACX,WAAW,YAAqB,KAAK,MAAM;GAC3C,WAAW,YAAqB,KAAK,MAAM;EAC/C;CACJ;CAEA,iBAAoC;EAChC,IAAI;EACJ,GAAG;GACC,KAAK;GACL,KAAK,QAAQ,KAAK;EACtB,SAAS,KAAK,MAAM,MAAM,SAAS,KAAK,OAAO,EAAE;EAEjD,OAAO;CACX;AACJ;;ACnkBA,IAAI;AACJ,SAAgB,oBAAoB;CAChC,IAAI,OAAO,aAAa,aACpB,OAAO;CAGX,WAAW,IAAI,eAAe;CAE9B,OAAO;AACX;;ACDA,SAAgB,eAAe,MAAiC;CAC5D,OAAO,kBAAkB,CAAC,CAAC,SAAS,IAAI;AAC5C;;;;;AAMA,SAAgB,iBAAiB,IAAsB;CACnD,OAAO,kBAAkB,CAAC,CAAC,WAAW,EAAE;AAC5C;;;;;;;;;;;AAYA,eAAsB,KAAK,OAA6B,SAAsC;CAC1F,OAAO,kBAAkB,CAAC,CAAC,KAAK,OAAO,OAAO;AAClD;AAEA,SAAgB,SAAS,OAA6B,SAA6B;CAC/E,OAAO,kBAAkB,CAAC,CAAC,SAAS,OAAO,OAAO;AACtD;;;;;;;AAQA,eAAsB,aAAa,OAA6B,SAAsC;CAClG,OAAO,kBAAkB,CAAC,CAAC,aAAa,OAAO,OAAO;AAC1D;AAEA,SAAgB,iBAAiB,OAA6B,SAA6B;CACvF,OAAO,kBAAkB,CAAC,CAAC,iBAAiB,OAAO,OAAO;AAC9D;;;;;;AAOA,eAAsB,MAAM,OAA6B,OAAgB,SAAwC;CAC7G,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,OAAO,OAAO;AAC1D;AAEA,SAAgB,UAAU,OAA6B,OAAgB,SAA+B;CAClG,kBAAkB,CAAC,CAAC,UAAU,OAAO,OAAO,OAAO;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,gBAAgB,SAA2C;CACvE,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,QAAQ;CACzD,MAAM,WAAW,OAAO,UAAU,OAAO;CAEzC,aAAa;EACT,OAAO,UAAU,QAAQ;CAC7B;AACJ;;AC3EA,SAAS,aAAgB,KAAc,OAA+B;CAClE,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,eAAe,KAAK,KAAK,GAC5C;CAEJ,OAAO,IAAI;AACf;AAEA,UAAU,kBACN,SACkC;CAClC,IAAI,QAAQ,QACR,OAAO,OAAO,SACJ,SAAS,gBAAgB;EAAE,KAAK,QAAQ;EAAK,QAAQ,QAAQ;CAAO,CAAC,SACrE,aAAa,gBAAgB;EAAE,KAAK,QAAQ;EAAK,QAAQ,QAAQ;CAAO,CAAC,CACnF;CAGJ,OAAO,OAAO,SACJ,OAAO,gBAAgB,EAAE,KAAK,QAAQ,IAAI,CAAC,SAC3C,WAAW,gBAAgB,EAAE,KAAK,QAAQ,IAAI,CAAC,CACzD;AACJ;AAEA,UAAU,qBACN,OACA,SACwB;CACxB,MAAM,OAAO,OAAO,kBAAkB,OAAO;CAC7C,IAAI,CAAC,MACD;CAMJ,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,MAAM;CACvD,MAAM,WAAW,cAAc,IAAI;CAEnC,IAAI;EAMA,OAAO,aAAgB,OALJ,SACT,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC,GAE4B,KAAK;CACrC,SAAS,GAAG;EACR,IAAI,aAAa,eACb;EAEJ,MAAM;CACV;AACJ;AAEA,eAAsB,iBAClB,OACA,UAAmC,CAAC,GACb;CACvB,OAAO,aAAa,qBAAwB,OAAO,OAAO,CAAC;AAC/D;AAEA,SAAgB,qBACZ,OACA,UAAmC,CAAC,GACtB;CACd,OAAO,YAAY,qBAAwB,OAAO,OAAO,CAAC;AAC9D;AAEA,UAAU,sBACN,OACA,OACA,SACe;CACf,IAAI,CAAC,gBAAgB,KAAK,GACtB,MAAM,IAAI,YAAY,EAAE,SAAS,aAAa,MAAM,4BAA4B,CAAC;CAGrF,MAAM,OAAO,OAAO,kBAAkB,OAAO;CAC7C,IAAI,CAAC,MAGD,MAAM,IAAI,cAAc,EAAE,SAAS,oCAAoC,CAAC;CAG5E,MAAM,SAAS,kBAAkB,CAAC,CAAC,cAAc,MAAM;CACvD,MAAM,WAAW,cAAc,IAAI;CAEnC,MAAM,MAAM,OAAO,SACT,OAAO,KAAK,QAAQ,SACpB,OAAO,SAAS,QAAQ,CAClC;CAEA,IAAI,CAAC,SAAS,GAAG,GACb,MAAM,IAAI,WAAW;EACjB,SAAS;EACT,MAAM;CACV,CAAC;CAGL,IAAI,SAAS;CAIb,MAAM,SAAS,IAAI,WAAW,EAAE,QAAQ,OAAO,CAAC;CAChD,OAAO,SACG,OAAO,MAAM,UAAU,GAAG,SAC1B,OAAO,UAAU,UAAU,GAAG,CACxC;AACJ;;;;;;;AAQA,eAAsB,kBAClB,OACA,OACA,UAAoC,CAAC,GACvB;CACd,OAAO,aAAa,sBAAsB,OAAO,OAAO,OAAO,CAAC;AACpE;AAEA,SAAgB,sBACZ,OACA,OACA,UAAoC,CAAC,GAChC;CACL,YAAY,sBAAsB,OAAO,OAAO,OAAO,CAAC;AAC5D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "locter",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A library to locate files/modules by criteria, read them and write them back!",
|
|
6
6
|
"author": {
|
|
@@ -61,19 +61,20 @@
|
|
|
61
61
|
"@tada5hi/eslint-config": "^2.3.1",
|
|
62
62
|
"@tada5hi/tsconfig": "^0.7.2",
|
|
63
63
|
"@vitest/coverage-v8": "^4.1.10",
|
|
64
|
-
"eslint": "^10.
|
|
64
|
+
"eslint": "^10.8.0",
|
|
65
65
|
"husky": "^9.1.7",
|
|
66
|
-
"tsdown": "^0.22.
|
|
66
|
+
"tsdown": "^0.22.14",
|
|
67
67
|
"typescript": "^6.0.3",
|
|
68
|
-
"typescript-eslint": "^8.
|
|
68
|
+
"typescript-eslint": "^8.65.0",
|
|
69
69
|
"vitest": "^4.1.5"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@ebec/core": "^1.1
|
|
72
|
+
"@ebec/core": "^1.3.1",
|
|
73
73
|
"destr": "^2.0.5",
|
|
74
74
|
"fast-glob": "^3.3.3",
|
|
75
75
|
"flat": "^6.0.1",
|
|
76
76
|
"jiti": "^2.6.1",
|
|
77
|
+
"twinop": "^1.0.0",
|
|
77
78
|
"yaml": "^2.8.1"
|
|
78
79
|
}
|
|
79
80
|
}
|