locter 4.0.0 → 4.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +52 -14
- package/dist/index.d.mts +90 -45
- package/dist/index.mjs +146 -102
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -5
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";
|
|
@@ -28,7 +29,7 @@ var LocterError = class extends BaseError {
|
|
|
28
29
|
//#endregion
|
|
29
30
|
//#region src/errors/load.ts
|
|
30
31
|
const LOCTER_LOAD_ERROR_MARKER = Symbol.for("@locter/load-error");
|
|
31
|
-
var
|
|
32
|
+
var LoadError = class extends LocterError {
|
|
32
33
|
static [Symbol.hasInstance](input) {
|
|
33
34
|
return hasInstanceof(input, LOCTER_LOAD_ERROR_MARKER);
|
|
34
35
|
}
|
|
@@ -40,7 +41,7 @@ var LocterLoadError = class extends LocterError {
|
|
|
40
41
|
//#endregion
|
|
41
42
|
//#region src/errors/not-found.ts
|
|
42
43
|
const LOCTER_NOT_FOUND_ERROR_MARKER = Symbol.for("@locter/not-found-error");
|
|
43
|
-
var
|
|
44
|
+
var NotFoundError = class extends LocterError {
|
|
44
45
|
static [Symbol.hasInstance](input) {
|
|
45
46
|
return hasInstanceof(input, LOCTER_NOT_FOUND_ERROR_MARKER);
|
|
46
47
|
}
|
|
@@ -52,7 +53,7 @@ var LocterNotFoundError = class extends LocterError {
|
|
|
52
53
|
//#endregion
|
|
53
54
|
//#region src/errors/unknown-extension.ts
|
|
54
55
|
const LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER = Symbol.for("@locter/unknown-extension-error");
|
|
55
|
-
var
|
|
56
|
+
var UnknownExtensionError = class extends LocterError {
|
|
56
57
|
static [Symbol.hasInstance](input) {
|
|
57
58
|
return hasInstanceof(input, LOCTER_UNKNOWN_EXTENSION_ERROR_MARKER);
|
|
58
59
|
}
|
|
@@ -108,15 +109,29 @@ function isJestRuntimeEnvironment() {
|
|
|
108
109
|
function isVitestRuntimeEnvironment() {
|
|
109
110
|
return typeof process !== "undefined" && process.env.VITEST === "true";
|
|
110
111
|
}
|
|
112
|
+
const MODULE_OPTION_REGEX = /^(?:-r|--require|--import|--(?:experimental-)?loader)(?:=(.*))?$/;
|
|
113
|
+
function matchesProcessMarker(regex) {
|
|
114
|
+
if (typeof process === "undefined") return false;
|
|
115
|
+
const { execArgv } = process;
|
|
116
|
+
if (Array.isArray(execArgv)) for (let i = 0; i < execArgv.length; i++) {
|
|
117
|
+
const arg = execArgv[i];
|
|
118
|
+
if (typeof arg !== "string") continue;
|
|
119
|
+
const option = MODULE_OPTION_REGEX.exec(arg);
|
|
120
|
+
if (!option) continue;
|
|
121
|
+
const value = typeof option[1] === "string" ? option[1] : execArgv[i + 1];
|
|
122
|
+
if (typeof value === "string" && regex.test(value)) return true;
|
|
123
|
+
}
|
|
124
|
+
const { _preload_modules: preloadModules } = process;
|
|
125
|
+
return Array.isArray(preloadModules) && preloadModules.some((el) => regex.test(el));
|
|
126
|
+
}
|
|
127
|
+
const TS_NODE_MARKER_REGEX = /(?:^|=|[\\/"'])ts-node(?:$|[\\/"'])/;
|
|
111
128
|
function isTsNodeRuntimeEnvironment() {
|
|
112
|
-
|
|
129
|
+
if (process[Symbol.for("ts-node.register.instance")]) return true;
|
|
130
|
+
return matchesProcessMarker(TS_NODE_MARKER_REGEX);
|
|
113
131
|
}
|
|
114
|
-
const TSX_MARKER_REGEX = /(?:^|=|[\\/])tsx(?:$|[\\/])/;
|
|
132
|
+
const TSX_MARKER_REGEX = /(?:^|=|[\\/"'])tsx(?:$|[\\/"'])/;
|
|
115
133
|
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));
|
|
134
|
+
return matchesProcessMarker(TSX_MARKER_REGEX);
|
|
120
135
|
}
|
|
121
136
|
//#endregion
|
|
122
137
|
//#region src/utils/typescript.ts
|
|
@@ -128,7 +143,7 @@ function isTypeScriptError(input) {
|
|
|
128
143
|
//#endregion
|
|
129
144
|
//#region src/errors/write.ts
|
|
130
145
|
const LOCTER_WRITE_ERROR_MARKER = Symbol.for("@locter/write-error");
|
|
131
|
-
var
|
|
146
|
+
var WriteError = class extends LocterError {
|
|
132
147
|
static [Symbol.hasInstance](input) {
|
|
133
148
|
return hasInstanceof(input, LOCTER_WRITE_ERROR_MARKER);
|
|
134
149
|
}
|
|
@@ -148,13 +163,13 @@ function wrapLoaderError(input, path) {
|
|
|
148
163
|
if (input instanceof LocterError) return input;
|
|
149
164
|
const code = isObject(input) && hasStringProperty(input, "code") ? input.code : void 0;
|
|
150
165
|
const message = isObject(input) && hasStringProperty(input, "message") ? input.message : `Failed to load: ${path}`;
|
|
151
|
-
if (code && NOT_FOUND_CODES.has(code)) return new
|
|
166
|
+
if (code && NOT_FOUND_CODES.has(code)) return new NotFoundError({
|
|
152
167
|
message,
|
|
153
168
|
code,
|
|
154
169
|
cause: input,
|
|
155
170
|
path
|
|
156
171
|
});
|
|
157
|
-
return new
|
|
172
|
+
return new LoadError({
|
|
158
173
|
message,
|
|
159
174
|
code,
|
|
160
175
|
cause: input,
|
|
@@ -164,7 +179,7 @@ function wrapLoaderError(input, path) {
|
|
|
164
179
|
function wrapWriteError(input, path) {
|
|
165
180
|
if (input instanceof LocterError) return input;
|
|
166
181
|
const code = isObject(input) && hasStringProperty(input, "code") ? input.code : void 0;
|
|
167
|
-
return new
|
|
182
|
+
return new WriteError({
|
|
168
183
|
message: isObject(input) && hasStringProperty(input, "message") ? input.message : `Failed to write: ${path}`,
|
|
169
184
|
code,
|
|
170
185
|
cause: input,
|
|
@@ -172,45 +187,6 @@ function wrapWriteError(input, path) {
|
|
|
172
187
|
});
|
|
173
188
|
}
|
|
174
189
|
//#endregion
|
|
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
190
|
//#region src/locator/utils.ts
|
|
215
191
|
function buildLocatorPatterns(pattern) {
|
|
216
192
|
return Array.isArray(pattern) ? pattern : [pattern];
|
|
@@ -372,7 +348,7 @@ function isNotFound(e) {
|
|
|
372
348
|
* Base class for writers of text-based file formats: serializes via
|
|
373
349
|
* `stringify`, creates missing parent directories, writes the file as
|
|
374
350
|
* UTF-8 (always terminated by a single trailing newline), and wraps
|
|
375
|
-
* failures in
|
|
351
|
+
* failures in WriteError. Subclasses implement `stringify` only —
|
|
376
352
|
* both `write` variants are derived from the same body.
|
|
377
353
|
*/
|
|
378
354
|
var TextFileWriter = class {
|
|
@@ -789,7 +765,7 @@ function graftMap(doc, node, value) {
|
|
|
789
765
|
* target file already exists, the new value is grafted into its parsed
|
|
790
766
|
* document, so comments and anchors attached to surviving keys survive
|
|
791
767
|
* the write-back. New files are plain `yaml.stringify` output. An
|
|
792
|
-
* existing file that fails to parse throws (wrapped as
|
|
768
|
+
* existing file that fails to parse throws (wrapped as WriteError)
|
|
793
769
|
* instead of being silently overwritten.
|
|
794
770
|
*/
|
|
795
771
|
var YAMLWriter = class extends TextFileWriter {
|
|
@@ -953,12 +929,16 @@ var FormatRegistry = class {
|
|
|
953
929
|
* normalized module record — a module IS a record, and the
|
|
954
930
|
* normalization only irons out the CJS/ESM interop divergence so
|
|
955
931
|
* both twin variants agree on one shape.
|
|
932
|
+
*
|
|
933
|
+
* options.format names a registered format id to use instead of
|
|
934
|
+
* extension dispatch (e.g. { format: 'text' } reads module source
|
|
935
|
+
* without evaluating it).
|
|
956
936
|
*/
|
|
957
|
-
async read(input) {
|
|
958
|
-
return runTwinAsync(this.readBody(input));
|
|
937
|
+
async read(input, options = {}) {
|
|
938
|
+
return runTwinAsync(this.readBody(input, options));
|
|
959
939
|
}
|
|
960
|
-
readSync(input) {
|
|
961
|
-
return runTwinSync(this.readBody(input));
|
|
940
|
+
readSync(input, options = {}) {
|
|
941
|
+
return runTwinSync(this.readBody(input, options));
|
|
962
942
|
}
|
|
963
943
|
/**
|
|
964
944
|
* Read a file/module and present the result as a normalized module
|
|
@@ -966,28 +946,30 @@ var FormatRegistry = class {
|
|
|
966
946
|
* `.default` always holds the loaded value, top-level keys are
|
|
967
947
|
* re-exposed as named exports.
|
|
968
948
|
*/
|
|
969
|
-
async readAsModule(input) {
|
|
970
|
-
return runTwinAsync(this.readAsModuleBody(input));
|
|
949
|
+
async readAsModule(input, options = {}) {
|
|
950
|
+
return runTwinAsync(this.readAsModuleBody(input, options));
|
|
971
951
|
}
|
|
972
|
-
readAsModuleSync(input) {
|
|
973
|
-
return runTwinSync(this.readAsModuleBody(input));
|
|
952
|
+
readAsModuleSync(input, options = {}) {
|
|
953
|
+
return runTwinSync(this.readAsModuleBody(input, options));
|
|
974
954
|
}
|
|
975
|
-
*readBody(input) {
|
|
976
|
-
const { output, reader } = yield* this.executeBody(input);
|
|
955
|
+
*readBody(input, options) {
|
|
956
|
+
const { output, reader } = yield* this.executeBody(input, options);
|
|
977
957
|
if (reader instanceof ModuleReader) return toModuleRecord(output);
|
|
978
958
|
return output;
|
|
979
959
|
}
|
|
980
|
-
*readAsModuleBody(input) {
|
|
981
|
-
const { output, reader } = yield* this.executeBody(input);
|
|
960
|
+
*readAsModuleBody(input, options) {
|
|
961
|
+
const { output, reader } = yield* this.executeBody(input, options);
|
|
982
962
|
return this.toRecord(output, reader);
|
|
983
963
|
}
|
|
984
964
|
/**
|
|
985
965
|
* Shared dispatch + execution of both read bodies: resolve the
|
|
986
966
|
* reader, run it, wrap errors. Normalization is the caller's call.
|
|
987
967
|
*/
|
|
988
|
-
*executeBody(input) {
|
|
968
|
+
*executeBody(input, options) {
|
|
989
969
|
const filePath = buildFilePath(input);
|
|
990
|
-
|
|
970
|
+
let reader;
|
|
971
|
+
if (typeof options.format === "undefined") reader = this.findReader(filePath);
|
|
972
|
+
else reader = this.resolveReader(options.format);
|
|
991
973
|
if (!reader) throw this.unknownExtensionError(filePath);
|
|
992
974
|
try {
|
|
993
975
|
return {
|
|
@@ -998,32 +980,45 @@ var FormatRegistry = class {
|
|
|
998
980
|
throw wrapLoaderError(e, filePath);
|
|
999
981
|
}
|
|
1000
982
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
983
|
+
/**
|
|
984
|
+
* options.format names a registered format id to use instead of
|
|
985
|
+
* extension dispatch — see writeBody for the boundary semantics.
|
|
986
|
+
*/
|
|
987
|
+
async write(input, value, options = {}) {
|
|
988
|
+
return runTwinAsync(this.writeBody(input, value, options));
|
|
1003
989
|
}
|
|
1004
|
-
writeSync(input, value) {
|
|
1005
|
-
runTwinSync(this.writeBody(input, value));
|
|
990
|
+
writeSync(input, value, options = {}) {
|
|
991
|
+
runTwinSync(this.writeBody(input, value, options));
|
|
1006
992
|
}
|
|
1007
993
|
/**
|
|
1008
994
|
* Shared body of write/writeSync: dispatch, unwrap records, write, wrap.
|
|
1009
995
|
* The inverse boundary of readAsModuleBody: a record produced by
|
|
1010
996
|
* readAsModule() (brand detected) is unwrapped to its `.default` value;
|
|
1011
997
|
* anything else is written as-is.
|
|
998
|
+
*
|
|
999
|
+
* An explicit options.format skips extension dispatch entirely —
|
|
1000
|
+
* including the bare-specifier guard: naming the format resolves the
|
|
1001
|
+
* ambiguity the guard exists for, so extensionless paths become
|
|
1002
|
+
* writable.
|
|
1012
1003
|
*/
|
|
1013
|
-
*writeBody(input, value) {
|
|
1004
|
+
*writeBody(input, value, options) {
|
|
1014
1005
|
const filePath = buildFilePath(input);
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
const writer = this.findWriter(filePath);
|
|
1020
|
-
if (!writer) {
|
|
1021
|
-
if (this.findReader(filePath)) throw new LocterWriteError({
|
|
1022
|
-
message: `The format of extension ${pathToLocatorInfo(filePath).extension} is read-only.`,
|
|
1006
|
+
let writer;
|
|
1007
|
+
if (typeof options.format === "undefined") {
|
|
1008
|
+
if (!isFilePath(filePath)) throw new WriteError({
|
|
1009
|
+
message: `Cannot write to a bare module specifier: ${filePath}`,
|
|
1023
1010
|
path: filePath
|
|
1024
1011
|
});
|
|
1025
|
-
|
|
1026
|
-
|
|
1012
|
+
const found = this.findWriter(filePath);
|
|
1013
|
+
if (!found) {
|
|
1014
|
+
if (this.findReader(filePath)) throw new WriteError({
|
|
1015
|
+
message: `The format of extension ${pathToLocatorInfo(filePath).extension} is read-only.`,
|
|
1016
|
+
path: filePath
|
|
1017
|
+
});
|
|
1018
|
+
throw this.unknownExtensionError(filePath);
|
|
1019
|
+
}
|
|
1020
|
+
writer = found;
|
|
1021
|
+
} else writer = this.resolveWriter(options.format, filePath);
|
|
1027
1022
|
const plain = isModuleRecord(value) ? value.default : value;
|
|
1028
1023
|
try {
|
|
1029
1024
|
yield* op(() => writer.write(filePath, plain), () => writer.writeSync(filePath, plain));
|
|
@@ -1072,7 +1067,7 @@ var FormatRegistry = class {
|
|
|
1072
1067
|
* 1. bare specifier (no extension) → module reader, always
|
|
1073
1068
|
* 2. user rules, registration order → first match wins (can override built-ins)
|
|
1074
1069
|
* 3. built-in extension table
|
|
1075
|
-
* 4. undefined → read/readSync throw
|
|
1070
|
+
* 4. undefined → read/readSync throw UnknownExtensionError
|
|
1076
1071
|
*/
|
|
1077
1072
|
findReader(input) {
|
|
1078
1073
|
if (!isFilePath(input)) return this.builtInReader("module");
|
|
@@ -1093,6 +1088,43 @@ var FormatRegistry = class {
|
|
|
1093
1088
|
const id = this.findBuiltInId(input);
|
|
1094
1089
|
if (id && "writer" in BUILT_IN_PRESETS[id]) return this.builtInWriter(id);
|
|
1095
1090
|
}
|
|
1091
|
+
/**
|
|
1092
|
+
* Resolve a reader by EXPLICIT format id (the per-call override) —
|
|
1093
|
+
* a user rule id or a built-in id — bypassing extension dispatch.
|
|
1094
|
+
* Unknown ids and writer-only rules throw.
|
|
1095
|
+
*/
|
|
1096
|
+
resolveReader(id) {
|
|
1097
|
+
const rule = this.rules.find((item) => item.id === id);
|
|
1098
|
+
if (rule) {
|
|
1099
|
+
if (rule.getReader) return rule.getReader();
|
|
1100
|
+
throw new LocterError({ message: `The format ${id} has no reader.` });
|
|
1101
|
+
}
|
|
1102
|
+
if (hasOwnProperty(BUILT_IN_PRESETS, id)) return this.builtInReader(id);
|
|
1103
|
+
throw this.unknownFormatError(id);
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* Write-side counterpart of resolveReader. Reader-only rules and
|
|
1107
|
+
* read-only built-ins (module) throw WriteError, mirroring
|
|
1108
|
+
* what extension dispatch throws for read-only extensions.
|
|
1109
|
+
*/
|
|
1110
|
+
resolveWriter(id, path) {
|
|
1111
|
+
const rule = this.rules.find((item) => item.id === id);
|
|
1112
|
+
if (rule) {
|
|
1113
|
+
if (rule.getWriter) return rule.getWriter();
|
|
1114
|
+
throw new WriteError({
|
|
1115
|
+
message: `The format ${id} is read-only.`,
|
|
1116
|
+
path
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
if (hasOwnProperty(BUILT_IN_PRESETS, id)) {
|
|
1120
|
+
if ("writer" in BUILT_IN_PRESETS[id]) return this.builtInWriter(id);
|
|
1121
|
+
throw new WriteError({
|
|
1122
|
+
message: `The format ${id} is read-only.`,
|
|
1123
|
+
path
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1126
|
+
throw this.unknownFormatError(id);
|
|
1127
|
+
}
|
|
1096
1128
|
findRule(input, filter) {
|
|
1097
1129
|
const info = pathToLocatorInfo(input);
|
|
1098
1130
|
for (const rule of this.rules) {
|
|
@@ -1114,11 +1146,14 @@ var FormatRegistry = class {
|
|
|
1114
1146
|
return this.builtInExtensions.get(info.extension);
|
|
1115
1147
|
}
|
|
1116
1148
|
unknownExtensionError(input) {
|
|
1117
|
-
return new
|
|
1149
|
+
return new UnknownExtensionError({
|
|
1118
1150
|
message: `No format registered for extension: ${pathToLocatorInfo(input).extension ?? "unknown"}`,
|
|
1119
1151
|
path: input
|
|
1120
1152
|
});
|
|
1121
1153
|
}
|
|
1154
|
+
unknownFormatError(id) {
|
|
1155
|
+
return new LocterError({ message: `No format registered with id: ${id}` });
|
|
1156
|
+
}
|
|
1122
1157
|
compile(id, rule) {
|
|
1123
1158
|
return {
|
|
1124
1159
|
id,
|
|
@@ -1161,12 +1196,16 @@ function unregisterFormat(id) {
|
|
|
1161
1196
|
* (json/yaml/conf and custom readers — mutable, round-trip-symmetric
|
|
1162
1197
|
* with write); for modules the normalized module record (a module IS a
|
|
1163
1198
|
* record; normalization only irons out CJS/ESM interop divergence).
|
|
1199
|
+
*
|
|
1200
|
+
* options.format forces a registered format id instead of extension
|
|
1201
|
+
* dispatch — e.g. { format: 'text' } reads a module file's source
|
|
1202
|
+
* WITHOUT evaluating it.
|
|
1164
1203
|
*/
|
|
1165
|
-
async function read(input) {
|
|
1166
|
-
return useFormatRegistry().read(input);
|
|
1204
|
+
async function read(input, options) {
|
|
1205
|
+
return useFormatRegistry().read(input, options);
|
|
1167
1206
|
}
|
|
1168
|
-
function readSync(input) {
|
|
1169
|
-
return useFormatRegistry().readSync(input);
|
|
1207
|
+
function readSync(input, options) {
|
|
1208
|
+
return useFormatRegistry().readSync(input, options);
|
|
1170
1209
|
}
|
|
1171
1210
|
/**
|
|
1172
1211
|
* Read a file/module and present the result as a normalized module
|
|
@@ -1174,17 +1213,22 @@ function readSync(input) {
|
|
|
1174
1213
|
* always holds the loaded value, top-level keys are re-exposed as
|
|
1175
1214
|
* named exports.
|
|
1176
1215
|
*/
|
|
1177
|
-
async function readAsModule(input) {
|
|
1178
|
-
return useFormatRegistry().readAsModule(input);
|
|
1216
|
+
async function readAsModule(input, options) {
|
|
1217
|
+
return useFormatRegistry().readAsModule(input, options);
|
|
1179
1218
|
}
|
|
1180
|
-
function readAsModuleSync(input) {
|
|
1181
|
-
return useFormatRegistry().readAsModuleSync(input);
|
|
1219
|
+
function readAsModuleSync(input, options) {
|
|
1220
|
+
return useFormatRegistry().readAsModuleSync(input, options);
|
|
1182
1221
|
}
|
|
1183
|
-
|
|
1184
|
-
|
|
1222
|
+
/**
|
|
1223
|
+
* options.format forces a registered format id instead of extension
|
|
1224
|
+
* dispatch — this also lifts the bare-specifier guard (extensionless
|
|
1225
|
+
* paths) and the read-only block on module extensions.
|
|
1226
|
+
*/
|
|
1227
|
+
async function write(input, value, options) {
|
|
1228
|
+
return useFormatRegistry().write(input, value, options);
|
|
1185
1229
|
}
|
|
1186
|
-
function writeSync(input, value) {
|
|
1187
|
-
useFormatRegistry().writeSync(input, value);
|
|
1230
|
+
function writeSync(input, value, options) {
|
|
1231
|
+
useFormatRegistry().writeSync(input, value, options);
|
|
1188
1232
|
}
|
|
1189
1233
|
/**
|
|
1190
1234
|
* Override the built-in module reader's `import` / `require` calls.
|
|
@@ -1241,7 +1285,7 @@ function* readPackageFieldBody(field, options) {
|
|
|
1241
1285
|
try {
|
|
1242
1286
|
return extractField(yield* op(() => reader.read(filePath), () => reader.readSync(filePath)), field);
|
|
1243
1287
|
} catch (e) {
|
|
1244
|
-
if (e instanceof
|
|
1288
|
+
if (e instanceof NotFoundError) return;
|
|
1245
1289
|
throw e;
|
|
1246
1290
|
}
|
|
1247
1291
|
}
|
|
@@ -1254,11 +1298,11 @@ function readPackageFieldSync(field, options = {}) {
|
|
|
1254
1298
|
function* writePackageFieldBody(field, value, options) {
|
|
1255
1299
|
if (!isSafeObjectKey(field)) throw new LocterError({ message: `The field ${field} is not a safe object key.` });
|
|
1256
1300
|
const info = yield* locatePackageBody(options);
|
|
1257
|
-
if (!info) throw new
|
|
1301
|
+
if (!info) throw new NotFoundError({ message: "No package.json could be located." });
|
|
1258
1302
|
const reader = useFormatRegistry().builtInReader("json");
|
|
1259
1303
|
const filePath = buildFilePath(info);
|
|
1260
1304
|
const pkg = yield* op(() => reader.read(filePath), () => reader.readSync(filePath));
|
|
1261
|
-
if (!isObject(pkg)) throw new
|
|
1305
|
+
if (!isObject(pkg)) throw new WriteError({
|
|
1262
1306
|
message: "The located package.json does not contain an object.",
|
|
1263
1307
|
path: filePath
|
|
1264
1308
|
});
|
|
@@ -1270,7 +1314,7 @@ function* writePackageFieldBody(field, value, options) {
|
|
|
1270
1314
|
* Set a top-level field of the nearest `package.json` (same locate
|
|
1271
1315
|
* semantics as readPackageField) and write it back, preserving the
|
|
1272
1316
|
* file's existing indentation. Passing `undefined` removes the field.
|
|
1273
|
-
* Throws
|
|
1317
|
+
* Throws NotFoundError when no package.json could be located.
|
|
1274
1318
|
*/
|
|
1275
1319
|
async function writePackageField(field, value, options = {}) {
|
|
1276
1320
|
return runTwinAsync(writePackageFieldBody(field, value, options));
|
|
@@ -1279,6 +1323,6 @@ function writePackageFieldSync(field, value, options = {}) {
|
|
|
1279
1323
|
runTwinSync(writePackageFieldBody(field, value, options));
|
|
1280
1324
|
}
|
|
1281
1325
|
//#endregion
|
|
1282
|
-
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,
|
|
1326
|
+
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 };
|
|
1283
1327
|
|
|
1284
1328
|
//# sourceMappingURL=index.mjs.map
|