@kubb/core 5.0.0-beta.40 → 5.0.0-beta.42
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 +13 -13
- package/dist/{diagnostics-DhfW8YpT.d.ts → diagnostics-DZGgDzSv.d.ts} +183 -33
- package/dist/index.cjs +270 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/index.js +271 -37
- package/dist/index.js.map +1 -1
- package/dist/{memoryStorage-DTv1Kub1.js → memoryStorage-BOnaknb7.js} +170 -23
- package/dist/memoryStorage-BOnaknb7.js.map +1 -0
- package/dist/{memoryStorage-Dkxnid2K.cjs → memoryStorage-Dldu8sRT.cjs} +169 -22
- package/dist/memoryStorage-Dldu8sRT.cjs.map +1 -0
- package/dist/mocks.cjs +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.js +1 -1
- package/package.json +4 -4
- package/src/Fingerprint.ts +98 -0
- package/src/KubbDriver.ts +102 -33
- package/src/Manifest.ts +85 -0
- package/src/Telemetry.ts +13 -1
- package/src/caches/fsCache.ts +103 -0
- package/src/createCache.ts +74 -0
- package/src/createKubb.ts +57 -4
- package/src/defineLogger.ts +10 -28
- package/src/defineParser.ts +1 -1
- package/src/index.ts +2 -0
- package/src/storages/fsStorage.ts +15 -23
- package/src/types.ts +3 -0
- package/dist/memoryStorage-DTv1Kub1.js.map +0 -1
- package/dist/memoryStorage-Dkxnid2K.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_memoryStorage = require("./memoryStorage-
|
|
2
|
+
const require_memoryStorage = require("./memoryStorage-Dldu8sRT.cjs");
|
|
3
3
|
let node_util = require("node:util");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -61,7 +61,26 @@ const randomColors = [
|
|
|
61
61
|
*/
|
|
62
62
|
function randomCliColor(text) {
|
|
63
63
|
if (!text) return "";
|
|
64
|
-
return (0, node_util.styleText)(randomColors[(0, node_crypto.
|
|
64
|
+
return (0, node_util.styleText)(randomColors[(0, node_crypto.hash)("sha256", text, "buffer").readUInt32BE(0) % randomColors.length] ?? "white", text);
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region ../../internals/utils/src/path.ts
|
|
68
|
+
/**
|
|
69
|
+
* Converts a filesystem path to use POSIX (`/`) separators.
|
|
70
|
+
*
|
|
71
|
+
* Most of the codebase compares and composes paths as strings (prefix matching, joining for
|
|
72
|
+
* import specifiers, splitting on `/`). On POSIX `path.resolve` already returns `/`-separated
|
|
73
|
+
* paths, but on Windows it returns `\`-separated paths, which breaks every such comparison.
|
|
74
|
+
*
|
|
75
|
+
* Routing every path that crosses a module boundary through `toPosixPath` keeps the rest of the
|
|
76
|
+
* code platform-agnostic. The conversion runs unconditionally so Windows-specific behavior is
|
|
77
|
+
* exercisable from POSIX CI.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* toPosixPath('C:\\repo\\src\\pet.ts') // 'C:/repo/src/pet.ts'
|
|
81
|
+
*/
|
|
82
|
+
function toPosixPath(filePath) {
|
|
83
|
+
return filePath.replaceAll("\\", "/");
|
|
65
84
|
}
|
|
66
85
|
//#endregion
|
|
67
86
|
//#region ../../internals/utils/src/env.ts
|
|
@@ -81,8 +100,72 @@ function isCIEnvironment() {
|
|
|
81
100
|
return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.BITBUCKET_BUILD_NUMBER || process.env.JENKINS_URL || process.env.CIRCLECI || process.env.TRAVIS || process.env.TEAMCITY_VERSION || process.env.BUILDKITE || process.env.TF_BUILD);
|
|
82
101
|
}
|
|
83
102
|
//#endregion
|
|
103
|
+
//#region ../../internals/utils/src/runtime.ts
|
|
104
|
+
/**
|
|
105
|
+
* Returns `true` when the current process is running under Bun.
|
|
106
|
+
*
|
|
107
|
+
* Detection keys off the global `Bun` object rather than `process.versions`,
|
|
108
|
+
* because Bun polyfills `process.versions.node` for Node compatibility and would
|
|
109
|
+
* otherwise look like Node.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* if (isBun()) {
|
|
114
|
+
* await Bun.write(path, data)
|
|
115
|
+
* }
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
function isBun() {
|
|
119
|
+
return typeof Bun !== "undefined";
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Returns `true` when the current process is running under Deno.
|
|
123
|
+
*/
|
|
124
|
+
function isDeno() {
|
|
125
|
+
return typeof globalThis.Deno !== "undefined";
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Returns the name of the runtime executing the current process.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* getRuntimeName() // 'bun' when run with `bun kubb`, 'node' otherwise
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
function getRuntimeName() {
|
|
136
|
+
if (isBun()) return "bun";
|
|
137
|
+
if (isDeno()) return "deno";
|
|
138
|
+
return "node";
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Returns the version of the active runtime, or an empty string when it cannot be read.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```ts
|
|
145
|
+
* getRuntimeVersion() // '1.3.11' under Bun, '22.22.2' under Node
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
function getRuntimeVersion() {
|
|
149
|
+
if (isBun()) return process.versions.bun ?? "";
|
|
150
|
+
if (isDeno()) return globalThis.Deno?.version?.deno ?? "";
|
|
151
|
+
return process.versions?.node ?? "";
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
84
154
|
//#region ../../internals/utils/src/fs.ts
|
|
85
155
|
/**
|
|
156
|
+
* Reads the file at `path` as a UTF-8 string.
|
|
157
|
+
* Uses `Bun.file().text()` when running under Bun, `fs.readFile` otherwise.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* const source = await read('./src/Pet.ts')
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
async function read(path) {
|
|
165
|
+
if (isBun()) return Bun.file(path).text();
|
|
166
|
+
return (0, node_fs_promises.readFile)(path, { encoding: "utf8" });
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
86
169
|
* Writes `data` to `path`, trimming leading/trailing whitespace before saving.
|
|
87
170
|
* Skips the write when the trimmed content is empty or identical to what is already on disk.
|
|
88
171
|
* Creates any missing parent directories automatically.
|
|
@@ -99,7 +182,7 @@ async function write(path, data, options = {}) {
|
|
|
99
182
|
const trimmed = data.trim();
|
|
100
183
|
if (trimmed === "") return null;
|
|
101
184
|
const resolved = (0, node_path.resolve)(path);
|
|
102
|
-
if (
|
|
185
|
+
if (isBun()) {
|
|
103
186
|
const file = Bun.file(resolved);
|
|
104
187
|
if ((await file.exists() ? await file.text() : null) === trimmed) return null;
|
|
105
188
|
await Bun.write(resolved, trimmed);
|
|
@@ -212,6 +295,35 @@ function createAdapter(build) {
|
|
|
212
295
|
return (options) => build(options ?? {});
|
|
213
296
|
}
|
|
214
297
|
//#endregion
|
|
298
|
+
//#region src/createCache.ts
|
|
299
|
+
/**
|
|
300
|
+
* Defines a custom cache backend. The builder receives user options and returns a
|
|
301
|
+
* {@link Cache}. Reach for this when the filesystem backend doesn't fit, for
|
|
302
|
+
* example to store snapshots in Redis or a database.
|
|
303
|
+
*
|
|
304
|
+
* @example In-memory cache (the built-in implementation)
|
|
305
|
+
* ```ts
|
|
306
|
+
* import { createCache } from '@kubb/core'
|
|
307
|
+
*
|
|
308
|
+
* export const memoryCache = createCache(() => {
|
|
309
|
+
* const store = new Map<string, CachedSnapshot>()
|
|
310
|
+
*
|
|
311
|
+
* return {
|
|
312
|
+
* name: 'memory',
|
|
313
|
+
* async restore({ key }) {
|
|
314
|
+
* return store.get(key) ?? null
|
|
315
|
+
* },
|
|
316
|
+
* async persist({ key, snapshot }) {
|
|
317
|
+
* store.set(key, snapshot)
|
|
318
|
+
* },
|
|
319
|
+
* }
|
|
320
|
+
* })
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
function createCache(build) {
|
|
324
|
+
return (options) => build(options ?? {});
|
|
325
|
+
}
|
|
326
|
+
//#endregion
|
|
215
327
|
//#region src/storages/fsStorage.ts
|
|
216
328
|
/**
|
|
217
329
|
* Built-in filesystem storage driver.
|
|
@@ -263,21 +375,21 @@ const fsStorage = require_memoryStorage.createStorage(() => ({
|
|
|
263
375
|
},
|
|
264
376
|
async getKeys(base) {
|
|
265
377
|
const resolvedBase = (0, node_path.resolve)(base ?? process.cwd());
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
for (const entry of entries) {
|
|
274
|
-
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
275
|
-
if (entry.isDirectory()) yield* walk((0, node_path.join)(dir, entry.name), rel);
|
|
276
|
-
else yield rel;
|
|
277
|
-
}
|
|
378
|
+
if (isBun()) {
|
|
379
|
+
const bunGlob = new Bun.Glob("**/*");
|
|
380
|
+
return Array.fromAsync(bunGlob.scan({
|
|
381
|
+
cwd: resolvedBase,
|
|
382
|
+
onlyFiles: true,
|
|
383
|
+
dot: true
|
|
384
|
+
}));
|
|
278
385
|
}
|
|
279
386
|
const keys = [];
|
|
280
|
-
|
|
387
|
+
try {
|
|
388
|
+
for await (const entry of (0, node_fs_promises.glob)("**/*", {
|
|
389
|
+
cwd: resolvedBase,
|
|
390
|
+
withFileTypes: true
|
|
391
|
+
})) if (entry.isFile()) keys.push(toPosixPath((0, node_path.relative)(resolvedBase, (0, node_path.join)(entry.parentPath, entry.name))));
|
|
392
|
+
} catch (_error) {}
|
|
281
393
|
return keys;
|
|
282
394
|
},
|
|
283
395
|
async clear(base) {
|
|
@@ -336,6 +448,7 @@ function resolveConfig(userConfig) {
|
|
|
336
448
|
...userConfig.output
|
|
337
449
|
},
|
|
338
450
|
storage: userConfig.storage ?? fsStorage(),
|
|
451
|
+
cache: userConfig.cache === false ? void 0 : userConfig.cache,
|
|
339
452
|
reporters: userConfig.reporters ?? [],
|
|
340
453
|
plugins: userConfig.plugins ?? []
|
|
341
454
|
};
|
|
@@ -531,11 +644,10 @@ const logLevel = {
|
|
|
531
644
|
verbose: 4
|
|
532
645
|
};
|
|
533
646
|
/**
|
|
534
|
-
* Defines a typed logger.
|
|
535
|
-
*
|
|
536
|
-
* or cleanup callback to the caller.
|
|
647
|
+
* Defines a typed logger. The `install` method subscribes to lifecycle events
|
|
648
|
+
* on the shared emitter and forwards them to the logger's destination.
|
|
537
649
|
*
|
|
538
|
-
* @example
|
|
650
|
+
* @example
|
|
539
651
|
* ```ts
|
|
540
652
|
* import { defineLogger } from '@kubb/core'
|
|
541
653
|
*
|
|
@@ -547,20 +659,6 @@ const logLevel = {
|
|
|
547
659
|
* },
|
|
548
660
|
* })
|
|
549
661
|
* ```
|
|
550
|
-
*
|
|
551
|
-
* @example Logger that returns a hook sink factory
|
|
552
|
-
* ```ts
|
|
553
|
-
* import { defineLogger, type LoggerOptions } from '@kubb/core'
|
|
554
|
-
* import type { HookSinkFactory } from './sinks'
|
|
555
|
-
*
|
|
556
|
-
* export const myLogger = defineLogger<LoggerOptions, HookSinkFactory>({
|
|
557
|
-
* name: 'my-logger',
|
|
558
|
-
* install(context) {
|
|
559
|
-
* // … register event handlers …
|
|
560
|
-
* return () => ({ onStdout: console.log })
|
|
561
|
-
* },
|
|
562
|
-
* })
|
|
563
|
-
* ```
|
|
564
662
|
*/
|
|
565
663
|
function defineLogger(logger) {
|
|
566
664
|
return logger;
|
|
@@ -781,6 +879,8 @@ var Telemetry = class Telemetry {
|
|
|
781
879
|
command: options.command,
|
|
782
880
|
kubbVersion: options.kubbVersion,
|
|
783
881
|
nodeVersion: node_process.default.versions.node.split(".")[0],
|
|
882
|
+
runtime: getRuntimeName(),
|
|
883
|
+
runtimeVersion: getRuntimeVersion().split(".")[0],
|
|
784
884
|
platform: node_os.default.platform(),
|
|
785
885
|
ci: isCIEnvironment(),
|
|
786
886
|
plugins: options.plugins ?? [],
|
|
@@ -811,6 +911,14 @@ var Telemetry = class Telemetry {
|
|
|
811
911
|
key: "kubb.node_version",
|
|
812
912
|
value: { stringValue: event.nodeVersion }
|
|
813
913
|
},
|
|
914
|
+
{
|
|
915
|
+
key: "kubb.runtime",
|
|
916
|
+
value: { stringValue: event.runtime }
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
key: "kubb.runtime_version",
|
|
920
|
+
value: { stringValue: event.runtimeVersion }
|
|
921
|
+
},
|
|
814
922
|
{
|
|
815
923
|
key: "kubb.platform",
|
|
816
924
|
value: { stringValue: event.platform }
|
|
@@ -1042,6 +1150,132 @@ function defineParser(parser) {
|
|
|
1042
1150
|
return parser;
|
|
1043
1151
|
}
|
|
1044
1152
|
//#endregion
|
|
1153
|
+
//#region src/Manifest.ts
|
|
1154
|
+
/**
|
|
1155
|
+
* Reads and prunes the local cache manifest. All methods are static, so call them as
|
|
1156
|
+
* `Manifest.read(dir)` and `Manifest.prune(data, ...)`. A damaged manifest reads as empty so the
|
|
1157
|
+
* cache degrades to misses instead of throwing. Writing goes through `write` from `@internals/utils`.
|
|
1158
|
+
*/
|
|
1159
|
+
var Manifest = class Manifest {
|
|
1160
|
+
/**
|
|
1161
|
+
* On-disk layout version for the manifest itself. Bumped when the manifest shape changes; a
|
|
1162
|
+
* mismatch makes the whole local cache read as empty.
|
|
1163
|
+
*/
|
|
1164
|
+
static version = 1;
|
|
1165
|
+
/**
|
|
1166
|
+
* Reads the manifest at `dir/manifest.json`. A missing, corrupt, or version-mismatched file reads
|
|
1167
|
+
* as an empty manifest.
|
|
1168
|
+
*/
|
|
1169
|
+
static async read(dir) {
|
|
1170
|
+
try {
|
|
1171
|
+
const parsed = JSON.parse(await read((0, node_path.join)(dir, "manifest.json")));
|
|
1172
|
+
if (parsed.version !== Manifest.version || typeof parsed.entries !== "object") return Manifest.#empty();
|
|
1173
|
+
return parsed;
|
|
1174
|
+
} catch {
|
|
1175
|
+
return Manifest.#empty();
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Selects the keys to evict so the cache stays within `ttlDays` and `maxEntries`. Returns the
|
|
1180
|
+
* surviving manifest plus the evicted keys (the caller deletes their blobs). Pure, does no IO.
|
|
1181
|
+
*/
|
|
1182
|
+
static prune(manifest, { maxEntries, ttlDays, now }) {
|
|
1183
|
+
const ttlMs = ttlDays * 24 * 60 * 60 * 1e3;
|
|
1184
|
+
const removed = [];
|
|
1185
|
+
const kept = [];
|
|
1186
|
+
for (const [key, entry] of Object.entries(manifest.entries)) if (now - entry.lastAccess > ttlMs) removed.push(key);
|
|
1187
|
+
else kept.push([key, entry]);
|
|
1188
|
+
if (kept.length > maxEntries) {
|
|
1189
|
+
kept.sort((a, b) => b[1].lastAccess - a[1].lastAccess);
|
|
1190
|
+
for (const [key] of kept.splice(maxEntries)) removed.push(key);
|
|
1191
|
+
}
|
|
1192
|
+
return {
|
|
1193
|
+
manifest: {
|
|
1194
|
+
version: Manifest.version,
|
|
1195
|
+
entries: Object.fromEntries(kept)
|
|
1196
|
+
},
|
|
1197
|
+
removed
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
static #empty() {
|
|
1201
|
+
return {
|
|
1202
|
+
version: Manifest.version,
|
|
1203
|
+
entries: {}
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
};
|
|
1207
|
+
//#endregion
|
|
1208
|
+
//#region src/caches/fsCache.ts
|
|
1209
|
+
function blobName(relativePath) {
|
|
1210
|
+
return `${(0, node_crypto.createHash)("sha256").update(relativePath).digest("hex")}.blob`;
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Local filesystem cache. Stores each build snapshot as content blobs plus an index,
|
|
1214
|
+
* tracked by a manifest under `node_modules/.cache/kubb/` (the Nx and Vitest
|
|
1215
|
+
* convention). Least-recently-used and expired entries are pruned on every persist.
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```ts
|
|
1219
|
+
* import { fsCache } from '@kubb/core'
|
|
1220
|
+
*
|
|
1221
|
+
* export default defineConfig({
|
|
1222
|
+
* cache: fsCache(),
|
|
1223
|
+
* })
|
|
1224
|
+
* ```
|
|
1225
|
+
*/
|
|
1226
|
+
const fsCache = createCache((options = {}) => {
|
|
1227
|
+
const dir = (0, node_path.resolve)(options.dir ?? (0, node_path.join)("node_modules", ".cache", "kubb"));
|
|
1228
|
+
const maxEntries = options.maxEntries ?? 50;
|
|
1229
|
+
const ttlDays = options.ttlDays ?? 7;
|
|
1230
|
+
const blobsDir = (0, node_path.join)(dir, "blobs");
|
|
1231
|
+
const manifestPath = (0, node_path.join)(dir, "manifest.json");
|
|
1232
|
+
return {
|
|
1233
|
+
name: "fs",
|
|
1234
|
+
async restore({ key }) {
|
|
1235
|
+
const manifest = await Manifest.read(dir);
|
|
1236
|
+
const entry = manifest.entries[key];
|
|
1237
|
+
if (!entry) return null;
|
|
1238
|
+
try {
|
|
1239
|
+
const index = JSON.parse(await read((0, node_path.join)(blobsDir, key, "index.json")));
|
|
1240
|
+
const files = {};
|
|
1241
|
+
for (const { path, blob } of index) files[path] = await read((0, node_path.join)(blobsDir, key, blob));
|
|
1242
|
+
entry.lastAccess = Date.now();
|
|
1243
|
+
await write(manifestPath, JSON.stringify(manifest)).catch(() => {});
|
|
1244
|
+
return { files };
|
|
1245
|
+
} catch {
|
|
1246
|
+
return null;
|
|
1247
|
+
}
|
|
1248
|
+
},
|
|
1249
|
+
async persist({ key, snapshot }) {
|
|
1250
|
+
const entryDir = (0, node_path.join)(blobsDir, key);
|
|
1251
|
+
const index = [];
|
|
1252
|
+
for (const [path, source] of Object.entries(snapshot.files)) {
|
|
1253
|
+
const blob = blobName(path);
|
|
1254
|
+
await write((0, node_path.join)(entryDir, blob), source);
|
|
1255
|
+
index.push({
|
|
1256
|
+
path,
|
|
1257
|
+
blob
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
await write((0, node_path.join)(entryDir, "index.json"), JSON.stringify(index));
|
|
1261
|
+
const manifest = await Manifest.read(dir);
|
|
1262
|
+
const now = Date.now();
|
|
1263
|
+
manifest.entries[key] = {
|
|
1264
|
+
files: index.map((item) => item.path),
|
|
1265
|
+
createdAt: now,
|
|
1266
|
+
lastAccess: now
|
|
1267
|
+
};
|
|
1268
|
+
const pruned = Manifest.prune(manifest, {
|
|
1269
|
+
maxEntries,
|
|
1270
|
+
ttlDays,
|
|
1271
|
+
now
|
|
1272
|
+
});
|
|
1273
|
+
await Promise.all(pruned.removed.map((removedKey) => clean((0, node_path.join)(blobsDir, removedKey))));
|
|
1274
|
+
await write(manifestPath, JSON.stringify(pruned.manifest));
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
1277
|
+
});
|
|
1278
|
+
//#endregion
|
|
1045
1279
|
exports.AsyncEventEmitter = require_memoryStorage.AsyncEventEmitter;
|
|
1046
1280
|
exports.Diagnostics = require_memoryStorage.Diagnostics;
|
|
1047
1281
|
exports.KubbDriver = require_memoryStorage.KubbDriver;
|
|
@@ -1055,6 +1289,7 @@ Object.defineProperty(exports, "ast", {
|
|
|
1055
1289
|
});
|
|
1056
1290
|
exports.cliReporter = cliReporter;
|
|
1057
1291
|
exports.createAdapter = createAdapter;
|
|
1292
|
+
exports.createCache = createCache;
|
|
1058
1293
|
exports.createKubb = createKubb;
|
|
1059
1294
|
exports.createRenderer = createRenderer;
|
|
1060
1295
|
exports.createReporter = createReporter;
|
|
@@ -1066,6 +1301,7 @@ exports.defineParser = defineParser;
|
|
|
1066
1301
|
exports.definePlugin = require_memoryStorage.definePlugin;
|
|
1067
1302
|
exports.defineResolver = require_memoryStorage.defineResolver;
|
|
1068
1303
|
exports.fileReporter = fileReporter;
|
|
1304
|
+
exports.fsCache = fsCache;
|
|
1069
1305
|
exports.fsStorage = fsStorage;
|
|
1070
1306
|
exports.jsonReporter = jsonReporter;
|
|
1071
1307
|
exports.logLevel = logLevel;
|