• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yiming-liao / logry / 15847159054

24 Jun 2025 09:49AM UTC coverage: 96.514% (-0.2%) from 96.733%
15847159054

push

github

yiming-liao
refactor(core): restructure logger pipeline and unify formatter

- Moved normalization and formatting steps from Logger to Transporters, aligning with Handler behavior.
- Relocated HandlerManager into core module due to tight coupling with Logger logic.
- Refactored Logger class into layered structure for better separation of concerns and extensibility.
- Unified formatter for all platforms; replaced platform separation with type-based strategy.
- Added edge support via  module to ensure compatibility without Node.js globals.
- Introduced  module exposing base handler classes (BaseHandler, NodeHandler, BrowserHandler, etc.) for developer extension.
- Cleaned up examples and benchmarks for clarity.
- Reorganized and updated test suite under .

449 of 499 branches covered (89.98%)

Branch coverage included in aggregate %.

2153 of 2176 new or added lines in 88 files covered. (98.94%)

17 existing lines in 3 files now uncovered.

4175 of 4292 relevant lines covered (97.27%)

4.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.0
/src/modules/formatters/utils/format-string-fields.ts
1
import type {
1✔
2
  CustomFormatter,
1✔
3
  FormatFieldOptions,
1✔
4
  FormatFieldReturn,
1✔
5
} from "@/modules/formatters/types";
1✔
6
import type { Platform } from "@/shared/types";
1✔
7
import type { SnapshotLogFields, FieldKey } from "@/shared/types/log-fields";
1✔
8
import { resolveScopeString } from "@/modules/formatters/utils/resolve-scope-string";
1✔
9
import { addAnsiStyle } from "@/modules/formatters/utils/style/add-ansi-style";
1✔
10
import { addLevelPadding } from "@/modules/formatters/utils/style/add-level-padding";
1✔
11
import { addLineBreakPrefix } from "@/modules/formatters/utils/style/add-line-break-prefix";
1✔
12
import { addPrefixAndSuffix } from "@/modules/formatters/utils/style/add-prefix-and-suffix";
1✔
13
import { addSpaceAfter } from "@/modules/formatters/utils/style/add-space-after";
1✔
14
import { tryCustomFormatter } from "@/modules/formatters/utils/try-custom-formatter";
1✔
15

1✔
16
/**
1✔
17
 * Format a string-type log field with optional styles, spacing, and custom logic.
1✔
18
 */
1✔
19
export const formatStringFields = <P extends Platform, K extends FieldKey>({
1✔
20
  platform,
12✔
21
  fieldKey,
12✔
22
  fieldValue,
12✔
23
  raw,
12✔
24
  options,
12✔
25
}: {
12✔
26
  platform: P;
12✔
27
  fieldKey: K;
12✔
28
  fieldValue?: string;
12✔
29
  raw: SnapshotLogFields;
12✔
30
  options: FormatFieldOptions<P, K, "string">;
12✔
31
}): FormatFieldReturn<"string"> => {
12✔
32
  const isNode = platform === "node";
12✔
33
  const isBrowser = platform === "browser";
12✔
34

12✔
35
  const { hide, prefix, suffix, lineBreaks, spaceAfter, customFormatter } =
12✔
36
    options;
12✔
37
  const nodeOptions = options as FormatFieldOptions<"node", K, "string">;
12✔
38
  const browserOptions = options as FormatFieldOptions<"browser", K, "string">;
12✔
39

12✔
40
  // Return early if hidden or empty
12✔
41
  if (hide || fieldValue === undefined || fieldValue === null) {
12✔
42
    return {
3✔
43
      fieldValue: "",
3✔
44
      withAnsiStyle: "",
3✔
45
      cssStyle: "",
3✔
46
    };
3✔
47
  }
3✔
48

9✔
49
  // Use custom formatter if provided
9✔
50
  if (customFormatter) {
12!
NEW
51
    const customized = tryCustomFormatter({
×
NEW
52
      fieldKey,
×
NEW
53
      input: { fieldValue, raw },
×
NEW
54
      customFormatter: customFormatter as CustomFormatter<"string">,
×
NEW
55
    });
×
NEW
56
    if (customized) {
×
NEW
57
      return customized;
×
NEW
58
    }
×
NEW
59
  }
×
60

9✔
61
  // Format scope (array → string)
9✔
62
  if (fieldKey === "scope" && Array.isArray(raw.scope)) {
12✔
63
    fieldValue = resolveScopeString({
1✔
64
      scope: fieldValue,
1✔
65
      rawScope: raw.scope,
1✔
66
      showOnlyLatest: (options as FormatFieldOptions<P, "scope", "string">)
1✔
67
        .showOnlyLatest,
1✔
68
      customSeparator: (options as FormatFieldOptions<P, "scope", "string">)
1✔
69
        .separator,
1✔
70
    });
1✔
71
  }
1✔
72

9✔
73
  // Apply prefix and suffix
9✔
74
  let decorated = addPrefixAndSuffix(fieldValue, prefix, suffix);
9✔
75

9✔
76
  // Optionally align level text width
9✔
77
  if (
9✔
78
    fieldKey === "level" &&
9✔
79
    typeof raw.level === "string" &&
12✔
80
    (options as FormatFieldOptions<P, "level", "string">).enableAlignment
2✔
81
  ) {
12✔
82
    decorated = addLevelPadding(decorated, raw.level);
2✔
83
  }
2✔
84

9✔
85
  // Final plain string
9✔
86
  let plain = addLineBreakPrefix(decorated, lineBreaks);
9✔
87
  plain = addSpaceAfter(plain, spaceAfter);
9✔
88

9✔
89
  // Optionally apply ANSI color (Node only)
9✔
90
  let withAnsiStyle: string | undefined;
9✔
91
  if (isNode) {
9✔
92
    withAnsiStyle = addAnsiStyle(decorated, nodeOptions.ansiStyle);
9✔
93
    withAnsiStyle = addLineBreakPrefix(withAnsiStyle, lineBreaks);
9✔
94
    withAnsiStyle = addSpaceAfter(withAnsiStyle, spaceAfter);
9✔
95
  }
9✔
96

9✔
97
  // Return platform-specific result
9✔
98
  return {
9✔
99
    fieldValue: plain,
9✔
100
    withAnsiStyle: isNode ? withAnsiStyle : undefined,
12!
101
    cssStyle: isBrowser ? browserOptions.cssStyle : undefined,
12!
102
  };
12✔
103
};
12✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc