@produtype/core 1.20.0 → 1.21.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.
@@ -33,15 +33,43 @@ const LOGGING_PACKAGES = [
33
33
  ];
34
34
  /** Elixir reaches for a backend rather than a logger: Logger itself is in OTP. */
35
35
  const ELIXIR_LOGGING_PACKAGES = ['logger_json', 'logger_file_backend', 'sentry'];
36
+ /**
37
+ * The route, in every spelling somebody writes it.
38
+ *
39
+ * `\/(health|healthz|readyz|livez|alive)\b` does not match `/healthcheck`: after
40
+ * `health` comes a `c`, and the boundary fails. Netflix's dispatch declares
41
+ * `@api_router.get("/healthcheck")` and was told it has no health endpoint — the
42
+ * plainest spelling there is, missed by the pattern meant to find it.
43
+ *
44
+ * This does not disturb the decision recorded below about Dropwizard. That one is
45
+ * about an endpoint the *framework* publishes, which no Dropwizard application writes
46
+ * in its own source; a line like dispatch's is somebody declaring the route
47
+ * themselves.
48
+ */
49
+ const HEALTH_ROUTE = /\/(health|healthz|healthcheck|health[-_]check|readyz|livez|alive)\b/i;
36
50
  async function detectObservability(ctx) {
37
51
  const evidence = [];
38
- const logDeps = [...(0, detectContext_1.hasAnyDep)(ctx, LOGGING_PACKAGES), ...(0, detectContext_1.hasAnyElixirDep)(ctx, ELIXIR_LOGGING_PACKAGES)];
52
+ /**
53
+ * .NET names its logging in the project file and nothing here was reading it.
54
+ *
55
+ * Radarr declares `NLog`, `NLog.Extensions.Logging` and
56
+ * `NLog.Layouts.ClefJsonLayout` — CLEF being the compact JSON event format — and
57
+ * was reported as logging something but not structurally. The npm list has had
58
+ * winston and pino since the beginning and treats the dependency alone as enough;
59
+ * these are the same statement in another manifest.
60
+ */
61
+ const DOTNET_LOGGING_PACKAGES = ['NLog', 'NLog.Extensions.Logging', 'Serilog', 'Serilog.AspNetCore', 'Microsoft.Extensions.Logging', 'log4net'];
62
+ const logDeps = [
63
+ ...(0, detectContext_1.hasAnyDep)(ctx, LOGGING_PACKAGES),
64
+ ...(0, detectContext_1.hasAnyElixirDep)(ctx, ELIXIR_LOGGING_PACKAGES),
65
+ ...(0, detectContext_1.hasAnyDotnetDep)(ctx, DOTNET_LOGGING_PACKAGES),
66
+ ];
39
67
  const sentryDeps = (0, detectContext_1.hasAnyDep)(ctx, ['@sentry/node', 'sentry-sdk']);
40
68
  for (const d of logDeps)
41
69
  evidence.push({ type: 'dependency', value: d, claim: 'logging' });
42
70
  for (const d of sentryDeps)
43
71
  evidence.push({ type: 'dependency', value: d, claim: 'logging' });
44
- const hits = await (0, textSearch_1.searchInFiles)(ctx.root, ctx.files.source, [/\/(health|healthz|readyz|livez|alive)\b/i, /x-request-id/i, /correlation-id/i, /error\s*handler/i, /RotatingFileHandler/i], 25);
72
+ const hits = await (0, textSearch_1.searchInFiles)(ctx.root, ctx.files.source, [HEALTH_ROUTE, /x-request-id/i, /correlation-id/i, /error\s*handler/i, /RotatingFileHandler/i], 25);
45
73
  /**
46
74
  * One search, three answers, so the claim is decided per hit rather than per search.
47
75
  *
@@ -50,7 +78,7 @@ async function detectObservability(ctx) {
50
78
  * is what the line is evidence of.
51
79
  */
52
80
  for (const m of hits) {
53
- const claim = /\/(health|healthz|readyz|livez|alive)\b/i.test(m.snippet)
81
+ const claim = HEALTH_ROUTE.test(m.snippet)
54
82
  ? 'health'
55
83
  : /x-request-id|correlation-id/i.test(m.snippet)
56
84
  ? 'request-id'
@@ -116,7 +144,7 @@ async function detectObservability(ctx) {
116
144
  const hasHealth = declaredProbes.length > 0
117
145
  || healthFiles.length > 0
118
146
  || actuator.length > 0
119
- || hits.some((h) => /\/(health|healthz|readyz|livez|alive)\b/i.test(h.snippet));
147
+ || hits.some((h) => HEALTH_ROUTE.test(h.snippet));
120
148
  const hasReqId = hits.some((h) => /x-request-id|correlation-id/i.test(h.snippet));
121
149
  // Structured logging without a logging library is still structured logging. What
122
150
  // matters is that entries are machine-readable and correlated, not which package
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {