locter 4.0.0-beta.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +72 -14
- package/dist/index.d.mts +131 -27
- package/dist/index.mjs +187 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -28,7 +28,7 @@ var LocterError = class extends BaseError {
|
|
|
28
28
|
//#endregion
|
|
29
29
|
//#region src/errors/load.ts
|
|
30
30
|
const LOCTER_LOAD_ERROR_MARKER = Symbol.for("@locter/load-error");
|
|
31
|
-
var
|
|
31
|
+
var LoadError = class extends LocterError {
|
|
32
32
|
static [Symbol.hasInstance](input) {
|
|
33
33
|
return hasInstanceof(input, LOCTER_LOAD_ERROR_MARKER);
|
|
34
34
|
}
|
|
@@ -40,7 +40,7 @@ var LocterLoadError = class extends LocterError {
|
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/errors/not-found.ts
|
|
42
42
|
const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for("@locter/not-found-error");
|
|
43
|
-
var
|
|
43
|
+
var NotFoundError = class extends LocterError {
|
|
44
44
|
static [Symbol.hasInstance](input) {
|
|
45
45
|
return hasInstanceof(input, LOCTER_NOT_FOUND_ERROR_MARKER);
|
|
46
46
|
}
|
|
@@ -52,7 +52,7 @@ var LocterNotFoundError = class extends LocterError {
|
|
|
52
52
|
//#endregion
|
|
53
53
|
//#region src/errors/unknown-extension.ts
|
|
54
54
|
const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for("@locter/unknown-extension-error");
|
|
55
|
-
var
|
|
55
|
+
var UnknownExtensionError = class extends LocterError {
|
|
56
56
|
static [Symbol.hasInstance](input) {
|
|
57
57
|
return hasInstanceof(input, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);
|
|
58
58
|
}
|
|
@@ -128,7 +128,7 @@ function isTypeScriptError(input) {
|
|
|
128
128
|
//#endregion
|
|
129
129
|
//#region src/errors/write.ts
|
|
130
130
|
const LOCTER_WRITE_ERROR_MARKER = Symbol.for("@locter/write-error");
|
|
131
|
-
var
|
|
131
|
+
var WriteError = class extends LocterError {
|
|
132
132
|
static [Symbol.hasInstance](input) {
|
|
133
133
|
return hasInstanceof(input, LOCTER_WRITE_ERROR_MARKER);
|
|
134
134
|
}
|
|
@@ -148,13 +148,13 @@ function wrapLoaderError(input, path) {
|
|
|
148
148
|
if (input instanceof LocterError) return input;
|
|
149
149
|
const code = isObject(input) && hasStringProperty(input, "code") ? input.code : void 0;
|
|
150
150
|
const message = isObject(input) && hasStringProperty(input, "message") ? input.message : `Failed to load: ${path}`;
|
|
151
|
-
if (code && NOT_FOUND_CODES.has(code)) return new
|
|
151
|
+
if (code && NOT_FOUND_CODES.has(code)) return new NotFoundError({
|
|
152
152
|
message,
|
|
153
153
|
code,
|
|
154
154
|
cause: input,
|
|
155
155
|
path
|
|
156
156
|
});
|
|
157
|
-
return new
|
|
157
|
+
return new LoadError({
|
|
158
158
|
message,
|
|
159
159
|
code,
|
|
160
160
|
cause: input,
|
|
@@ -164,7 +164,7 @@ function wrapLoaderError(input, path) {
|
|
|
164
164
|
function wrapWriteError(input, path) {
|
|
165
165
|
if (input instanceof LocterError) return input;
|
|
166
166
|
const code = isObject(input) && hasStringProperty(input, "code") ? input.code : void 0;
|
|
167
|
-
return new
|
|
167
|
+
return new WriteError({
|
|
168
168
|
message: isObject(input) && hasStringProperty(input, "message") ? input.message : `Failed to write: ${path}`,
|
|
169
169
|
code,
|
|
170
170
|
cause: input,
|
|
@@ -372,7 +372,7 @@ function isNotFound(e) {
|
|
|
372
372
|
* Base class for writers of text-based file formats: serializes via
|
|
373
373
|
* `stringify`, creates missing parent directories, writes the file as
|
|
374
374
|
* UTF-8 (always terminated by a single trailing newline), and wraps
|
|
375
|
-
* failures in
|
|
375
|
+
* failures in WriteError. Subclasses implement `stringify` only —
|
|
376
376
|
* both `write` variants are derived from the same body.
|
|
377
377
|
*/
|
|
378
378
|
var TextFileWriter = class {
|
|
@@ -444,11 +444,39 @@ var ConfReader = class extends TextFileReader {
|
|
|
444
444
|
}
|
|
445
445
|
};
|
|
446
446
|
//#endregion
|
|
447
|
-
//#region src/format/
|
|
448
|
-
|
|
449
|
-
|
|
447
|
+
//#region src/format/value.ts
|
|
448
|
+
/**
|
|
449
|
+
* Lenient VALUE codec (env-var / key-value philosophy): primitives
|
|
450
|
+
* serialize to their bare string form, RegExp and BigInt to their
|
|
451
|
+
* string representation (also nested), everything else to JSON.
|
|
452
|
+
* The counterpart of deserializeValue — used per value by the conf
|
|
453
|
+
* format, and exported for consumers building lenient custom formats.
|
|
454
|
+
*/
|
|
455
|
+
function serializeValue(input) {
|
|
456
|
+
if (typeof input === "string") return input;
|
|
457
|
+
if (typeof input === "undefined") return "undefined";
|
|
458
|
+
if (input === null) return "null";
|
|
459
|
+
if (typeof input === "boolean") return input ? "true" : "false";
|
|
460
|
+
if (typeof input === "number") return `${input}`;
|
|
461
|
+
if (typeof input === "bigint") return input.toString();
|
|
462
|
+
if (input instanceof RegExp) return input.toString();
|
|
463
|
+
return JSON.stringify(input, (_key, item) => {
|
|
464
|
+
if (item instanceof RegExp) return item.toString();
|
|
465
|
+
if (typeof item === "bigint") return item.toString();
|
|
466
|
+
return item;
|
|
467
|
+
}) ?? String(input);
|
|
450
468
|
}
|
|
451
469
|
/**
|
|
470
|
+
* Lenient parse of a serialized value: coerces 'true'/'123'/'null'/
|
|
471
|
+
* 'undefined' to their primitive, parses JSON payloads, and falls back
|
|
472
|
+
* to returning the raw string — it never throws.
|
|
473
|
+
*/
|
|
474
|
+
function deserializeValue(input) {
|
|
475
|
+
return destr(input);
|
|
476
|
+
}
|
|
477
|
+
//#endregion
|
|
478
|
+
//#region src/format/built-in/conf/writer.ts
|
|
479
|
+
/**
|
|
452
480
|
* Serializes an object to `key=value` lines (the inverse of ConfReader):
|
|
453
481
|
* nested objects become dot-separated keys, arrays become repeated
|
|
454
482
|
* `key[]=` lines. Round-trips are structural, not textual — comments,
|
|
@@ -694,6 +722,32 @@ function getModuleExport(data, filterFn) {
|
|
|
694
722
|
};
|
|
695
723
|
}
|
|
696
724
|
//#endregion
|
|
725
|
+
//#region src/format/built-in/text/reader.ts
|
|
726
|
+
/**
|
|
727
|
+
* Raw text: the file content, as-is. No value coercion — a .txt
|
|
728
|
+
* containing '123' reads as the string '123' (use deserializeValue
|
|
729
|
+
* for lenient value semantics).
|
|
730
|
+
*/
|
|
731
|
+
var TextReader = class extends TextFileReader {
|
|
732
|
+
parse(content) {
|
|
733
|
+
return content;
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
//#endregion
|
|
737
|
+
//#region src/format/built-in/text/writer.ts
|
|
738
|
+
/**
|
|
739
|
+
* Raw text: accepts strings only — coercing arbitrary values would be
|
|
740
|
+
* lossy ([object Object]); serialize explicitly (e.g. serializeValue)
|
|
741
|
+
* before writing. Output ends with a single trailing newline, like
|
|
742
|
+
* every text writer.
|
|
743
|
+
*/
|
|
744
|
+
var TextWriter = class extends TextFileWriter {
|
|
745
|
+
stringify(value) {
|
|
746
|
+
if (typeof value !== "string") throw new Error("The value must be a string for the text format.");
|
|
747
|
+
return value;
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
//#endregion
|
|
697
751
|
//#region src/format/built-in/yaml/reader.ts
|
|
698
752
|
var YAMLReader = class extends TextFileReader {
|
|
699
753
|
parse(content) {
|
|
@@ -735,7 +789,7 @@ function graftMap(doc, node, value) {
|
|
|
735
789
|
* target file already exists, the new value is grafted into its parsed
|
|
736
790
|
* document, so comments and anchors attached to surviving keys survive
|
|
737
791
|
* the write-back. New files are plain `yaml.stringify` output. An
|
|
738
|
-
* existing file that fails to parse throws (wrapped as
|
|
792
|
+
* existing file that fails to parse throws (wrapped as WriteError)
|
|
739
793
|
* instead of being silently overwritten.
|
|
740
794
|
*/
|
|
741
795
|
var YAMLWriter = class extends TextFileWriter {
|
|
@@ -785,6 +839,11 @@ const BUILT_IN_PRESETS = {
|
|
|
785
839
|
extensions: [".yml", ".yaml"],
|
|
786
840
|
reader: () => new YAMLReader(),
|
|
787
841
|
writer: () => new YAMLWriter()
|
|
842
|
+
},
|
|
843
|
+
text: {
|
|
844
|
+
extensions: [".txt"],
|
|
845
|
+
reader: () => new TextReader(),
|
|
846
|
+
writer: () => new TextWriter()
|
|
788
847
|
}
|
|
789
848
|
};
|
|
790
849
|
//#endregion
|
|
@@ -894,12 +953,16 @@ var FormatRegistry = class {
|
|
|
894
953
|
* normalized module record — a module IS a record, and the
|
|
895
954
|
* normalization only irons out the CJS/ESM interop divergence so
|
|
896
955
|
* both twin variants agree on one shape.
|
|
956
|
+
*
|
|
957
|
+
* options.format names a registered format id to use instead of
|
|
958
|
+
* extension dispatch (e.g. { format: 'text' } reads module source
|
|
959
|
+
* without evaluating it).
|
|
897
960
|
*/
|
|
898
|
-
async read(input) {
|
|
899
|
-
return runTwinAsync(this.readBody(input));
|
|
961
|
+
async read(input, options = {}) {
|
|
962
|
+
return runTwinAsync(this.readBody(input, options));
|
|
900
963
|
}
|
|
901
|
-
readSync(input) {
|
|
902
|
-
return runTwinSync(this.readBody(input));
|
|
964
|
+
readSync(input, options = {}) {
|
|
965
|
+
return runTwinSync(this.readBody(input, options));
|
|
903
966
|
}
|
|
904
967
|
/**
|
|
905
968
|
* Read a file/module and present the result as a normalized module
|
|
@@ -907,28 +970,30 @@ var FormatRegistry = class {
|
|
|
907
970
|
* `.default` always holds the loaded value, top-level keys are
|
|
908
971
|
* re-exposed as named exports.
|
|
909
972
|
*/
|
|
910
|
-
async readAsModule(input) {
|
|
911
|
-
return runTwinAsync(this.readAsModuleBody(input));
|
|
973
|
+
async readAsModule(input, options = {}) {
|
|
974
|
+
return runTwinAsync(this.readAsModuleBody(input, options));
|
|
912
975
|
}
|
|
913
|
-
readAsModuleSync(input) {
|
|
914
|
-
return runTwinSync(this.readAsModuleBody(input));
|
|
976
|
+
readAsModuleSync(input, options = {}) {
|
|
977
|
+
return runTwinSync(this.readAsModuleBody(input, options));
|
|
915
978
|
}
|
|
916
|
-
*readBody(input) {
|
|
917
|
-
const { output, reader } = yield* this.executeBody(input);
|
|
979
|
+
*readBody(input, options) {
|
|
980
|
+
const { output, reader } = yield* this.executeBody(input, options);
|
|
918
981
|
if (reader instanceof ModuleReader) return toModuleRecord(output);
|
|
919
982
|
return output;
|
|
920
983
|
}
|
|
921
|
-
*readAsModuleBody(input) {
|
|
922
|
-
const { output, reader } = yield* this.executeBody(input);
|
|
984
|
+
*readAsModuleBody(input, options) {
|
|
985
|
+
const { output, reader } = yield* this.executeBody(input, options);
|
|
923
986
|
return this.toRecord(output, reader);
|
|
924
987
|
}
|
|
925
988
|
/**
|
|
926
989
|
* Shared dispatch + execution of both read bodies: resolve the
|
|
927
990
|
* reader, run it, wrap errors. Normalization is the caller's call.
|
|
928
991
|
*/
|
|
929
|
-
*executeBody(input) {
|
|
992
|
+
*executeBody(input, options) {
|
|
930
993
|
const filePath = buildFilePath(input);
|
|
931
|
-
|
|
994
|
+
let reader;
|
|
995
|
+
if (typeof options.format === "undefined") reader = this.findReader(filePath);
|
|
996
|
+
else reader = this.resolveReader(options.format);
|
|
932
997
|
if (!reader) throw this.unknownExtensionError(filePath);
|
|
933
998
|
try {
|
|
934
999
|
return {
|
|
@@ -939,32 +1004,45 @@ var FormatRegistry = class {
|
|
|
939
1004
|
throw wrapLoaderError(e, filePath);
|
|
940
1005
|
}
|
|
941
1006
|
}
|
|
942
|
-
|
|
943
|
-
|
|
1007
|
+
/**
|
|
1008
|
+
* options.format names a registered format id to use instead of
|
|
1009
|
+
* extension dispatch — see writeBody for the boundary semantics.
|
|
1010
|
+
*/
|
|
1011
|
+
async write(input, value, options = {}) {
|
|
1012
|
+
return runTwinAsync(this.writeBody(input, value, options));
|
|
944
1013
|
}
|
|
945
|
-
writeSync(input, value) {
|
|
946
|
-
runTwinSync(this.writeBody(input, value));
|
|
1014
|
+
writeSync(input, value, options = {}) {
|
|
1015
|
+
runTwinSync(this.writeBody(input, value, options));
|
|
947
1016
|
}
|
|
948
1017
|
/**
|
|
949
1018
|
* Shared body of write/writeSync: dispatch, unwrap records, write, wrap.
|
|
950
1019
|
* The inverse boundary of readAsModuleBody: a record produced by
|
|
951
1020
|
* readAsModule() (brand detected) is unwrapped to its `.default` value;
|
|
952
1021
|
* anything else is written as-is.
|
|
1022
|
+
*
|
|
1023
|
+
* An explicit options.format skips extension dispatch entirely —
|
|
1024
|
+
* including the bare-specifier guard: naming the format resolves the
|
|
1025
|
+
* ambiguity the guard exists for, so extensionless paths become
|
|
1026
|
+
* writable.
|
|
953
1027
|
*/
|
|
954
|
-
*writeBody(input, value) {
|
|
1028
|
+
*writeBody(input, value, options) {
|
|
955
1029
|
const filePath = buildFilePath(input);
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
const writer = this.findWriter(filePath);
|
|
961
|
-
if (!writer) {
|
|
962
|
-
if (this.findReader(filePath)) throw new LocterWriteError({
|
|
963
|
-
message: `The format of extension ${pathToLocatorInfo(filePath).extension} is read-only.`,
|
|
1030
|
+
let writer;
|
|
1031
|
+
if (typeof options.format === "undefined") {
|
|
1032
|
+
if (!isFilePath(filePath)) throw new WriteError({
|
|
1033
|
+
message: `Cannot write to a bare module specifier: ${filePath}`,
|
|
964
1034
|
path: filePath
|
|
965
1035
|
});
|
|
966
|
-
|
|
967
|
-
|
|
1036
|
+
const found = this.findWriter(filePath);
|
|
1037
|
+
if (!found) {
|
|
1038
|
+
if (this.findReader(filePath)) throw new WriteError({
|
|
1039
|
+
message: `The format of extension ${pathToLocatorInfo(filePath).extension} is read-only.`,
|
|
1040
|
+
path: filePath
|
|
1041
|
+
});
|
|
1042
|
+
throw this.unknownExtensionError(filePath);
|
|
1043
|
+
}
|
|
1044
|
+
writer = found;
|
|
1045
|
+
} else writer = this.resolveWriter(options.format, filePath);
|
|
968
1046
|
const plain = isModuleRecord(value) ? value.default : value;
|
|
969
1047
|
try {
|
|
970
1048
|
yield* op(() => writer.write(filePath, plain), () => writer.writeSync(filePath, plain));
|
|
@@ -1013,7 +1091,7 @@ var FormatRegistry = class {
|
|
|
1013
1091
|
* 1. bare specifier (no extension) → module reader, always
|
|
1014
1092
|
* 2. user rules, registration order → first match wins (can override built-ins)
|
|
1015
1093
|
* 3. built-in extension table
|
|
1016
|
-
* 4. undefined → read/readSync throw
|
|
1094
|
+
* 4. undefined → read/readSync throw UnknownExtensionError
|
|
1017
1095
|
*/
|
|
1018
1096
|
findReader(input) {
|
|
1019
1097
|
if (!isFilePath(input)) return this.builtInReader("module");
|
|
@@ -1034,6 +1112,43 @@ var FormatRegistry = class {
|
|
|
1034
1112
|
const id = this.findBuiltInId(input);
|
|
1035
1113
|
if (id && "writer" in BUILT_IN_PRESETS[id]) return this.builtInWriter(id);
|
|
1036
1114
|
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Resolve a reader by EXPLICIT format id (the per-call override) —
|
|
1117
|
+
* a user rule id or a built-in id — bypassing extension dispatch.
|
|
1118
|
+
* Unknown ids and writer-only rules throw.
|
|
1119
|
+
*/
|
|
1120
|
+
resolveReader(id) {
|
|
1121
|
+
const rule = this.rules.find((item) => item.id === id);
|
|
1122
|
+
if (rule) {
|
|
1123
|
+
if (rule.getReader) return rule.getReader();
|
|
1124
|
+
throw new LocterError({ message: `The format ${id} has no reader.` });
|
|
1125
|
+
}
|
|
1126
|
+
if (hasOwnProperty(BUILT_IN_PRESETS, id)) return this.builtInReader(id);
|
|
1127
|
+
throw this.unknownFormatError(id);
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Write-side counterpart of resolveReader. Reader-only rules and
|
|
1131
|
+
* read-only built-ins (module) throw WriteError, mirroring
|
|
1132
|
+
* what extension dispatch throws for read-only extensions.
|
|
1133
|
+
*/
|
|
1134
|
+
resolveWriter(id, path) {
|
|
1135
|
+
const rule = this.rules.find((item) => item.id === id);
|
|
1136
|
+
if (rule) {
|
|
1137
|
+
if (rule.getWriter) return rule.getWriter();
|
|
1138
|
+
throw new WriteError({
|
|
1139
|
+
message: `The format ${id} is read-only.`,
|
|
1140
|
+
path
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
if (hasOwnProperty(BUILT_IN_PRESETS, id)) {
|
|
1144
|
+
if ("writer" in BUILT_IN_PRESETS[id]) return this.builtInWriter(id);
|
|
1145
|
+
throw new WriteError({
|
|
1146
|
+
message: `The format ${id} is read-only.`,
|
|
1147
|
+
path
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
throw this.unknownFormatError(id);
|
|
1151
|
+
}
|
|
1037
1152
|
findRule(input, filter) {
|
|
1038
1153
|
const info = pathToLocatorInfo(input);
|
|
1039
1154
|
for (const rule of this.rules) {
|
|
@@ -1055,11 +1170,14 @@ var FormatRegistry = class {
|
|
|
1055
1170
|
return this.builtInExtensions.get(info.extension);
|
|
1056
1171
|
}
|
|
1057
1172
|
unknownExtensionError(input) {
|
|
1058
|
-
return new
|
|
1173
|
+
return new UnknownExtensionError({
|
|
1059
1174
|
message: `No format registered for extension: ${pathToLocatorInfo(input).extension ?? "unknown"}`,
|
|
1060
1175
|
path: input
|
|
1061
1176
|
});
|
|
1062
1177
|
}
|
|
1178
|
+
unknownFormatError(id) {
|
|
1179
|
+
return new LocterError({ message: `No format registered with id: ${id}` });
|
|
1180
|
+
}
|
|
1063
1181
|
compile(id, rule) {
|
|
1064
1182
|
return {
|
|
1065
1183
|
id,
|
|
@@ -1102,12 +1220,16 @@ function unregisterFormat(id) {
|
|
|
1102
1220
|
* (json/yaml/conf and custom readers — mutable, round-trip-symmetric
|
|
1103
1221
|
* with write); for modules the normalized module record (a module IS a
|
|
1104
1222
|
* record; normalization only irons out CJS/ESM interop divergence).
|
|
1223
|
+
*
|
|
1224
|
+
* options.format forces a registered format id instead of extension
|
|
1225
|
+
* dispatch — e.g. { format: 'text' } reads a module file's source
|
|
1226
|
+
* WITHOUT evaluating it.
|
|
1105
1227
|
*/
|
|
1106
|
-
async function read(input) {
|
|
1107
|
-
return useFormatRegistry().read(input);
|
|
1228
|
+
async function read(input, options) {
|
|
1229
|
+
return useFormatRegistry().read(input, options);
|
|
1108
1230
|
}
|
|
1109
|
-
function readSync(input) {
|
|
1110
|
-
return useFormatRegistry().readSync(input);
|
|
1231
|
+
function readSync(input, options) {
|
|
1232
|
+
return useFormatRegistry().readSync(input, options);
|
|
1111
1233
|
}
|
|
1112
1234
|
/**
|
|
1113
1235
|
* Read a file/module and present the result as a normalized module
|
|
@@ -1115,17 +1237,22 @@ function readSync(input) {
|
|
|
1115
1237
|
* always holds the loaded value, top-level keys are re-exposed as
|
|
1116
1238
|
* named exports.
|
|
1117
1239
|
*/
|
|
1118
|
-
async function readAsModule(input) {
|
|
1119
|
-
return useFormatRegistry().readAsModule(input);
|
|
1240
|
+
async function readAsModule(input, options) {
|
|
1241
|
+
return useFormatRegistry().readAsModule(input, options);
|
|
1120
1242
|
}
|
|
1121
|
-
function readAsModuleSync(input) {
|
|
1122
|
-
return useFormatRegistry().readAsModuleSync(input);
|
|
1243
|
+
function readAsModuleSync(input, options) {
|
|
1244
|
+
return useFormatRegistry().readAsModuleSync(input, options);
|
|
1123
1245
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1246
|
+
/**
|
|
1247
|
+
* options.format forces a registered format id instead of extension
|
|
1248
|
+
* dispatch — this also lifts the bare-specifier guard (extensionless
|
|
1249
|
+
* paths) and the read-only block on module extensions.
|
|
1250
|
+
*/
|
|
1251
|
+
async function write(input, value, options) {
|
|
1252
|
+
return useFormatRegistry().write(input, value, options);
|
|
1126
1253
|
}
|
|
1127
|
-
function writeSync(input, value) {
|
|
1128
|
-
useFormatRegistry().writeSync(input, value);
|
|
1254
|
+
function writeSync(input, value, options) {
|
|
1255
|
+
useFormatRegistry().writeSync(input, value, options);
|
|
1129
1256
|
}
|
|
1130
1257
|
/**
|
|
1131
1258
|
* Override the built-in module reader's `import` / `require` calls.
|
|
@@ -1182,7 +1309,7 @@ function* readPackageFieldBody(field, options) {
|
|
|
1182
1309
|
try {
|
|
1183
1310
|
return extractField(yield* op(() => reader.read(filePath), () => reader.readSync(filePath)), field);
|
|
1184
1311
|
} catch (e) {
|
|
1185
|
-
if (e instanceof
|
|
1312
|
+
if (e instanceof NotFoundError) return;
|
|
1186
1313
|
throw e;
|
|
1187
1314
|
}
|
|
1188
1315
|
}
|
|
@@ -1195,11 +1322,11 @@ function readPackageFieldSync(field, options = {}) {
|
|
|
1195
1322
|
function* writePackageFieldBody(field, value, options) {
|
|
1196
1323
|
if (!isSafeObjectKey(field)) throw new LocterError({ message: `The field ${field} is not a safe object key.` });
|
|
1197
1324
|
const info = yield* locatePackageBody(options);
|
|
1198
|
-
if (!info) throw new
|
|
1325
|
+
if (!info) throw new NotFoundError({ message: "No package.json could be located." });
|
|
1199
1326
|
const reader = useFormatRegistry().builtInReader("json");
|
|
1200
1327
|
const filePath = buildFilePath(info);
|
|
1201
1328
|
const pkg = yield* op(() => reader.read(filePath), () => reader.readSync(filePath));
|
|
1202
|
-
if (!isObject(pkg)) throw new
|
|
1329
|
+
if (!isObject(pkg)) throw new WriteError({
|
|
1203
1330
|
message: "The located package.json does not contain an object.",
|
|
1204
1331
|
path: filePath
|
|
1205
1332
|
});
|
|
@@ -1211,7 +1338,7 @@ function* writePackageFieldBody(field, value, options) {
|
|
|
1211
1338
|
* Set a top-level field of the nearest `package.json` (same locate
|
|
1212
1339
|
* semantics as readPackageField) and write it back, preserving the
|
|
1213
1340
|
* file's existing indentation. Passing `undefined` removes the field.
|
|
1214
|
-
* Throws
|
|
1341
|
+
* Throws NotFoundError when no package.json could be located.
|
|
1215
1342
|
*/
|
|
1216
1343
|
async function writePackageField(field, value, options = {}) {
|
|
1217
1344
|
return runTwinAsync(writePackageFieldBody(field, value, options));
|
|
@@ -1220,6 +1347,6 @@ function writePackageFieldSync(field, value, options = {}) {
|
|
|
1220
1347
|
runTwinSync(writePackageFieldBody(field, value, options));
|
|
1221
1348
|
}
|
|
1222
1349
|
//#endregion
|
|
1223
|
-
export { ConfReader, ConfWriter, FormatRegistry, JSONReader, JSONWriter, LOCTER_ERROR_MARKER, LOCTER_LOAD_ERROR_MARKER, LOCTER_NOT_FOUND_ERROR_MARKER, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER, LOCTER_WRITE_ERROR_MARKER, LocterError,
|
|
1350
|
+
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 };
|
|
1224
1351
|
|
|
1225
1352
|
//# sourceMappingURL=index.mjs.map
|