@devopsplaybook.io/common-utils 1.9.2 → 1.10.0-beta.22.53149f9

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.
@@ -11,6 +11,7 @@ jobs:
11
11
  uses: devopsplaybook-io/common-utils/.github/workflows/reusable-npm-merge.yml@main
12
12
  with:
13
13
  npm_package_name: "@devopsplaybook.io/common-utils"
14
+ node_version: "22"
14
15
  secrets:
15
16
  NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
16
17
  QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
@@ -20,6 +20,7 @@ jobs:
20
20
  uses: devopsplaybook-io/common-utils/.github/workflows/reusable-npm-pr.yml@main
21
21
  with:
22
22
  npm_package_name: "@devopsplaybook.io/common-utils"
23
+ node_version: "22"
23
24
  secrets:
24
25
  NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
25
26
  QUALITY_DASHBOARD_URL: ${{ secrets.QUALITY_DASHBOARD_URL }}
@@ -7,7 +7,7 @@ on:
7
7
  description: "Node.js version to use"
8
8
  required: false
9
9
  type: string
10
- default: "18"
10
+ default: "22"
11
11
  npm_package_name:
12
12
  description: "NPM package name (e.g. @devopsplaybook.io/otel-utils)"
13
13
  required: true
@@ -7,7 +7,7 @@ on:
7
7
  description: "Node.js version to use"
8
8
  required: false
9
9
  type: string
10
- default: "18"
10
+ default: "22"
11
11
  npm_package_name:
12
12
  description: "NPM package name (e.g. @devopsplaybook.io/otel-utils)"
13
13
  required: true
package/AGENTS.md CHANGED
@@ -52,8 +52,8 @@ The weekly update of the shared npm libraries is agent-driven instead: a Kuberne
52
52
  ## Key Conventions
53
53
 
54
54
  - **TypeScript**: Target ES2019, CommonJS output, strict mode enabled, declarations generated.
55
- - **ESLint**: Uses `typescript-eslint` with `strict` and `stylistic` rule sets. Minimize `eslint-disable` comments; use them only when the type system cannot express the constraint (e.g., `@typescript-eslint/no-explicit-any` for `this as any` dynamic field access in `ConfigBase`).
56
- - **Tests**: Jest with `ts-jest`. Spec files live next to source (`*.spec.ts`). Run with `npm run test`. The `tsconfig.spec.json` includes jest types.
55
+ - **Linting**: Uses `oxlint` with its default **recommended** preset. Minimize disable comments (`eslint-disable`-style comments are honored by oxlint); use them only when the rule cannot be satisfied (e.g. `no-explicit-any` is not enabled by the recommended preset, so `any` needs no directive).
56
+ - **Tests**: Jest with `@swc/jest` transform (`jsc.target` matches tsconfig ES2019) and `v8` coverage provider. Spec files live next to source (`*.spec.ts`). Run with `npm run test`. The `tsconfig.spec.json` includes jest types; `npm run build` also type-checks specs (`tsc -p tsconfig.spec.json --noEmit`).
57
57
  - **No default exports**: All modules use named exports only.
58
58
  - **OTel dependency injection**: Every DB module exposes a `*SetOTel(tracer, logger)` function that must be called before `*Init()`. OTel instances are stored as module-level singletons.
59
59
  - **Auth modules**: `AuthSetOTel(tracer)` and `UsersDataSetOTel(tracer)` must be called before `AuthInit`. Application scopes are registered through `AuthInit(context, config, allScopes)`; `UsersRoutes` relies on `req.tracerSpanApi` set by the `otel-utils-fastify` hooks.
@@ -68,7 +68,7 @@ The weekly update of the shared npm libraries is agent-driven instead: a Kuberne
68
68
  ```bash
69
69
  npm install
70
70
  npm run build # tsc -> dist/
71
- npm run lint # eslint src (must pass with 0 errors)
71
+ npm run lint # oxlint src (must pass with 0 errors)
72
72
  npm run test # jest --coverage (all tests must pass)
73
73
  ```
74
74
 
