@cleaver/breakcheck-core 0.2.4 → 0.3.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 +134 -1
- package/dist/api/index.d.ts +23 -5
- package/dist/api/index.js +71 -10
- package/dist/api/index.js.map +1 -1
- package/dist/core/check/index.d.ts +9 -0
- package/dist/core/check/index.js +116 -0
- package/dist/core/check/index.js.map +1 -0
- package/dist/core/compare/classes/ComparisonRepository.d.ts +11 -0
- package/dist/core/compare/classes/ComparisonRepository.js +26 -4
- package/dist/core/compare/classes/ComparisonRepository.js.map +1 -1
- package/dist/core/compare/index.js +22 -6
- package/dist/core/compare/index.js.map +1 -1
- package/dist/core/crawler/implementations/cheerio.d.ts +1 -1
- package/dist/core/crawler/implementations/cheerio.js +2 -2
- package/dist/core/crawler/implementations/cheerio.js.map +1 -1
- package/dist/core/crawler/implementations/playwright.d.ts +1 -1
- package/dist/core/crawler/implementations/playwright.js +2 -2
- package/dist/core/crawler/implementations/playwright.js.map +1 -1
- package/dist/core/crawler/index.d.ts +13 -2
- package/dist/core/crawler/index.js +25 -6
- package/dist/core/crawler/index.js.map +1 -1
- package/dist/core/crawler/url-paths.d.ts +18 -0
- package/dist/core/crawler/url-paths.js +113 -0
- package/dist/core/crawler/url-paths.js.map +1 -0
- package/dist/core/rules/RulesDsl.js +273 -56
- package/dist/core/rules/RulesDsl.js.map +1 -1
- package/dist/core/rules/RulesEngine.js +56 -17
- package/dist/core/rules/RulesEngine.js.map +1 -1
- package/dist/core/snapshot/classes/SnapshotRepository.d.ts +15 -2
- package/dist/core/snapshot/classes/SnapshotRepository.js +110 -9
- package/dist/core/snapshot/classes/SnapshotRepository.js.map +1 -1
- package/dist/core/snapshot/index.d.ts +3 -2
- package/dist/core/snapshot/index.js +41 -3
- package/dist/core/snapshot/index.js.map +1 -1
- package/dist/core/snapshot/route-coverage.d.ts +3 -0
- package/dist/core/snapshot/route-coverage.js +18 -0
- package/dist/core/snapshot/route-coverage.js.map +1 -0
- package/dist/core/snapshot/update-routes.d.ts +4 -0
- package/dist/core/snapshot/update-routes.js +58 -0
- package/dist/core/snapshot/update-routes.js.map +1 -0
- package/dist/core/view/index.d.ts +2 -1
- package/dist/core/view/index.js +4 -4
- package/dist/core/view/index.js.map +1 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +18 -0
- package/dist/lib/config.js +363 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crawlee-logger.d.ts +2 -0
- package/dist/lib/crawlee-logger.js +43 -0
- package/dist/lib/crawlee-logger.js.map +1 -0
- package/dist/lib/logger.d.ts +8 -3
- package/dist/lib/logger.js +11 -1
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/root.d.ts +1 -1
- package/dist/lib/root.js +17 -6
- package/dist/lib/root.js.map +1 -1
- package/dist/lib/storage.d.ts +12 -0
- package/dist/lib/storage.js +76 -0
- package/dist/lib/storage.js.map +1 -0
- package/dist/types/api.d.ts +47 -0
- package/dist/types/compare.d.ts +5 -2
- package/dist/types/config.d.ts +72 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/rules.d.ts +8 -3
- package/dist/types/rules.js.map +1 -1
- package/package.json +11 -10
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LoadedProjectConfig, ProjectConfig, ProjectConfigLoadOptions, ResolvedProjectConfig } from "../types/config.js";
|
|
2
|
+
export declare const PROJECT_CONFIG_FILENAME = "breakcheck.config.json";
|
|
3
|
+
export declare const PROJECT_CONFIG_VERSION: 1;
|
|
4
|
+
/** Validates and normalizes an in-memory project configuration. */
|
|
5
|
+
export declare function validateProjectConfig(value: unknown, sourcePath?: string): ProjectConfig;
|
|
6
|
+
/** Finds the nearest project configuration at or above `cwd`. */
|
|
7
|
+
export declare function findProjectConfig(cwd?: string): Promise<string | undefined>;
|
|
8
|
+
/** Loads exactly one selected or discovered project configuration. */
|
|
9
|
+
export declare function loadProjectConfig(options?: ProjectConfigLoadOptions): Promise<LoadedProjectConfig | undefined>;
|
|
10
|
+
/**
|
|
11
|
+
* Loads configuration and resolves all configured filesystem paths. When no
|
|
12
|
+
* storage directory is configured, the legacy project-root behavior remains.
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveProjectConfig(options?: ProjectConfigLoadOptions): Promise<ResolvedProjectConfig>;
|
|
15
|
+
/** Serializes a validated project configuration with stable formatting. */
|
|
16
|
+
export declare function serializeProjectConfig(config: ProjectConfig): string;
|
|
17
|
+
/** Creates a project configuration without overwriting an existing path. */
|
|
18
|
+
export declare function writeProjectConfig(configPath: string, config: ProjectConfig): Promise<void>;
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { access, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findRootDir } from "./root.js";
|
|
4
|
+
export const PROJECT_CONFIG_FILENAME = "breakcheck.config.json";
|
|
5
|
+
export const PROJECT_CONFIG_VERSION = 1;
|
|
6
|
+
function isRecord(value) {
|
|
7
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
function sourceLabel(sourcePath) {
|
|
10
|
+
return sourcePath ? ` in ${sourcePath}` : "";
|
|
11
|
+
}
|
|
12
|
+
function invalidConfig(message, sourcePath, cause) {
|
|
13
|
+
return new Error(`Invalid Breakcheck configuration${sourceLabel(sourcePath)}: ${message}`, {
|
|
14
|
+
cause,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function assertKnownKeys(value, allowed, context, sourcePath) {
|
|
18
|
+
const unknown = Object.keys(value).filter((key) => !allowed.includes(key));
|
|
19
|
+
if (unknown.length > 0) {
|
|
20
|
+
throw invalidConfig(`${context} contains unsupported field(s): ${unknown.join(", ")}.`, sourcePath);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function requiredString(value, field, sourcePath) {
|
|
24
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
25
|
+
throw invalidConfig(`${field} must be a non-empty string.`, sourcePath);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function optionalString(value, field, sourcePath) {
|
|
30
|
+
if (value === undefined)
|
|
31
|
+
return undefined;
|
|
32
|
+
return requiredString(value, field, sourcePath);
|
|
33
|
+
}
|
|
34
|
+
function validateBaseUrl(value, sourcePath) {
|
|
35
|
+
const baseUrl = requiredString(value, "baseUrl", sourcePath);
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = new URL(baseUrl);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
throw invalidConfig(`baseUrl must be a valid HTTP(S) URL.`, sourcePath, error);
|
|
42
|
+
}
|
|
43
|
+
if ((parsed.protocol !== "http:" && parsed.protocol !== "https:") ||
|
|
44
|
+
!parsed.hostname) {
|
|
45
|
+
throw invalidConfig(`baseUrl must be a valid HTTP(S) URL.`, sourcePath);
|
|
46
|
+
}
|
|
47
|
+
return baseUrl;
|
|
48
|
+
}
|
|
49
|
+
function validateInteger(value, field, minimum, sourcePath) {
|
|
50
|
+
if (typeof value !== "number" ||
|
|
51
|
+
!Number.isInteger(value) ||
|
|
52
|
+
value < minimum) {
|
|
53
|
+
throw invalidConfig(`${field} must be an integer greater than or equal to ${minimum}.`, sourcePath);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function validateStringArray(value, field, sourcePath) {
|
|
58
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
59
|
+
throw invalidConfig(`${field} must be an array of strings.`, sourcePath);
|
|
60
|
+
}
|
|
61
|
+
return [...value];
|
|
62
|
+
}
|
|
63
|
+
function validateCommand(value, field, sourcePath) {
|
|
64
|
+
if (!Array.isArray(value) ||
|
|
65
|
+
value.length === 0 ||
|
|
66
|
+
value.some((argument) => typeof argument !== "string") ||
|
|
67
|
+
typeof value[0] !== "string" ||
|
|
68
|
+
value[0].trim().length === 0) {
|
|
69
|
+
throw invalidConfig(`${field} must be a non-empty array of strings.`, sourcePath);
|
|
70
|
+
}
|
|
71
|
+
const command = [];
|
|
72
|
+
for (const argument of value) {
|
|
73
|
+
if (typeof argument !== "string") {
|
|
74
|
+
throw invalidConfig(`${field} must be a non-empty array of strings.`, sourcePath);
|
|
75
|
+
}
|
|
76
|
+
command.push(argument);
|
|
77
|
+
}
|
|
78
|
+
return command;
|
|
79
|
+
}
|
|
80
|
+
function validateCommandList(value, field, sourcePath) {
|
|
81
|
+
if (!Array.isArray(value)) {
|
|
82
|
+
throw invalidConfig(`${field} must be an array of command arrays.`, sourcePath);
|
|
83
|
+
}
|
|
84
|
+
return value.map((command, index) => validateCommand(command, `${field}[${index}]`, sourcePath));
|
|
85
|
+
}
|
|
86
|
+
function validateEnvironment(value, sourcePath) {
|
|
87
|
+
if (!isRecord(value)) {
|
|
88
|
+
throw invalidConfig("check.server.env must be an object of strings.", sourcePath);
|
|
89
|
+
}
|
|
90
|
+
const environment = {};
|
|
91
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
92
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || typeof entry !== "string") {
|
|
93
|
+
throw invalidConfig("check.server.env keys must be environment variable names and values must be strings.", sourcePath);
|
|
94
|
+
}
|
|
95
|
+
environment[key] = entry;
|
|
96
|
+
}
|
|
97
|
+
return environment;
|
|
98
|
+
}
|
|
99
|
+
function validateCheckServerConfig(value, sourcePath) {
|
|
100
|
+
if (!isRecord(value)) {
|
|
101
|
+
throw invalidConfig("check.server must be an object.", sourcePath);
|
|
102
|
+
}
|
|
103
|
+
assertKnownKeys(value, ["start", "stop", "cwd", "env", "readyPath", "timeoutMs"], "check.server", sourcePath);
|
|
104
|
+
const readyPath = optionalString(value.readyPath, "check.server.readyPath", sourcePath);
|
|
105
|
+
if (readyPath !== undefined &&
|
|
106
|
+
(!readyPath.startsWith("/") || readyPath.startsWith("//"))) {
|
|
107
|
+
throw invalidConfig("check.server.readyPath must be a root-relative path beginning with one slash.", sourcePath);
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
start: validateCommand(value.start, "check.server.start", sourcePath),
|
|
111
|
+
...(value.stop === undefined
|
|
112
|
+
? {}
|
|
113
|
+
: { stop: validateCommand(value.stop, "check.server.stop", sourcePath) }),
|
|
114
|
+
...(value.cwd === undefined
|
|
115
|
+
? {}
|
|
116
|
+
: { cwd: requiredString(value.cwd, "check.server.cwd", sourcePath) }),
|
|
117
|
+
...(value.env === undefined
|
|
118
|
+
? {}
|
|
119
|
+
: { env: validateEnvironment(value.env, sourcePath) }),
|
|
120
|
+
...(readyPath === undefined ? {} : { readyPath }),
|
|
121
|
+
...(value.timeoutMs === undefined
|
|
122
|
+
? {}
|
|
123
|
+
: {
|
|
124
|
+
timeoutMs: validateInteger(value.timeoutMs, "check.server.timeoutMs", 1, sourcePath),
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function validateCheckConfig(value, sourcePath) {
|
|
129
|
+
if (value === undefined)
|
|
130
|
+
return undefined;
|
|
131
|
+
if (!isRecord(value)) {
|
|
132
|
+
throw invalidConfig("check must be an object.", sourcePath);
|
|
133
|
+
}
|
|
134
|
+
assertKnownKeys(value, ["routesFile", "baselineSnapshot", "prepare", "server", "reportDir"], "check", sourcePath);
|
|
135
|
+
const prepare = value.prepare === undefined
|
|
136
|
+
? undefined
|
|
137
|
+
: validateCommandList(value.prepare, "check.prepare", sourcePath);
|
|
138
|
+
const server = value.server === undefined
|
|
139
|
+
? undefined
|
|
140
|
+
: validateCheckServerConfig(value.server, sourcePath);
|
|
141
|
+
const reportDir = optionalString(value.reportDir, "check.reportDir", sourcePath);
|
|
142
|
+
return {
|
|
143
|
+
routesFile: requiredString(value.routesFile, "check.routesFile", sourcePath),
|
|
144
|
+
baselineSnapshot: requiredString(value.baselineSnapshot, "check.baselineSnapshot", sourcePath),
|
|
145
|
+
...(prepare === undefined ? {} : { prepare }),
|
|
146
|
+
...(server === undefined ? {} : { server }),
|
|
147
|
+
...(reportDir === undefined ? {} : { reportDir }),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function validateCrawlConfig(value, sourcePath) {
|
|
151
|
+
if (value === undefined)
|
|
152
|
+
return undefined;
|
|
153
|
+
if (!isRecord(value)) {
|
|
154
|
+
throw invalidConfig("crawl must be an object.", sourcePath);
|
|
155
|
+
}
|
|
156
|
+
assertKnownKeys(value, [
|
|
157
|
+
"crawlerType",
|
|
158
|
+
"maxDepth",
|
|
159
|
+
"maxConcurrency",
|
|
160
|
+
"includePatterns",
|
|
161
|
+
"excludePatterns",
|
|
162
|
+
], "crawl", sourcePath);
|
|
163
|
+
const crawlerType = value.crawlerType;
|
|
164
|
+
if (crawlerType !== undefined &&
|
|
165
|
+
crawlerType !== "cheerio" &&
|
|
166
|
+
crawlerType !== "playwright") {
|
|
167
|
+
throw invalidConfig(`crawl.crawlerType must be either "cheerio" or "playwright".`, sourcePath);
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
...(crawlerType === undefined ? {} : { crawlerType }),
|
|
171
|
+
...(value.maxDepth === undefined
|
|
172
|
+
? {}
|
|
173
|
+
: {
|
|
174
|
+
maxDepth: validateInteger(value.maxDepth, "crawl.maxDepth", 0, sourcePath),
|
|
175
|
+
}),
|
|
176
|
+
...(value.maxConcurrency === undefined
|
|
177
|
+
? {}
|
|
178
|
+
: {
|
|
179
|
+
maxConcurrency: validateInteger(value.maxConcurrency, "crawl.maxConcurrency", 1, sourcePath),
|
|
180
|
+
}),
|
|
181
|
+
...(value.includePatterns === undefined
|
|
182
|
+
? {}
|
|
183
|
+
: {
|
|
184
|
+
includePatterns: validateStringArray(value.includePatterns, "crawl.includePatterns", sourcePath),
|
|
185
|
+
}),
|
|
186
|
+
...(value.excludePatterns === undefined
|
|
187
|
+
? {}
|
|
188
|
+
: {
|
|
189
|
+
excludePatterns: validateStringArray(value.excludePatterns, "crawl.excludePatterns", sourcePath),
|
|
190
|
+
}),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function validateComparisonConfig(value, sourcePath) {
|
|
194
|
+
if (value === undefined)
|
|
195
|
+
return undefined;
|
|
196
|
+
if (!isRecord(value)) {
|
|
197
|
+
throw invalidConfig("comparison must be an object.", sourcePath);
|
|
198
|
+
}
|
|
199
|
+
assertKnownKeys(value, ["rulesDir"], "comparison", sourcePath);
|
|
200
|
+
const rulesDir = optionalString(value.rulesDir, "comparison.rulesDir", sourcePath);
|
|
201
|
+
return rulesDir === undefined ? {} : { rulesDir };
|
|
202
|
+
}
|
|
203
|
+
/** Validates and normalizes an in-memory project configuration. */
|
|
204
|
+
export function validateProjectConfig(value, sourcePath) {
|
|
205
|
+
if (!isRecord(value)) {
|
|
206
|
+
throw invalidConfig("the root value must be an object.", sourcePath);
|
|
207
|
+
}
|
|
208
|
+
if (value.version !== 1 && value.version !== 2) {
|
|
209
|
+
throw invalidConfig("version must be 1 or 2.", sourcePath);
|
|
210
|
+
}
|
|
211
|
+
assertKnownKeys(value, value.version === 1
|
|
212
|
+
? ["version", "baseUrl", "storageDir", "crawl", "comparison"]
|
|
213
|
+
: ["version", "baseUrl", "storageDir", "crawl", "comparison", "check"], "the root object", sourcePath);
|
|
214
|
+
const config = { version: value.version };
|
|
215
|
+
if (value.baseUrl !== undefined) {
|
|
216
|
+
config.baseUrl = validateBaseUrl(value.baseUrl, sourcePath);
|
|
217
|
+
}
|
|
218
|
+
if (value.storageDir !== undefined) {
|
|
219
|
+
config.storageDir = requiredString(value.storageDir, "storageDir", sourcePath);
|
|
220
|
+
}
|
|
221
|
+
const crawl = validateCrawlConfig(value.crawl, sourcePath);
|
|
222
|
+
if (crawl !== undefined)
|
|
223
|
+
config.crawl = crawl;
|
|
224
|
+
const comparison = validateComparisonConfig(value.comparison, sourcePath);
|
|
225
|
+
if (comparison !== undefined)
|
|
226
|
+
config.comparison = comparison;
|
|
227
|
+
const check = validateCheckConfig(value.check, sourcePath);
|
|
228
|
+
if (check !== undefined) {
|
|
229
|
+
if (value.version !== 2) {
|
|
230
|
+
throw invalidConfig("check settings require configuration version 2.", sourcePath);
|
|
231
|
+
}
|
|
232
|
+
config.check = check;
|
|
233
|
+
}
|
|
234
|
+
return config;
|
|
235
|
+
}
|
|
236
|
+
async function pathExists(filePath) {
|
|
237
|
+
try {
|
|
238
|
+
await access(filePath);
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** Finds the nearest project configuration at or above `cwd`. */
|
|
249
|
+
export async function findProjectConfig(cwd = process.cwd()) {
|
|
250
|
+
let directory = path.resolve(cwd);
|
|
251
|
+
while (true) {
|
|
252
|
+
const candidate = path.join(directory, PROJECT_CONFIG_FILENAME);
|
|
253
|
+
if (await pathExists(candidate))
|
|
254
|
+
return candidate;
|
|
255
|
+
const parent = path.dirname(directory);
|
|
256
|
+
if (parent === directory)
|
|
257
|
+
return undefined;
|
|
258
|
+
directory = parent;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** Loads exactly one selected or discovered project configuration. */
|
|
262
|
+
export async function loadProjectConfig(options = {}) {
|
|
263
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
264
|
+
if (options.configPath !== undefined && options.noConfig) {
|
|
265
|
+
throw new Error("--config and --no-config cannot be used together.");
|
|
266
|
+
}
|
|
267
|
+
if (options.noConfig)
|
|
268
|
+
return undefined;
|
|
269
|
+
if (options.configPath !== undefined &&
|
|
270
|
+
options.configPath.trim().length === 0) {
|
|
271
|
+
throw new Error("--config requires a file path.");
|
|
272
|
+
}
|
|
273
|
+
const configPath = options.configPath !== undefined
|
|
274
|
+
? path.resolve(cwd, options.configPath)
|
|
275
|
+
: await findProjectConfig(cwd);
|
|
276
|
+
if (configPath === undefined)
|
|
277
|
+
return undefined;
|
|
278
|
+
let content;
|
|
279
|
+
try {
|
|
280
|
+
content = await readFile(configPath, "utf8");
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
throw new Error(`Unable to read Breakcheck configuration ${configPath}.`, {
|
|
284
|
+
cause: error,
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
let parsed;
|
|
288
|
+
try {
|
|
289
|
+
parsed = JSON.parse(content);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
throw invalidConfig("file is not valid JSON.", configPath, error);
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
configPath,
|
|
296
|
+
config: validateProjectConfig(parsed, configPath),
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Loads configuration and resolves all configured filesystem paths. When no
|
|
301
|
+
* storage directory is configured, the legacy project-root behavior remains.
|
|
302
|
+
*/
|
|
303
|
+
export async function resolveProjectConfig(options = {}) {
|
|
304
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
305
|
+
const loaded = await loadProjectConfig({ ...options, cwd });
|
|
306
|
+
const config = loaded?.config;
|
|
307
|
+
const configDirectory = loaded ? path.dirname(loaded.configPath) : cwd;
|
|
308
|
+
const storageDir = config?.storageDir === undefined
|
|
309
|
+
? await findRootDir(cwd)
|
|
310
|
+
: path.resolve(configDirectory, config.storageDir);
|
|
311
|
+
let check;
|
|
312
|
+
if (config?.check) {
|
|
313
|
+
const server = config.check.server;
|
|
314
|
+
check = {
|
|
315
|
+
configDirectory,
|
|
316
|
+
routesFile: path.resolve(configDirectory, config.check.routesFile),
|
|
317
|
+
baselineSnapshot: config.check.baselineSnapshot,
|
|
318
|
+
prepare: config.check.prepare,
|
|
319
|
+
reportDir: path.resolve(configDirectory, config.check.reportDir ?? path.join(storageDir, "reports")),
|
|
320
|
+
...(server === undefined
|
|
321
|
+
? {}
|
|
322
|
+
: {
|
|
323
|
+
server: {
|
|
324
|
+
start: server.start,
|
|
325
|
+
...(server.stop === undefined ? {} : { stop: server.stop }),
|
|
326
|
+
...(server.env === undefined ? {} : { env: server.env }),
|
|
327
|
+
...(server.readyPath === undefined
|
|
328
|
+
? {}
|
|
329
|
+
: { readyPath: server.readyPath }),
|
|
330
|
+
...(server.timeoutMs === undefined
|
|
331
|
+
? {}
|
|
332
|
+
: { timeoutMs: server.timeoutMs }),
|
|
333
|
+
cwd: path.resolve(configDirectory, server.cwd ?? "."),
|
|
334
|
+
},
|
|
335
|
+
}),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
...(loaded ? { configPath: loaded.configPath } : {}),
|
|
340
|
+
storageDir: path.resolve(storageDir),
|
|
341
|
+
...(config?.baseUrl === undefined ? {} : { baseUrl: config.baseUrl }),
|
|
342
|
+
crawl: { ...(config?.crawl ?? {}) },
|
|
343
|
+
...(config?.comparison?.rulesDir === undefined
|
|
344
|
+
? {}
|
|
345
|
+
: {
|
|
346
|
+
rulesDir: path.resolve(configDirectory, config.comparison.rulesDir),
|
|
347
|
+
}),
|
|
348
|
+
...(check === undefined ? {} : { check }),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
/** Serializes a validated project configuration with stable formatting. */
|
|
352
|
+
export function serializeProjectConfig(config) {
|
|
353
|
+
return `${JSON.stringify(validateProjectConfig(config), null, 2)}\n`;
|
|
354
|
+
}
|
|
355
|
+
/** Creates a project configuration without overwriting an existing path. */
|
|
356
|
+
export async function writeProjectConfig(configPath, config) {
|
|
357
|
+
const absolutePath = path.resolve(configPath);
|
|
358
|
+
await writeFile(absolutePath, serializeProjectConfig(config), {
|
|
359
|
+
encoding: "utf8",
|
|
360
|
+
flag: "wx",
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Logger as CrawleeLogger, log as crawleeLog, LogLevel } from "crawlee";
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
class PinoCrawleeLogger extends CrawleeLogger {
|
|
6
|
+
pinoLogger;
|
|
7
|
+
constructor(pinoLogger) {
|
|
8
|
+
super({});
|
|
9
|
+
this.pinoLogger = pinoLogger;
|
|
10
|
+
}
|
|
11
|
+
_log(level, message, data, exception, opts = {}) {
|
|
12
|
+
const component = typeof opts.prefix === "string" ? opts.prefix : undefined;
|
|
13
|
+
const prefix = component ? `${component}: ` : "";
|
|
14
|
+
const suffix = typeof opts.suffix === "string" ? ` ${opts.suffix}` : "";
|
|
15
|
+
const fields = {
|
|
16
|
+
...(isRecord(data) ? data : {}),
|
|
17
|
+
...(component ? { component } : {}),
|
|
18
|
+
...(exception !== undefined ? { err: exception } : {}),
|
|
19
|
+
};
|
|
20
|
+
const logMessage = `${prefix}${message}${suffix}`;
|
|
21
|
+
switch (level) {
|
|
22
|
+
case LogLevel.ERROR:
|
|
23
|
+
this.pinoLogger.error(fields, logMessage);
|
|
24
|
+
break;
|
|
25
|
+
case LogLevel.SOFT_FAIL:
|
|
26
|
+
case LogLevel.WARNING:
|
|
27
|
+
this.pinoLogger.warn(fields, logMessage);
|
|
28
|
+
break;
|
|
29
|
+
case LogLevel.DEBUG:
|
|
30
|
+
case LogLevel.PERF:
|
|
31
|
+
this.pinoLogger.debug(fields, logMessage);
|
|
32
|
+
break;
|
|
33
|
+
case LogLevel.INFO:
|
|
34
|
+
default:
|
|
35
|
+
this.pinoLogger.info(fields, logMessage);
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function configureCrawleeLogger(pinoLogger) {
|
|
41
|
+
crawleeLog.setOptions({ logger: new PinoCrawleeLogger(pinoLogger) });
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=crawlee-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crawlee-logger.js","sourceRoot":"","sources":["../../src/lib/crawlee-logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,GAAG,IAAI,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG/E,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,iBAAkB,SAAQ,aAAa;IACd,UAAU;IAAvC,YAA6B,UAAsB;QACjD,KAAK,CAAC,EAAE,CAAC,CAAC;0BADiB,UAAU;IAEvC,CAAC;IAEQ,IAAI,CACX,KAAe,EACf,OAAe,EACf,IAAc,EACd,SAAmB,EACnB,IAAI,GAA4B,EAAE;QAElC,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5E,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG;YACb,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC;QACF,MAAM,UAAU,GAAG,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC;QAElD,QAAQ,KAAK,EAAE,CAAC;YACd,KAAK,QAAQ,CAAC,KAAK;gBACjB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAC1C,MAAM;YACR,KAAK,QAAQ,CAAC,SAAS,CAAC;YACxB,KAAK,QAAQ,CAAC,OAAO;gBACnB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACzC,MAAM;YACR,KAAK,QAAQ,CAAC,KAAK,CAAC;YACpB,KAAK,QAAQ,CAAC,IAAI;gBAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBAC1C,MAAM;YACR,KAAK,QAAQ,CAAC,IAAI,CAAC;YACnB;gBACE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACzC,MAAM;QACV,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAsB;IAC3D,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/lib/logger.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { pino } from "pino";
|
|
2
|
+
type LogLevel = "fatal" | "error" | "warn" | "info" | "debug" | "trace" | "silent";
|
|
2
3
|
export interface LoggerConfig {
|
|
3
4
|
useJsonLogs?: boolean;
|
|
4
5
|
level?: LogLevel;
|
|
5
6
|
}
|
|
6
|
-
export declare function createLogger(config?: LoggerConfig):
|
|
7
|
-
|
|
7
|
+
export declare function createLogger(config?: LoggerConfig): pino.Logger<never, boolean>;
|
|
8
|
+
/**
|
|
9
|
+
* Configure the shared Breakcheck logger and the Crawlee logger together.
|
|
10
|
+
*/
|
|
11
|
+
export declare function configureLogger(config?: LoggerConfig): pino.Logger<never, boolean>;
|
|
12
|
+
export declare let logger: pino.Logger<never, boolean>;
|
|
8
13
|
export {};
|
package/dist/lib/logger.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { pino } from "pino";
|
|
2
|
+
import { configureCrawleeLogger } from "./crawlee-logger.js";
|
|
2
3
|
// Determine the log level from the environment variable, defaulting to 'info'
|
|
3
4
|
const logLevel = process.env.LOG_LEVEL || "info";
|
|
4
5
|
// Create a logger with the specified configuration
|
|
@@ -20,7 +21,16 @@ export function createLogger(config = {}) {
|
|
|
20
21
|
transport,
|
|
21
22
|
});
|
|
22
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Configure the shared Breakcheck logger and the Crawlee logger together.
|
|
26
|
+
*/
|
|
27
|
+
export function configureLogger(config = {}) {
|
|
28
|
+
logger = createLogger(config);
|
|
29
|
+
configureCrawleeLogger(logger);
|
|
30
|
+
return logger;
|
|
31
|
+
}
|
|
23
32
|
// Create the default shared logger instance (for backward compatibility)
|
|
24
33
|
// This will use pretty logging by default for CLI, but can be overridden
|
|
25
|
-
export
|
|
34
|
+
export let logger = createLogger({ useJsonLogs: false });
|
|
35
|
+
configureCrawleeLogger(logger);
|
|
26
36
|
//# sourceMappingURL=logger.js.map
|
package/dist/lib/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,8EAA8E;AAC9E,MAAM,QAAQ,GAAc,OAAO,CAAC,GAAG,CAAC,SAAsB,IAAI,MAAM,CAAC;AAQzE,mDAAmD;AACnD,MAAM,UAAU,YAAY,CAAC,MAAM,GAAiB,EAAE;IACpD,MAAM,EAAE,WAAW,GAAG,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC;IAEzD,gDAAgD;IAChD,MAAM,SAAS,GAAG,WAAW;QAC3B,CAAC,CAAC,SAAS,CAAC,4BAA4B;QACxC,CAAC,CAAC;YACE,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE;gBACP,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,cAAc;gBAC7B,MAAM,EAAE,cAAc;aACvB;SACF,CAAC;IAEN,OAAO,IAAI,CAAC;QACV,KAAK;QACL,SAAS;KACV,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAM,GAAiB,EAAE;IACvD,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAC9B,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,yEAAyE;AACzE,yEAAyE;AACzE,MAAM,CAAC,IAAI,MAAM,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;AACzD,sBAAsB,CAAC,MAAM,CAAC,CAAC"}
|
package/dist/lib/root.d.ts
CHANGED
package/dist/lib/root.js
CHANGED
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import { findUp
|
|
2
|
-
import
|
|
3
|
-
import path from "path";
|
|
1
|
+
import { findUp } from "find-up";
|
|
2
|
+
import { access, readFile } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
async function pathExists(filePath) {
|
|
5
|
+
try {
|
|
6
|
+
await access(filePath);
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT")
|
|
11
|
+
return false;
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
4
15
|
/**
|
|
5
16
|
* Finds the root directory of the project by looking for a package.json file
|
|
6
17
|
* that contains a "workspaces" configuration.
|
|
7
18
|
*
|
|
8
19
|
* @returns The absolute path to the root directory
|
|
9
20
|
*/
|
|
10
|
-
export async function findRootDir() {
|
|
21
|
+
export async function findRootDir(startDir = process.cwd()) {
|
|
11
22
|
const rootPackageJsonPath = await findUp(async (directory) => {
|
|
12
23
|
const packageJsonPath = path.join(directory, "package.json");
|
|
13
24
|
const exists = await pathExists(packageJsonPath);
|
|
14
25
|
if (exists) {
|
|
15
|
-
const packageJson = JSON.parse(await
|
|
26
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, "utf8"));
|
|
16
27
|
if (packageJson.workspaces) {
|
|
17
28
|
return packageJsonPath;
|
|
18
29
|
}
|
|
19
30
|
}
|
|
20
|
-
}, { type: "file" });
|
|
31
|
+
}, { type: "file", cwd: startDir });
|
|
21
32
|
return rootPackageJsonPath
|
|
22
33
|
? path.dirname(rootPackageJsonPath)
|
|
23
34
|
: process.cwd();
|
package/dist/lib/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/lib/root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/lib/root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YACtE,OAAO,KAAK,CAAC;QACf,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,QAAQ,GAAW,OAAO,CAAC,GAAG,EAAE;IAEhC,MAAM,mBAAmB,GAAG,MAAM,MAAM,CACtC,KAAK,EAAE,SAAS,EAAE,EAAE;QAClB,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC;YACxE,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;gBAC3B,OAAO,eAAe,CAAC;YACzB,CAAC;QACH,CAAC;IACH,CAAC,EACD,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAChC,CAAC;IAEF,OAAO,mBAAmB;QACxB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC;QACnC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Resolved locations for all Breakcheck-managed artifacts. */
|
|
2
|
+
export interface StorageContext {
|
|
3
|
+
storageDir: string;
|
|
4
|
+
snapshotsDir: string;
|
|
5
|
+
comparisonsDir: string;
|
|
6
|
+
}
|
|
7
|
+
/** Resolves an explicit artifact root or the legacy project root. */
|
|
8
|
+
export declare function resolveStorageContext(storageDir?: string): Promise<StorageContext>;
|
|
9
|
+
export declare function resolveStorageEntry(storageDir: string, name: string, kind: string): string;
|
|
10
|
+
export declare function deleteStorageEntry(storageDir: string, name: string, kind: string): Promise<boolean>;
|
|
11
|
+
export declare function listStorageDirectories(storageDir: string): Promise<string[]>;
|
|
12
|
+
export declare function deleteAllStorageEntries(storageDir: string, kind: string): Promise<string[]>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { lstat, readdir, rm } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findRootDir } from "./root.js";
|
|
4
|
+
/** Resolves an explicit artifact root or the legacy project root. */
|
|
5
|
+
export async function resolveStorageContext(storageDir) {
|
|
6
|
+
const resolvedStorageDir = path.resolve(storageDir ?? (await findRootDir()));
|
|
7
|
+
return {
|
|
8
|
+
storageDir: resolvedStorageDir,
|
|
9
|
+
snapshotsDir: path.join(resolvedStorageDir, "snapshots"),
|
|
10
|
+
comparisonsDir: path.join(resolvedStorageDir, "comparisons"),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function isErrnoException(error) {
|
|
14
|
+
return (error instanceof Error && "code" in error && typeof error.code === "string");
|
|
15
|
+
}
|
|
16
|
+
export function resolveStorageEntry(storageDir, name, kind) {
|
|
17
|
+
if (name.length === 0 ||
|
|
18
|
+
name.trim().length === 0 ||
|
|
19
|
+
name === "." ||
|
|
20
|
+
name === ".." ||
|
|
21
|
+
name.includes("/") ||
|
|
22
|
+
name.includes("\\")) {
|
|
23
|
+
throw new Error(`Invalid ${kind} name "${name}". Names must be a single path component.`);
|
|
24
|
+
}
|
|
25
|
+
const resolvedStorageDir = path.resolve(storageDir);
|
|
26
|
+
const resolvedEntry = path.resolve(resolvedStorageDir, name);
|
|
27
|
+
if (path.dirname(resolvedEntry) !== resolvedStorageDir) {
|
|
28
|
+
throw new Error(`Invalid ${kind} name "${name}". Names must remain inside the storage directory.`);
|
|
29
|
+
}
|
|
30
|
+
return resolvedEntry;
|
|
31
|
+
}
|
|
32
|
+
export async function deleteStorageEntry(storageDir, name, kind) {
|
|
33
|
+
const entryPath = resolveStorageEntry(storageDir, name, kind);
|
|
34
|
+
let entryStats;
|
|
35
|
+
try {
|
|
36
|
+
entryStats = await lstat(entryPath);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (isErrnoException(error) && error.code === "ENOENT") {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
if (!entryStats.isDirectory()) {
|
|
45
|
+
throw new Error(`Cannot delete ${kind} "${name}": it is not a directory.`);
|
|
46
|
+
}
|
|
47
|
+
await rm(entryPath, { recursive: true });
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
export async function listStorageDirectories(storageDir) {
|
|
51
|
+
let entries;
|
|
52
|
+
try {
|
|
53
|
+
entries = await readdir(storageDir, { withFileTypes: true });
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (isErrnoException(error) && error.code === "ENOENT") {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
return entries
|
|
62
|
+
.filter((entry) => entry.isDirectory())
|
|
63
|
+
.map((entry) => entry.name)
|
|
64
|
+
.sort();
|
|
65
|
+
}
|
|
66
|
+
export async function deleteAllStorageEntries(storageDir, kind) {
|
|
67
|
+
const names = await listStorageDirectories(storageDir);
|
|
68
|
+
const deletedNames = [];
|
|
69
|
+
for (const name of names) {
|
|
70
|
+
if (await deleteStorageEntry(storageDir, name, kind)) {
|
|
71
|
+
deletedNames.push(name);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return deletedNames;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=storage.js.map
|