@cronn/lib-file-snapshots 1.1.1 → 1.2.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/dist/index.d.mts CHANGED
@@ -22,6 +22,10 @@ declare class Table<TRow extends TableRow = TableRow> implements TableData<TRow>
22
22
  static fromRecords<TRow extends TableRowRecord>(rows: Array<TRow>): Table;
23
23
  }
24
24
  //#endregion
25
+ //#region src/types/normalizer.d.ts
26
+ type Normalizer<TValue> = (value: TValue) => TValue;
27
+ type NormalizerWithContext<TValue, TContext> = (value: TValue, context: TContext) => TValue;
28
+ //#endregion
25
29
  //#region src/types/serializer.d.ts
26
30
  interface SnapshotSerializer<TValue> {
27
31
  /**
@@ -57,7 +61,7 @@ interface JsonSerializerOptions {
57
61
  */
58
62
  indentSize?: number;
59
63
  }
60
- type JsonNormalizer = (value: unknown, context: JsonNormalizerContext) => unknown;
64
+ type JsonNormalizer = NormalizerWithContext<unknown, JsonNormalizerContext>;
61
65
  interface JsonNormalizerContext {
62
66
  key?: string;
63
67
  index?: number;
@@ -88,7 +92,7 @@ interface MarkdownTableSerializerOptions {
88
92
  */
89
93
  normalizers?: Array<MarkdownTableNormalizer>;
90
94
  }
91
- type MarkdownTableNormalizer = (value: TableCell) => TableCell;
95
+ type MarkdownTableNormalizer = Normalizer<TableCell>;
92
96
  declare class MarkdownTableSerializer implements SnapshotSerializer<TableData> {
93
97
  readonly fileExtension = "md";
94
98
  private readonly normalizers;
@@ -111,7 +115,7 @@ interface TextSerializerOptions {
111
115
  */
112
116
  fileExtension?: string;
113
117
  }
114
- type TextNormalizer = (value: string) => string;
118
+ type TextNormalizer = Normalizer<string>;
115
119
  declare class TextSerializer implements SnapshotSerializer<string> {
116
120
  readonly fileExtension: string;
117
121
  private readonly normalizers;
@@ -184,6 +188,36 @@ declare class ValidationFileMatcher<TValue> {
184
188
  declare function resolveNameAsFile(params: FilePathResolverParams): string;
185
189
  declare function resolveNameAsFileSuffix(params: FilePathResolverParams): string;
186
190
  //#endregion
191
+ //#region src/normalizers/string-normalizer.d.ts
192
+ /**
193
+ * Creates a guarded normalizer that only applies the given normalizer if the value is a string
194
+ *
195
+ * @example stringNormalizer((value) => value.trim())
196
+ */
197
+ declare function stringNormalizer<TValue>(normalizer: Normalizer<string>): Normalizer<TValue>;
198
+ //#endregion
199
+ //#region src/normalizers/mask-pattern.d.ts
200
+ /**
201
+ * Returns a normalizer that finds every distinct match of `searchPattern` and replaces it with `maskValue(index)`
202
+ *
203
+ * @param searchPattern The pattern to be masked (requires global flag to find all matches)
204
+ * @param maskValue The function returning the masked value to replace a matched value with
205
+ *
206
+ * @example maskPattern(/[\d{4}-\d{2}-\d{2}/g, (index) => `<DATE_${index}>`)
207
+ */
208
+ declare function maskPattern(searchPattern: RegExp, maskValue: (index: number) => string): Normalizer<string>;
209
+ //#endregion
210
+ //#region src/normalizers/mask-string.d.ts
211
+ /**
212
+ * Returns a normalizer that replaces every occurrence of `searchValue` with `maskedValue`.
213
+ *
214
+ * @param searchValue The value to be masked
215
+ * @param maskedValue The masked value to replace the `searchValue` with
216
+ *
217
+ * @example maskString("https://example.com", "<BASE_URL>")
218
+ */
219
+ declare function maskString(searchValue: string, maskedValue: string): Normalizer<string>;
220
+ //#endregion
187
221
  //#region src/utils/file.d.ts
188
222
  declare function normalizeFileName(testName: string): string;
189
223
  //#endregion
@@ -193,4 +227,4 @@ declare function isArray(value: unknown): value is Array<unknown>;
193
227
  type PlainObject = Record<PropertyKey, unknown>;
194
228
  declare function isPlainObject(value: unknown): value is PlainObject;
195
229
  //#endregion
196
- export { type FilePathResolver, type FilePathResolverParams, type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type MarkdownTableNormalizer, MarkdownTableSerializer, type PlainObject, type SnapshotSerializer, Table, type TableCell, type TableData, type TableRow, type TextNormalizer, TextSerializer, type UpdateSnapshotsType, ValidationFileMatcher, type ValidationFileMatcherResult, isArray, isPlainObject, isString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix };
230
+ export { type FilePathResolver, type FilePathResolverParams, type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type MarkdownTableNormalizer, MarkdownTableSerializer, type Normalizer, type NormalizerWithContext, type PlainObject, type SnapshotSerializer, Table, type TableCell, type TableData, type TableRow, type TextNormalizer, TextSerializer, type UpdateSnapshotsType, ValidationFileMatcher, type ValidationFileMatcherResult, isArray, isPlainObject, isString, maskPattern, maskString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix, stringNormalizer };
package/dist/index.mjs CHANGED
@@ -300,4 +300,60 @@ function resolveFilePath(params, resolveNamedFilePath) {
300
300
  });
301
301
  }
302
302
  //#endregion
303
- export { JsonSerializer, MarkdownTableSerializer, Table, TextSerializer, ValidationFileMatcher, isArray, isPlainObject, isString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix };
303
+ //#region src/normalizers/string-normalizer.ts
304
+ /**
305
+ * Creates a guarded normalizer that only applies the given normalizer if the value is a string
306
+ *
307
+ * @example stringNormalizer((value) => value.trim())
308
+ */
309
+ function stringNormalizer(normalizer) {
310
+ return guardedNormalizers(isString, normalizer);
311
+ }
312
+ function guardedNormalizers(guard, normalizer) {
313
+ return function conditionalNormalizer(value) {
314
+ if (!guard(value)) return value;
315
+ return normalizer(value);
316
+ };
317
+ }
318
+ //#endregion
319
+ //#region src/normalizers/mask-pattern.ts
320
+ /**
321
+ * Returns a normalizer that finds every distinct match of `searchPattern` and replaces it with `maskValue(index)`
322
+ *
323
+ * @param searchPattern The pattern to be masked (requires global flag to find all matches)
324
+ * @param maskValue The function returning the masked value to replace a matched value with
325
+ *
326
+ * @example maskPattern(/[\d{4}-\d{2}-\d{2}/g, (index) => `<DATE_${index}>`)
327
+ */
328
+ function maskPattern(searchPattern, maskValue) {
329
+ const distinctValues = /* @__PURE__ */ new Set();
330
+ return function normalizer(value) {
331
+ let match;
332
+ while ((match = searchPattern.exec(value)) !== null) {
333
+ const matchedValue = match[0];
334
+ if (!distinctValues.has(matchedValue)) distinctValues.add(matchedValue);
335
+ }
336
+ let maskedValue = value;
337
+ Array.from(distinctValues.values()).forEach((matchedValue, index) => {
338
+ maskedValue = maskedValue.replaceAll(matchedValue, maskValue(index));
339
+ });
340
+ return maskedValue;
341
+ };
342
+ }
343
+ //#endregion
344
+ //#region src/normalizers/mask-string.ts
345
+ /**
346
+ * Returns a normalizer that replaces every occurrence of `searchValue` with `maskedValue`.
347
+ *
348
+ * @param searchValue The value to be masked
349
+ * @param maskedValue The masked value to replace the `searchValue` with
350
+ *
351
+ * @example maskString("https://example.com", "<BASE_URL>")
352
+ */
353
+ function maskString(searchValue, maskedValue) {
354
+ return function normalizer(value) {
355
+ return value.replaceAll(searchValue, maskedValue);
356
+ };
357
+ }
358
+ //#endregion
359
+ export { JsonSerializer, MarkdownTableSerializer, Table, TextSerializer, ValidationFileMatcher, isArray, isPlainObject, isString, maskPattern, maskString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix, stringNormalizer };
package/package.json CHANGED
@@ -1,36 +1,24 @@
1
1
  {
2
2
  "name": "@cronn/lib-file-snapshots",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "The library agnostic core for testing file snapshots",
5
5
  "keywords": [
6
6
  "file snapshots"
7
7
  ],
8
+ "homepage": "https://github.com/cronn/file-snapshots",
8
9
  "bugs": {
9
10
  "url": "https://github.com/cronn/file-snapshots/issues"
10
11
  },
11
- "author": "cronn",
12
12
  "license": "Apache-2.0",
13
+ "author": "cronn",
13
14
  "repository": {
14
15
  "type": "git",
15
16
  "url": "git+https://github.com/cronn/file-snapshots.git",
16
17
  "directory": "packages/lib-file-snapshots"
17
18
  },
18
- "homepage": "https://github.com/cronn/file-snapshots",
19
- "engines": {
20
- "node": "^20 || ^22 || >=24"
21
- },
22
- "devEngines": {
23
- "runtime": {
24
- "name": "node",
25
- "version": ">=24.14.1 <25",
26
- "onFail": "error"
27
- },
28
- "packageManager": {
29
- "name": "pnpm",
30
- "version": ">=10.33.0 <11",
31
- "onFail": "error"
32
- }
33
- },
19
+ "files": [
20
+ "dist"
21
+ ],
34
22
  "type": "module",
35
23
  "exports": {
36
24
  "./package.json": "./package.json",
@@ -39,37 +27,48 @@
39
27
  "default": "./dist/index.mjs"
40
28
  }
41
29
  },
42
- "files": [
43
- "dist"
44
- ],
45
30
  "dependencies": {
46
31
  "markdown-table": "3.0.4"
47
32
  },
48
33
  "devDependencies": {
49
34
  "@arethetypeswrong/core": "0.18.2",
50
- "@trivago/prettier-plugin-sort-imports": "6.0.2",
51
- "@types/node": "24.12.2",
52
- "@typescript/native-preview": "7.0.0-dev.20260413.1",
53
- "@vitest/coverage-v8": "4.1.4",
54
- "eslint": "10.2.0",
35
+ "@types/node": "24.12.4",
36
+ "@typescript/native-preview": "7.0.0-dev.20260518.1",
37
+ "@vitest/coverage-v8": "4.1.6",
38
+ "eslint": "10.4.0",
55
39
  "eslint-config-prettier": "10.1.8",
56
40
  "eslint-plugin-check-file": "3.3.1",
57
41
  "eslint-plugin-unused-imports": "4.4.1",
58
- "prettier": "3.8.2",
59
- "publint": "0.3.18",
42
+ "publint": "0.3.21",
60
43
  "rimraf": "6.1.3",
61
- "tsdown": "0.21.7",
62
- "typescript-eslint": "8.58.1",
63
- "vitest": "4.1.4",
44
+ "tsdown": "0.22.0",
45
+ "typescript-eslint": "8.59.4",
46
+ "vitest": "4.1.6",
47
+ "node": "runtime:>=24.14.1 <25",
64
48
  "@cronn/shared-configs": "0.0.0"
65
49
  },
50
+ "devEngines": {
51
+ "packageManager": {
52
+ "name": "pnpm",
53
+ "version": "11.3.0",
54
+ "onFail": "download"
55
+ },
56
+ "runtime": {
57
+ "name": "node",
58
+ "version": ">=24.14.1 <25",
59
+ "onFail": "download"
60
+ }
61
+ },
62
+ "engines": {
63
+ "node": "^20 || ^22 || >=24"
64
+ },
66
65
  "scripts": {
66
+ "build": "tsdown",
67
+ "clean": "rimraf .turbo dist coverage",
68
+ "compile": "tsgo",
67
69
  "lint:check": "eslint src/ --max-warnings=0",
68
70
  "lint:fix": "eslint src/ --max-warnings=0 --fix",
69
71
  "test": "vitest run",
70
- "test:coverage": "vitest run --coverage",
71
- "compile": "tsgo",
72
- "build": "tsdown",
73
- "clean": "rimraf .turbo dist coverage"
72
+ "test:coverage": "vitest run --coverage"
74
73
  }
75
74
  }