@@ -91,7 +91,7 @@ All three commands must pass before committing. The CI pipeline (`reusable-npm-m
91
91
 
92
92
  - **uuid ESM**: `uuid` v14+ ships ESM. In any test that transitively imports `uuid`, add `jest.mock("uuid", () => ({ v4: () => "mock-uuid-1234" }))` to avoid `SyntaxError: Unexpected token 'export'`.
93
93
  - **better-sqlite3 is synchronous**: `SqlDbUtils` functions return values directly (not Promises). `PostgresDbUtils` functions return Promises. The `DbUtils` facade returns `number | Promise<number>` depending on the active backend.
94
- - **eslint-disable placement**: `eslint-disable-next-line` applies to the **immediately following line only**. When disabling a rule inside a function call argument, place the comment directly before the offending expression, not before the function call.
94
+ - **Disable-comment placement**: `eslint-disable-next-line` applies to the **immediately following line only** (oxlint honors these comments too). When disabling a rule inside a function call argument, place the comment directly before the offending expression, not before the function call.
95
95
  - **pg callback typing**: Always explicitly type pg callback parameters: `(error: Error | null, result: { rowCount: number | null })`. TypeScript cannot infer these from the overloaded `pool.query` signature.
96
96
 
97
97
  ## Adopting in Other Projects
package/README.md CHANGED
@@ -498,7 +498,7 @@ The `.github/workflows/` directory contains **reusable workflows** that other re
498
498
 
499
499
  | Input | Required | Default | Description |
500
500
  | ------------------ | -------- | ------- | --------------------------------------------------------- |
501
- | `node_version` | No | `"18"` | Node.js version |
501
+ | `node_version` | No | `"22"` | Node.js version |
502
502
  | `npm_package_name` | Yes | -- | npm package name (e.g. `@devopsplaybook.io/common-utils`) |
503
503
 
504
504
  | Secret | Required | Description |
@@ -630,7 +630,7 @@ jobs:
630
630
  ```bash
631
631
  npm install
632
632
  npm run build # TypeScript compilation -> dist/
633
- npm run lint # ESLint (strict + stylistic)
633
+ npm run lint # oxlint (recommended preset)
634
634
  npm run test # Jest with coverage
635
635
  ```
636
636
 
@@ -46,7 +46,6 @@ const path_1 = __importDefault(require("path"));
46
46
  * array → JSON.parse, etc.). When the default is already a string or
47
47
  * there is no default, the original string is returned as-is.
48
48
  */
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
49
  function coerceValue(value, defaultValue) {
51
50
  if (defaultValue === undefined || defaultValue === null) {
52
51
  return value;
@@ -145,7 +144,7 @@ class ConfigBase {
145
144
  if (pkg && pkg.version) {
146
145
  this.VERSION = pkg.version;
147
146
  }
148
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
147
+ // eslint-disable-next-line no-unused-vars -- catch binding kept so dist/ stays byte-identical to the TS6 build
149
148
  }
150
149
  catch (_e) {
151
150
  // fallback to "1"
@@ -196,7 +195,6 @@ class ConfigBase {
196
195
  field: def.field,
197
196
  sensitive: (_a = def.sensitive) !== null && _a !== void 0 ? _a : false,
198
197
  envAliases: (_b = def.envAliases) !== null && _b !== void 0 ? _b : [],
199
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
200
198
  defaultValue: this[def.field],
201
199
  });
202
200
  }
@@ -208,12 +206,11 @@ class ConfigBase {
208
206
  * When omitted nothing is logged (useful in tests).
209
207
  */
210
208
  async reload(logger) {
211
- // eslint-disable-next-line @typescript-eslint/no-empty-function
212
209
  const log = logger !== null && logger !== void 0 ? logger : (() => { });
213
210
  let content = {};
214
211
  try {
215
212
  content = await fse.readJson(this.CONFIG_FILE);
216
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
213
+ // eslint-disable-next-line no-unused-vars -- catch binding kept so dist/ stays byte-identical to the TS6 build
217
214
  }
218
215
  catch (_e) {
219
216
  // config file is optional – fall back to env + defaults
@@ -244,13 +241,11 @@ class ConfigBase {
244
241
  // 3. Apply environment value (full name or alias) if found,
245
242
  // coercing strings to match the default value type
246
243
  if (foundValue !== undefined) {
247
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
248
244
  this[field] = coerceValue(foundValue, defaultValue);
249
245
  }
250
246
  // 4. Config file override (environment always wins, but if neither
251
247
  // environment nor alias matched, check config file)
252
248
  if (foundValue === undefined && content[field] !== undefined) {
253
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
254
249
  this[field] = content[field];
255
250
  from = "config";
256
251
  }
@@ -258,9 +253,7 @@ class ConfigBase {
258
253
  log(`Configuration Value: ${field}: ******************** (from ${from})`);
259
254
  }
260
255
  else {
261
- log(
262
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
263
- `Configuration Value: ${field}: ${this[field]} (from ${from}${usedAlias ? ` via alias` : ""})`);
256
+ log(`Configuration Value: ${field}: ${this[field]} (from ${from}${usedAlias ? ` via alias` : ""})`);
264
257
  }
265
258
  }
266
259
  }
@@ -75,7 +75,6 @@ async function DbUtilsInit(context, config, sqlDir) {
75
75
  * - SQLite: `better-sqlite3` `Database` instance
76
76
  * - Postgres: `pg` `Pool` instance
77
77
  */
78
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
79
78
  function DbUtilsGetDatabase() {
80
79
  if (databaseType === "postgres") {
81
80
  return PostgresDbUtils.PostgresDbUtilsGetPool();
@@ -19,9 +19,7 @@ function DbUtilsNoTelemetrySetLogger(loggerIn) {
19
19
  *
20
20
  * @returns Number of rows inserted.
21
21
  */
22
- function DbUtilsNoTelemetryBatchInsert(tableCols, numCols,
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
- rows) {
22
+ function DbUtilsNoTelemetryBatchInsert(tableCols, numCols, rows) {
25
23
  if (rows.length === 0)
26
24
  return 0;
27
25
  const rowSQL = `(${Array.from({ length: numCols }, () => "?").join(",")})`;
@@ -40,7 +38,6 @@ function DbUtilsNoTelemetryExecSQL(sql, params = []) {
40
38
  if (dbType === "postgres") {
41
39
  const pgSql = (0, DbUtils_1.convertToPostgresPlaceholders)(sql);
42
40
  return new Promise((resolve, reject) => {
43
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
44
41
  (0, DbUtils_1.DbUtilsGetDatabase)().query(pgSql, params, (error, result) => {
45
42
  if (error) {
46
43
  logger.error(`SQL INSERT ERROR: ${sql.substring(0, 200)}`, error);
@@ -71,7 +68,6 @@ function DbUtilsNoTelemetryQuerySQL(sql, params = [], debug = false) {
71
68
  if (dbType === "postgres") {
72
69
  const pgSql = (0, DbUtils_1.convertToPostgresPlaceholders)(sql);
73
70
  return new Promise((resolve, reject) => {
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
71
  (0, DbUtils_1.DbUtilsGetDatabase)().query(pgSql, params, (error, result) => {
76
72
  if (error) {
77
73
  logger.error(`SQL ERROR: ${sql}`, error);
package/dist/src/LLM.js CHANGED
@@ -87,7 +87,6 @@ class LLMClient {
87
87
  throw new Error("LLM integration disabled (apiKey, apiUrl or model not set)");
88
88
  }
89
89
  const model = (options === null || options === void 0 ? void 0 : options.model) || this.model;
90
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
90
  const body = {
92
91
  model,
93
92
  messages,
@@ -122,7 +121,6 @@ class LLMClient {
122
121
  extractErrorMessage(err) {
123
122
  var _a, _b, _c;
124
123
  if (axios_1.default.isAxiosError(err)) {
125
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
124
  const providerMessage = (_c = (_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message;
127
125
  if (providerMessage) {
128
126
  return providerMessage;
@@ -36,7 +36,6 @@ function createOTelContext() {
36
36
  }
37
37
  return logger;
38
38
  },
39
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
39
  OTelRequestSpan: (req) => req === null || req === void 0 ? void 0 : req.tracerSpanApi,
41
40
  };
42
41
  }
@@ -166,9 +166,7 @@ class PostgresSchemaDbUtils {
166
166
  * otherwise use the runtime pool (default).
167
167
  * @returns Number of rows changed.
168
168
  */
169
- execSQL(context, sql,
170
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
- params = [], useSchemaPool = false) {
169
+ execSQL(context, sql, params = [], useSchemaPool = false) {
172
170
  const span = tracer.startSpan("PostgresSchemaDbUtilsExecSQL", context);
173
171
  const pool = useSchemaPool ? this.schemaPool : this.runtimePool;
174
172
  if (!pool) {
@@ -219,9 +217,7 @@ class PostgresSchemaDbUtils {
219
217
  * Execute a read SQL query with OTel tracing.
220
218
  * @returns Array of row objects.
221
219
  */
222
- querySQL(context, sql,
223
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
224
- params = [], useSchemaPool = false) {
220
+ querySQL(context, sql, params = [], useSchemaPool = false) {
225
221
  const span = tracer.startSpan("PostgresSchemaDbUtilsQuerySQL", context);
226
222
  const pool = useSchemaPool ? this.schemaPool : this.runtimePool;
227
223
  if (!pool) {
@@ -247,9 +243,7 @@ class PostgresSchemaDbUtils {
247
243
  /**
248
244
  * Run a callback inside a transaction.
249
245
  */
250
- async transaction(context,
251
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
252
- callback, useSchemaPool = false) {
246
+ async transaction(context, callback, useSchemaPool = false) {
253
247
  const span = tracer.startSpan("PostgresSchemaDbUtilsTransaction", context);
254
248
  const pool = useSchemaPool ? this.schemaPool : this.runtimePool;
255
249
  if (!pool) {
@@ -294,15 +288,12 @@ class PostgresSchemaDbUtils {
294
288
  this.moduleLogger.info("All database pools closed");
295
289
  }
296
290
  // -- Internal helpers (schema pool only) ----------------------------------
297
- execSQLForSchema(context, sql,
298
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
299
- params = []) {
291
+ execSQLForSchema(context, sql, params = []) {
300
292
  const span = tracer.startSpan("PostgresSchemaDbUtilsExecSQLForSchema", context);
301
293
  if (!this.schemaPool) {
302
294
  throw new Error(`Pool not initialized for schema: ${this.schemaName}`);
303
295
  }
304
296
  return new Promise((resolve, reject) => {
305
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
306
297
  this.schemaPool.query(sql, params, (error) => {
307
298
  span.end();
308
299
  if (error) {
@@ -322,11 +313,9 @@ class PostgresSchemaDbUtils {
322
313
  throw new Error(`Pool not initialized for schema: ${this.schemaName}`);
323
314
  }
324
315
  return new Promise((resolve, reject) => {
325
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
326
316
  this.schemaPool.query(sql, (error) => {
327
317
  span.end();
328
318
  if (error) {
329
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
330
319
  if (error.code === "ENOENT") {
331
320
  resolve();
332
321
  }
@@ -341,22 +330,18 @@ class PostgresSchemaDbUtils {
341
330
  });
342
331
  }
343
332
  catch (error) {
344
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
345
333
  if (error.code === "ENOENT") {
346
334
  return;
347
335
  }
348
336
  throw error;
349
337
  }
350
338
  }
351
- querySQLForSchema(context, sql,
352
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
353
- params = []) {
339
+ querySQLForSchema(context, sql, params = []) {
354
340
  const span = tracer.startSpan("PostgresSchemaDbUtilsQuerySQLForSchema", context);
355
341
  if (!this.schemaPool) {
356
342
  throw new Error(`Pool not initialized for schema: ${this.schemaName}`);
357
343
  }
358
344
  return new Promise((resolve, reject) => {
359
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
360
345
  this.schemaPool.query(sql, params, (error, result) => {
361
346
  span.end();
362
347
  if (error) {
@@ -104,7 +104,6 @@ async function AuthGenerateJWT(user) {
104
104
  * mirroring the owning user's live role and scopes is built (valid until
105
105
  * the token is revoked).
106
106
  */
107
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
107
  async function jwtDecodeCached(req) {
109
108
  if (req._jwtPayload) {
110
109
  return req._jwtPayload;
@@ -131,7 +130,6 @@ async function jwtDecodeCached(req) {
131
130
  * Permissions are read from the user record at resolution time, so
132
131
  * role/scope changes apply to existing tokens immediately.
133
132
  */
134
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
133
  async function resolveApiToken(authorizationHeader) {
136
134
  const token = authorizationHeader.split(" ")[1];
137
135
  if (!token) {
@@ -140,7 +138,6 @@ async function resolveApiToken(authorizationHeader) {
140
138
  const span = tracer.startSpan("AuthResolveApiToken");
141
139
  const tokenHash = (0, crypto_1.createHash)("sha256").update(token).digest("hex");
142
140
  const apiToken = await (0, UsersApiTokensData_1.UsersApiTokensDataGetByTokenHash)(span, tokenHash);
143
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
141
  let payload = null;
145
142
  if (apiToken) {
146
143
  const user = await (0, UsersData_1.UsersDataGet)(span, apiToken.userId);
@@ -156,17 +153,12 @@ async function resolveApiToken(authorizationHeader) {
156
153
  span.end();
157
154
  return payload;
158
155
  }
159
- async function AuthMustBeAuthenticated(
160
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
161
- req,
162
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
- res) {
156
+ async function AuthMustBeAuthenticated(req, res) {
164
157
  if (!(await jwtDecodeCached(req))) {
165
158
  res.status(403).send({ error: "Access Denied" });
166
159
  throw new Error("Access Denied");
167
160
  }
168
161
  }
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
162
  async function AuthMustBeAdmin(req, res) {
171
163
  const info = await jwtDecodeCached(req);
172
164
  if ((info === null || info === void 0 ? void 0 : info.role) === "admin") {
@@ -175,11 +167,7 @@ async function AuthMustBeAdmin(req, res) {
175
167
  res.status(403).send({ error: "Access Denied" });
176
168
  throw new Error("Access Denied");
177
169
  }
178
- async function AuthHasScope(
179
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
- req,
181
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
- res, scope) {
170
+ async function AuthHasScope(req, res, scope) {
183
171
  const info = await jwtDecodeCached(req);
184
172
  if (!info) {
185
173
  res.status(403).send({ error: "Access Denied" });
@@ -195,7 +183,6 @@ res, scope) {
195
183
  res.status(403).send({ error: "Access Denied" });
196
184
  throw new Error("Access Denied");
197
185
  }
198
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
186
  async function AuthGetUserSession(req) {
200
187
  const userSession = { isAuthenticated: false };
201
188
  const info = await jwtDecodeCached(req);
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.User = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  class User {
6
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
6
  static fromJson(json) {
8
7
  if (!json) {
9
8
  return null;
@@ -34,7 +33,6 @@ class User {
34
33
  this.scopes = [...User.DEFAULT_SCOPES];
35
34
  this.id = (0, uuid_1.v4)();
36
35
  }
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
36
  toJson() {
39
37
  return {
40
38
  id: this.id,
@@ -44,7 +42,6 @@ class User {
44
42
  scopes: this.scopes,
45
43
  };
46
44
  }
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
45
  toTransportJson() {
49
46
  return {
50
47
  id: this.id,
@@ -12,7 +12,6 @@ const uuid_1 = require("uuid");
12
12
  */
13
13
  class UserApiToken {
14
14
  //
15
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
15
  static fromJson(json) {
17
16
  if (!json) {
18
17
  return null;
@@ -28,7 +27,6 @@ class UserApiToken {
28
27
  constructor() {
29
28
  this.id = (0, uuid_1.v4)();
30
29
  }
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
30
  toJson() {
33
31
  return {
34
32
  id: this.id,
@@ -39,7 +37,6 @@ class UserApiToken {
39
37
  };
40
38
  }
41
39
  // Transport representation: never exposes the token hash.
42
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
43
40
  toTransportJson() {
44
41
  return {
45
42
  id: this.id,
@@ -71,7 +71,6 @@ async function UsersApiTokensDataDeleteByUser(context, userId) {
71
71
  span.end();
72
72
  }
73
73
  // Private Functions
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
74
  function fromRaw(tokenRaw) {
76
75
  const apiToken = new UserApiToken_1.UserApiToken();
77
76
  apiToken.id = tokenRaw.id;
@@ -86,7 +86,6 @@ async function UsersDataDelete(context, id) {
86
86
  span.end();
87
87
  }
88
88
  // Private Functions
89
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
89
  function fromRaw(userRaw) {
91
90
  const user = new User_1.User();
92
91
  user.id = userRaw.id;
@@ -13,7 +13,6 @@ const UsersApiTokensData_1 = require("./UsersApiTokensData");
13
13
  * Retrieves the OTel span attached to the request by the
14
14
  * `@devopsplaybook.io/otel-utils-fastify` hooks.
15
15
  */
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
16
  function requestSpan(req) {
18
17
  return req === null || req === void 0 ? void 0 : req.tracerSpanApi;
19
18
  }
package/jest.config.js CHANGED
@@ -2,12 +2,15 @@ module.exports = {
2
2
  moduleFileExtensions: ["ts", "js"],
3
3
  transform: {
4
4
  "^.+\\.(ts|tsx)$": [
5
- "ts-jest",
5
+ "@swc/jest",
6
6
  {
7
- tsconfig: "tsconfig.spec.json",
7
+ jsc: {
8
+ target: "es2019",
9
+ },
8
10
  },
9
11
  ],
10
12
  },
13
+ coverageProvider: "v8",
11
14
  testMatch: ["/**/src/**/*.spec.(ts|js)"],
12
15
  testPathIgnorePatterns: ["/node_modules/", "/dist/"],
13
16
  testEnvironment: "node",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devopsplaybook.io/common-utils",
3
- "version": "1.9.2",
3
+ "version": "1.10.0-beta.22.53149f9",
4
4
  "description": "Shared utility modules for devopsplaybook.io projects (DB, Config, OTel context, auth/users, notifications, LLM, system helpers)",
5
5
  "keywords": [
6
6
  "Open Telemetry",
@@ -21,8 +21,8 @@
21
21
  "main": "dist/index.js",
22
22
  "types": "dist/index.d.ts",
23
23
  "scripts": {
24
- "build": "tsc",
25
- "lint": "eslint src",
24
+ "build": "tsc && tsc -p tsconfig.spec.json --noEmit",
25
+ "lint": "oxlint src",
26
26
  "test": "jest --coverage"
27
27
  },
28
28
  "dependencies": {
@@ -39,7 +39,8 @@
39
39
  "uuid": "^14.0.2"
40
40
  },
41
41
  "devDependencies": {
42
- "@eslint/js": "^10.0.1",
42
+ "@swc/core": "^1.16.2",
43
+ "@swc/jest": "^0.2.39",
43
44
  "@types/bcrypt": "^6.0.0",
44
45
  "@types/better-sqlite3": "^9.6.0",
45
46
  "@types/fs-extra": "^11.0.4",
@@ -48,12 +49,9 @@
48
49
  "@types/node": "^26.6.2",
49
50
  "@types/pg": "^8.23.1",
50
51
  "@types/uuid": "^11.0.0",
51
- "eslint": "^10.11.0",
52
52
  "jest": "^30.5.2",
53
- "ts-jest": "^29.4.12",
54
- "ts-node": "^10.9.2",
55
- "typescript": "^6.0.3",
56
- "typescript-eslint": "^8.70.0"
53
+ "oxlint": "^1.83.0",
54
+ "typescript": "^7.0.2"
57
55
  },
58
56
  "publishConfig": {
59
57
  "access": "public"
package/src/ConfigBase.ts CHANGED
@@ -59,7 +59,6 @@ export interface ConfigCommonInterface
59
59
  * array → JSON.parse, etc.). When the default is already a string or
60
60
  * there is no default, the original string is returned as-is.
61
61
  */
62
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
62
  function coerceValue(value: string, defaultValue: any): any {
64
63
  if (defaultValue === undefined || defaultValue === null) {
65
64
  return value;
@@ -155,7 +154,6 @@ export abstract class ConfigBase implements ConfigCommonInterface {
155
154
  field: string;
156
155
  sensitive: boolean;
157
156
  envAliases: string[];
158
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
159
157
  defaultValue: any;
160
158
  }[] = [];
161
159
 
@@ -173,7 +171,7 @@ export abstract class ConfigBase implements ConfigCommonInterface {
173
171
  if (pkg && pkg.version) {
174
172
  this.VERSION = pkg.version;
175
173
  }
176
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
174
+ // eslint-disable-next-line no-unused-vars -- catch binding kept so dist/ stays byte-identical to the TS6 build
177
175
  } catch (_e) {
178
176
  // fallback to "1"
179
177
  }
@@ -224,7 +222,6 @@ export abstract class ConfigBase implements ConfigCommonInterface {
224
222
  field: def.field,
225
223
  sensitive: def.sensitive ?? false,
226
224
  envAliases: def.envAliases ?? [],
227
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
228
225
  defaultValue: (this as any)[def.field],
229
226
  });
230
227
  }
@@ -237,12 +234,11 @@ export abstract class ConfigBase implements ConfigCommonInterface {
237
234
  * When omitted nothing is logged (useful in tests).
238
235
  */
239
236
  public async reload(logger?: (message: string) => void): Promise<void> {
240
- // eslint-disable-next-line @typescript-eslint/no-empty-function
241
237
  const log = logger ?? (() => {});
242
238
  let content: Record<string, unknown> = {};
243
239
  try {
244
240
  content = await fse.readJson(this.CONFIG_FILE);
245
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
241
+ // eslint-disable-next-line no-unused-vars -- catch binding kept so dist/ stays byte-identical to the TS6 build
246
242
  } catch (_e) {
247
243
  // config file is optional – fall back to env + defaults
248
244
  }
@@ -277,14 +273,12 @@ export abstract class ConfigBase implements ConfigCommonInterface {
277
273
  // 3. Apply environment value (full name or alias) if found,
278
274
  // coercing strings to match the default value type
279
275
  if (foundValue !== undefined) {
280
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
281
276
  (this as any)[field] = coerceValue(foundValue, defaultValue);
282
277
  }
283
278
 
284
279
  // 4. Config file override (environment always wins, but if neither
285
280
  // environment nor alias matched, check config file)
286
281
  if (foundValue === undefined && content[field] !== undefined) {
287
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
288
282
  (this as any)[field] = content[field];
289
283
  from = "config";
290
284
  }
@@ -295,7 +289,6 @@ export abstract class ConfigBase implements ConfigCommonInterface {
295
289
  );
296
290
  } else {
297
291
  log(
298
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
299
292
  `Configuration Value: ${field}: ${(this as any)[field]} (from ${from}${usedAlias ? ` via alias` : ""})`,
300
293
  );
301
294
  }
package/src/DbUtils.ts CHANGED
@@ -53,7 +53,6 @@ export async function DbUtilsInit(
53
53
  * - SQLite: `better-sqlite3` `Database` instance
54
54
  * - Postgres: `pg` `Pool` instance
55
55
  */
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
56
  export function DbUtilsGetDatabase(): any {
58
57
  if (databaseType === "postgres") {
59
58
  return PostgresDbUtils.PostgresDbUtilsGetPool();
@@ -99,7 +98,6 @@ export function DbUtilsQuerySQL(
99
98
  sql: string,
100
99
  params: unknown[] = [],
101
100
  debug = false,
102
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
101
  ): any[] | Promise<any[]> {
104
102
  if (databaseType === "postgres") {
105
103
  return PostgresDbUtils.PostgresDbUtilsQuerySQL(
@@ -4,7 +4,6 @@ import {
4
4
  DbUtilsNoTelemetryQuerySQL,
5
5
  } from "./DbUtilsNoTelemetry";
6
6
 
7
- /* eslint-disable @typescript-eslint/no-unsafe-function-type */
8
7
 
9
8
  // Shared mock DB handle – defined BEFORE jest.mock factory so it's hoisted correctly.
10
9
  // We use jest.fn() at module scope; the mock factory captures the same reference.
@@ -38,11 +37,9 @@ beforeAll(() => {
38
37
  error: jest.fn(),
39
38
  info: jest.fn(),
40
39
  warn: jest.fn(),
41
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
40
  } as any;
43
41
  DbUtilsNoTelemetryModule.DbUtilsNoTelemetrySetLogger({
44
42
  createModuleLogger: () => mockLogger,
45
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
43
  } as any);
47
44
  });
48
45
 
@@ -62,7 +59,6 @@ describe("DbUtilsNoTelemetryBatchInsert", () => {
62
59
  mockPrepare.mockReturnValue({
63
60
  run: jest.fn().mockReturnValue({ changes: 2 }),
64
61
  all: jest.fn(),
65
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
66
62
  } as any);
67
63
 
68
64
  const rows = [
@@ -83,7 +79,6 @@ describe("DbUtilsNoTelemetryExecSQL (sqlite)", () => {
83
79
  mockPrepare.mockReturnValue({
84
80
  run: jest.fn().mockReturnValue({ changes: 3 }),
85
81
  all: jest.fn(),
86
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
87
82
  } as any);
88
83
 
89
84
  const result = DbUtilsNoTelemetryExecSQL("INSERT INTO t (c) VALUES (?)", [
@@ -135,7 +130,6 @@ describe("DbUtilsNoTelemetryQuerySQL (sqlite)", () => {
135
130
  mockPrepare.mockReturnValue({
136
131
  run: jest.fn(),
137
132
  all: jest.fn().mockReturnValue(expectedRows),
138
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
133
  } as any);
140
134
 
141
135
  const result = DbUtilsNoTelemetryQuerySQL("SELECT * FROM t");
@@ -24,7 +24,6 @@ export function DbUtilsNoTelemetrySetLogger(loggerIn: StandardLogger): void {
24
24
  export function DbUtilsNoTelemetryBatchInsert(
25
25
  tableCols: string,
26
26
  numCols: number,
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
27
  rows: any[][],
29
28
  ): number | Promise<number> {
30
29
  if (rows.length === 0) return 0;
@@ -50,7 +49,6 @@ export function DbUtilsNoTelemetryExecSQL(
50
49
  if (dbType === "postgres") {
51
50
  const pgSql = convertToPostgresPlaceholders(sql);
52
51
  return new Promise((resolve, reject) => {
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
52
  (DbUtilsGetDatabase() as any).query(
55
53
  pgSql,
56
54
  params,
@@ -87,7 +85,6 @@ export function DbUtilsNoTelemetryQuerySQL(
87
85
  sql: string,
88
86
  params: unknown[] = [],
89
87
  debug = false,
90
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
88
  ): any[] | Promise<any[]> {
92
89
  if (debug) {
93
90
  console.log(sql);
@@ -96,7 +93,6 @@ export function DbUtilsNoTelemetryQuerySQL(
96
93
  if (dbType === "postgres") {
97
94
  const pgSql = convertToPostgresPlaceholders(sql);
98
95
  return new Promise((resolve, reject) => {
99
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
96
  (DbUtilsGetDatabase() as any).query(
101
97
  pgSql,
102
98
  params,
package/src/LLM.ts CHANGED
@@ -159,7 +159,6 @@ export class LLMClient {
159
159
  }
160
160
 
161
161
  const model = options?.model || this.model;
162
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
163
162
  const body: Record<string, any> = {
164
163
  model,
165
164
  messages,
@@ -195,7 +194,6 @@ export class LLMClient {
195
194
  */
196
195
  private extractErrorMessage(err: unknown): string {
197
196
  if (axios.isAxiosError(err)) {
198
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
199
197
  const providerMessage = (err.response?.data as any)?.error?.message;
200
198
  if (providerMessage) {
201
199
  return providerMessage;
@@ -20,7 +20,6 @@ export interface OTelContext {
20
20
  * Retrieves the span previously attached to a request object.
21
21
  * Equivalent to `req.tracerSpanApi`.
22
22
  */
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
23
  OTelRequestSpan: (req: any) => Span | undefined;
25
24
  }
26
25
 
@@ -59,7 +58,6 @@ export function createOTelContext(): OTelContext {
59
58
  }
60
59
  return logger;
61
60
  },
62
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
61
  OTelRequestSpan: (req: any) => req?.tracerSpanApi as Span | undefined,
64
62
  };
65
63
  }
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
 
3
2
  // Mock pg before imports
4
3
  const mockQuery = jest.fn();
@@ -58,7 +57,6 @@ describe("PostgresDbUtils", () => {
58
57
  beforeEach(() => {
59
58
  jest.clearAllMocks();
60
59
  jest.isolateModules(() => {
61
- // eslint-disable-next-line @typescript-eslint/no-require-imports
62
60
  PostgresDbUtils = require("./PostgresDbUtils");
63
61
  });
64
62
  PostgresDbUtils.PostgresDbUtilsSetOTel(
@@ -181,7 +181,6 @@ export class PostgresSchemaDbUtils {
181
181
  execSQL(
182
182
  context: Span,
183
183
  sql: string,
184
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
185
184
  params: any[] = [],
186
185
  useSchemaPool = false,
187
186
  ): Promise<number> {
@@ -257,10 +256,8 @@ export class PostgresSchemaDbUtils {
257
256
  querySQL(
258
257
  context: Span,
259
258
  sql: string,
260
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
261
259
  params: any[] = [],
262
260
  useSchemaPool = false,
263
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
264
261
  ): Promise<any[]> {
265
262
  const span = tracer.startSpan("PostgresSchemaDbUtilsQuerySQL", context);
266
263
  const pool = useSchemaPool ? this.schemaPool : this.runtimePool;
@@ -300,7 +297,6 @@ export class PostgresSchemaDbUtils {
300
297
  */
301
298
  async transaction(
302
299
  context: Span,
303
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
304
300
  callback: (client: any) => Promise<void>,
305
301
  useSchemaPool = false,
306
302
  ): Promise<void> {
@@ -370,7 +366,6 @@ export class PostgresSchemaDbUtils {
370
366
  private execSQLForSchema(
371
367
  context: Span,
372
368
  sql: string,
373
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
374
369
  params: any[] = [],
375
370
  ): Promise<void> {
376
371
  const span = tracer.startSpan(
@@ -383,7 +378,6 @@ export class PostgresSchemaDbUtils {
383
378
  }
384
379
 
385
380
  return new Promise((resolve, reject) => {
386
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
387
381
  this.schemaPool!.query(sql, params, (error: Error | null) => {
388
382
  span.end();
389
383
  if (error) {
@@ -411,11 +405,9 @@ export class PostgresSchemaDbUtils {
411
405
  }
412
406
 
413
407
  return new Promise((resolve, reject) => {
414
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
415
408
  this.schemaPool!.query(sql, (error: Error | null) => {
416
409
  span.end();
417
410
  if (error) {
418
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
419
411
  if ((error as any).code === "ENOENT") {
420
412
  resolve();
421
413
  } else {
@@ -427,7 +419,6 @@ export class PostgresSchemaDbUtils {
427
419
  });
428
420
  });
429
421
  } catch (error) {
430
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
431
422
  if ((error as any).code === "ENOENT") {
432
423
  return;
433
424
  }
@@ -438,9 +429,7 @@ export class PostgresSchemaDbUtils {
438
429
  private querySQLForSchema(
439
430
  context: Span,
440
431
  sql: string,
441
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
442
432
  params: any[] = [],
443
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
444
433
  ): Promise<any[]> {
445
434
  const span = tracer.startSpan(
446
435
  "PostgresSchemaDbUtilsQuerySQLForSchema",
@@ -452,7 +441,6 @@ export class PostgresSchemaDbUtils {
452
441
  }
453
442
 
454
443
  return new Promise((resolve, reject) => {
455
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
456
444
  this.schemaPool!.query(
457
445
  sql,
458
446
  params,
@@ -616,7 +604,6 @@ export function PostgresDbUtilsQuerySQL(
616
604
  sql: string,
617
605
  params: unknown[] = [],
618
606
  debug = false,
619
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
620
607
  ): Promise<any[]> {
621
608
  const span = tracer.startSpan("PostgresDbUtilsQuerySQL", context);
622
609
  if (debug) {
@@ -1,4 +1,3 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
 
3
2
  // Mock dependencies before imports
4
3
  jest.mock("better-sqlite3", () => {
@@ -64,7 +63,6 @@ describe("SqlDbUtils", () => {
64
63
  jest.clearAllMocks();
65
64
  // Re-import to reset module state
66
65
  jest.isolateModules(() => {
67
- // eslint-disable-next-line @typescript-eslint/no-require-imports
68
66
  SqlDbUtils = require("./SqlDbUtils");
69
67
  });
70
68
  SqlDbUtils.SqlDbUtilsSetOTel(mockTracer as any, mockLogger as any);
@@ -77,7 +75,6 @@ describe("SqlDbUtils", () => {
77
75
  });
78
76
 
79
77
  it("SqlDbUtilsExecSQL should call prepare and run", () => {
80
- // eslint-disable-next-line @typescript-eslint/no-require-imports
81
78
  const Database = require("better-sqlite3");
82
79
  const db = new Database("/tmp/test.db");
83
80
  const mockRun = jest.fn().mockReturnValue({ changes: 5 });
package/src/SqlDbUtils.ts CHANGED
@@ -133,7 +133,6 @@ export function SqlDbUtilsQuerySQL(
133
133
  sql: string,
134
134
  params: unknown[] = [],
135
135
  debug = false,
136
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
136
  ): any[] {
138
137
  const span = tracer.startSpan("SqlDbUtilsQuerySQL", context);
139
138
  if (debug) {
package/src/users/Auth.ts CHANGED
@@ -85,7 +85,6 @@ export async function AuthGenerateJWT(user: User): Promise<string> {
85
85
  * mirroring the owning user's live role and scopes is built (valid until
86
86
  * the token is revoked).
87
87
  */
88
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
88
  async function jwtDecodeCached(req: any): Promise<any | null> {
90
89
  if (req._jwtPayload) {
91
90
  return req._jwtPayload;
@@ -115,7 +114,6 @@ async function jwtDecodeCached(req: any): Promise<any | null> {
115
114
  * Permissions are read from the user record at resolution time, so
116
115
  * role/scope changes apply to existing tokens immediately.
117
116
  */
118
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
119
117
  async function resolveApiToken(authorizationHeader: string): Promise<any | null> {
120
118
  const token = authorizationHeader.split(" ")[1];
121
119
  if (!token) {
@@ -124,7 +122,6 @@ async function resolveApiToken(authorizationHeader: string): Promise<any | null>
124
122
  const span = tracer.startSpan("AuthResolveApiToken");
125
123
  const tokenHash = createHash("sha256").update(token).digest("hex");
126
124
  const apiToken = await UsersApiTokensDataGetByTokenHash(span, tokenHash);
127
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
128
125
  let payload: any | null = null;
129
126
  if (apiToken) {
130
127
  const user = await UsersDataGet(span, apiToken.userId);
@@ -142,9 +139,7 @@ async function resolveApiToken(authorizationHeader: string): Promise<any | null>
142
139
  }
143
140
 
144
141
  export async function AuthMustBeAuthenticated(
145
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
142
  req: any,
147
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
143
  res: any,
149
144
  ): Promise<void> {
150
145
  if (!(await jwtDecodeCached(req))) {
@@ -153,7 +148,6 @@ export async function AuthMustBeAuthenticated(
153
148
  }
154
149
  }
155
150
 
156
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
151
  export async function AuthMustBeAdmin(req: any, res: any): Promise<void> {
158
152
  const info = await jwtDecodeCached(req);
159
153
  if (info?.role === "admin") {
@@ -164,9 +158,7 @@ export async function AuthMustBeAdmin(req: any, res: any): Promise<void> {
164
158
  }
165
159
 
166
160
  export async function AuthHasScope(
167
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
161
  req: any,
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
162
  res: any,
171
163
  scope: UserScope,
172
164
  ): Promise<void> {
@@ -186,7 +178,6 @@ export async function AuthHasScope(
186
178
  throw new Error("Access Denied");
187
179
  }
188
180
 
189
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
181
  export async function AuthGetUserSession(req: any): Promise<UserSession> {
191
182
  const userSession: UserSession = { isAuthenticated: false };
192
183
  const info = await jwtDecodeCached(req);
package/src/users/User.ts CHANGED
@@ -19,7 +19,6 @@ export class User {
19
19
  /** Full scope set of the host application, registered via `AuthInit`. */
20
20
  public static ALL_SCOPES: UserScope[] = [];
21
21
 
22
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
22
  public static fromJson(json: any): User | null {
24
23
  if (!json) {
25
24
  return null;
@@ -55,7 +54,6 @@ export class User {
55
54
  this.id = uuidv4();
56
55
  }
57
56
 
58
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
57
  public toJson(): any {
60
58
  return {
61
59
  id: this.id,
@@ -66,7 +64,6 @@ export class User {
66
64
  };
67
65
  }
68
66
 
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
67
  public toTransportJson(): any {
71
68
  return {
72
69
  id: this.id,
@@ -10,7 +10,6 @@ import { v4 as uuidv4 } from "uuid";
10
10
  */
11
11
  export class UserApiToken {
12
12
  //
13
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
13
  public static fromJson(json: any): UserApiToken | null {
15
14
  if (!json) {
16
15
  return null;
@@ -34,7 +33,6 @@ export class UserApiToken {
34
33
  this.id = uuidv4();
35
34
  }
36
35
 
37
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
36
  public toJson(): any {
39
37
  return {
40
38
  id: this.id,
@@ -46,7 +44,6 @@ export class UserApiToken {
46
44
  }
47
45
 
48
46
  // Transport representation: never exposes the token hash.
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
47
  public toTransportJson(): any {
51
48
  return {
52
49
  id: this.id,
@@ -100,7 +100,6 @@ export async function UsersApiTokensDataDeleteByUser(
100
100
 
101
101
  // Private Functions
102
102
 
103
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
104
103
  function fromRaw(tokenRaw: any): UserApiToken {
105
104
  const apiToken = new UserApiToken();
106
105
  apiToken.id = tokenRaw.id;
@@ -109,7 +109,6 @@ export async function UsersDataDelete(
109
109
 
110
110
  // Private Functions
111
111
 
112
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
112
  function fromRaw(userRaw: any): User {
114
113
  const user = new User();
115
114
  user.id = userRaw.id;
@@ -30,7 +30,6 @@ import {
30
30
  * Retrieves the OTel span attached to the request by the
31
31
  * `@devopsplaybook.io/otel-utils-fastify` hooks.
32
32
  */
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
33
  function requestSpan(req: any): Span | undefined {
35
34
  return req?.tracerSpanApi;
36
35
  }
@@ -3,5 +3,6 @@
3
3
  "compilerOptions": {
4
4
  "types": ["jest", "node"]
5
5
  },
6
- "include": ["src/**/*.spec.ts"]
6
+ "include": ["src/**/*.spec.ts"],
7
+ "exclude": []
7
8
  }
package/eslint.config.mjs DELETED
@@ -1,11 +0,0 @@
1
- // @ts-check
2
-
3
- import eslint from "@eslint/js";
4
- import tseslint from "typescript-eslint";
5
-
6
- export default tseslint.config(
7
- { ignores: ["dist/", "node_modules/"] },
8
- eslint.configs.recommended,
9
- ...tseslint.configs.strict,
10
- ...tseslint.configs.stylistic,
11
- );