UNPKG

@syngrisi/syngrisi

Version:
6,557 lines 219 kB
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// src/server/routes/v1/index.route.ts
var index_route_exports = {};
__export(index_route_exports, {
  default: () => index_route_default
});
module.exports = __toCommonJS(index_route_exports);
var import_express15 = __toESM(require("express"));

// src/server/routes/v1/auth.route.ts
var import_express = __toESM(require("express"));
var import_zod_to_openapi3 = require("@asteasolutions/zod-to-openapi");

// src/server/controllers/auth.controller.ts
var import_http_status = __toESM(require("http-status"));
var import_passport = __toESM(require("passport"));
var import_hasha = __toESM(require("hasha"));
var import_uuid_apikey = __toESM(require("uuid-apikey"));

// src/server/models/Check.model.ts
var import_mongoose = __toESM(require("mongoose"));

// src/server/models/plugins/paginate.plugin.ts
var paginate = (schema) => {
  schema.statics.paginate = async function(filter, options) {
    let sort;
    if (options.sortBy) {
      const sortingCriteria = [];
      options.sortBy.split(",").forEach((sortOption) => {
        const [key, order] = sortOption.split(":");
        sortingCriteria.push((order === "desc" ? "-" : "") + key);
      });
      sort = sortingCriteria.join(" ");
    } else {
      sort = { _id: -1 };
    }
    const limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
    const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
    const skip = (page - 1) * limit;
    const countPromise = this.countDocuments(filter).exec();
    let docsPromise = this.find(filter).sort(sort).skip(skip).limit(limit);
    if (options.populate) {
      options.populate.split(",").forEach((populateOption) => {
        docsPromise = docsPromise.populate(
          populateOption.split(".").reverse().reduce((a, b) => ({ path: b, populate: a }))
        );
      });
    }
    docsPromise = docsPromise.exec();
    return Promise.all([countPromise, docsPromise]).then((values) => {
      const [totalResults, results] = values;
      const totalPages = Math.ceil(totalResults / limit);
      const result = {
        results,
        page,
        limit,
        totalPages,
        totalResults,
        timestamp: Number(Date.now() + String(process.hrtime()[1]).slice(3, 6))
      };
      return Promise.resolve(result);
    });
  };
};
var paginate_plugin_default = paginate;

// src/server/models/plugins/toJSON.plugin.ts
var deleteAtPath = (obj, path6, index) => {
  if (index === path6.length - 1) {
    delete obj[path6[index]];
    return;
  }
  deleteAtPath(obj[path6[index]], path6, index + 1);
};
var toJSON = (schema) => {
  let transform;
  if (schema.options.toJSON && schema.options.toJSON.transform) {
    transform = schema.options.toJSON.transform;
  }
  schema.options.toJSON = Object.assign(schema.options.toJSON || {}, {
    transform(doc, ret, options) {
      Object.keys(schema.paths).forEach((path6) => {
        if (schema.paths[path6].options && schema.paths[path6].options.private) {
          deleteAtPath(ret, path6.split("."), 0);
        }
      });
      ret.id = ret._id.toString();
      delete ret.__v;
      delete ret.createdAt;
      delete ret.updatedAt;
      if (transform) {
        return transform(doc, ret, options);
      }
    }
  });
};
var toJSON_plugin_default = toJSON;

// src/server/models/plugins/paginateDistinct.plugin.ts
var import_bson = require("bson");
var paginateDistinct = (schema) => {
  schema.statics.paginateDistinct = async function(filter, options) {
    let sort;
    if (options.sortBy) {
      options.sortBy.split(",").forEach((sortOption) => {
        const [key, order] = sortOption.split(":");
        sort[key] = order === "desc" ? -1 : 1;
      });
    } else {
      sort = { _id: -1 };
    }
    let limit = options.limit && parseInt(options.limit.toString(), 10) >= 0 ? parseInt(options.limit.toString(), 10) : 10;
    limit = limit === 0 ? 9007199254740991 : limit;
    const page = options.page && parseInt(options.page.toString(), 10) > 0 ? parseInt(options.page.toString(), 10) : 1;
    const skip = (page - 1) * limit;
    const groupAggregateObj = { $group: { _id: `$${options.field}` } };
    const documentsCount = (await this.aggregate([groupAggregateObj]).exec()).length;
    const aggregateArr = [
      { $match: import_bson.EJSON.parse(filter.filter || "{}") },
      groupAggregateObj,
      { $sort: sort },
      { $skip: skip },
      { $limit: limit }
    ];
    const aggregatedDocs = (await this.aggregate(aggregateArr)).filter((x) => x._id).map((x) => {
      if (x[options.field]) {
        return x[options.field][0];
      }
      return { name: x._id };
    });
    return Promise.all([documentsCount, aggregatedDocs]).then((values) => {
      const [totalResults, results] = values;
      const totalPages = Math.ceil(totalResults / limit);
      const result = {
        results,
        page,
        limit,
        totalPages,
        totalResults,
        timestamp: (/* @__PURE__ */ new Date()).getTime()
      };
      return Promise.resolve(result);
    });
  };
};
var paginateDistinct_plugin_default = paginateDistinct;

// src/server/models/Check.model.ts
var CheckSchema = new import_mongoose.Schema({
  name: {
    type: String,
    required: [true, 'CheckSchema: The "name" field must be required']
  },
  test: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSTest",
    required: [true, 'CheckSchema: The "test" field must be required']
  },
  suite: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSSuite",
    required: [true, 'CheckSchema: The "suite" field must be required']
  },
  app: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSApp",
    required: [true, 'CheckSchema: The "app" field must be required']
  },
  branch: {
    type: String
  },
  realBaselineId: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSBaseline"
  },
  baselineId: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSSnapshot"
  },
  actualSnapshotId: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSSnapshot"
  },
  diffId: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSSnapshot"
  },
  createdDate: {
    type: Date,
    required: true,
    default: Date.now
  },
  updatedDate: {
    type: Date
  },
  status: {
    type: [{
      type: String,
      enum: {
        values: ["new", "pending", "approved", "running", "passed", "failed", "aborted"],
        message: "status is required"
      }
    }],
    default: ["new"]
  },
  browserName: {
    type: String
  },
  browserVersion: {
    type: String
  },
  browserFullVersion: {
    type: String
  },
  viewport: {
    type: String
  },
  os: {
    type: String
  },
  domDump: {
    type: String
  },
  result: {
    type: String,
    default: "{}"
  },
  run: {
    type: import_mongoose.Schema.Types.ObjectId
  },
  markedAs: {
    type: String,
    enum: ["bug", "accepted"]
  },
  markedDate: {
    type: Date
  },
  markedById: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSUser"
  },
  markedByUsername: {
    type: String
  },
  markedBugComment: {
    type: String
  },
  creatorId: {
    type: import_mongoose.Schema.Types.ObjectId,
    ref: "VRSUser"
  },
  creatorUsername: {
    type: String
  },
  failReasons: {
    type: [String]
  },
  vOffset: {
    type: String
  },
  topStablePixels: {
    type: String
  },
  meta: {
    type: Object
  }
});
CheckSchema.plugin(toJSON_plugin_default);
CheckSchema.plugin(paginate_plugin_default);
var Check = import_mongoose.default.model("VRSCheck", CheckSchema);
var Check_model_default = Check;

// src/server/models/Log.model.ts
var import_mongoose2 = __toESM(require("mongoose"));
var LogSchema = new import_mongoose2.Schema({
  timestamp: {
    type: Date
  },
  level: {
    type: String
  },
  message: {
    type: String
  },
  meta: {
    type: Object
  },
  hostname: {
    type: Object
  }
});
LogSchema.plugin(toJSON_plugin_default);
LogSchema.plugin(paginate_plugin_default);
var Log = import_mongoose2.default.model("VRSLog", LogSchema);
var Log_model_default = Log;

// src/server/models/App.model.ts
var import_mongoose3 = __toESM(require("mongoose"));
var AppSchema = new import_mongoose3.Schema({
  name: {
    type: String,
    default: "Others",
    unique: true,
    required: [true, 'AppSchema: The "name" field must be required']
  },
  description: {
    type: String
  },
  version: {
    type: String
  },
  updatedDate: {
    type: Date
  },
  createdDate: {
    type: Date
  },
  meta: {
    type: Object
  }
});
AppSchema.plugin(paginate_plugin_default);
AppSchema.plugin(toJSON_plugin_default);
var App = import_mongoose3.default.model("VRSApp", AppSchema);
var App_model_default = App;

// src/server/models/Snapshot.model.ts
var import_mongoose4 = __toESM(require("mongoose"));
var SnapshotSchema = new import_mongoose4.Schema({
  name: {
    type: String,
    required: [true, 'SnapshotSchema: The "name" field must be required']
  },
  path: {
    type: String
  },
  filename: {
    type: String
  },
  imghash: {
    type: String,
    required: [true, 'SnapshotSchema: The "imghash" field must be required']
  },
  createdDate: {
    type: Date,
    default: Date.now
  },
  vOffset: {
    type: Number
  },
  hOffset: {
    type: Number
  }
});
SnapshotSchema.plugin(toJSON_plugin_default);
SnapshotSchema.plugin(paginate_plugin_default);
var Snapshot = import_mongoose4.default.model("VRSSnapshot", SnapshotSchema);
var Snapshot_model_default = Snapshot;

// src/server/models/AppSettings.model.ts
var import_mongoose5 = __toESM(require("mongoose"));
var AppSettingsSchema = new import_mongoose5.Schema({
  name: {
    type: String,
    unique: true,
    required: [true, 'AppSettingsSchema: The "name" field must be required']
  },
  label: {
    type: String,
    required: [true, 'AppSettingsSchema: The "label" field must be required']
  },
  description: {
    type: String
  },
  type: {
    type: String,
    required: [true, 'AppSettingsSchema: The "type" field must be required']
  },
  value: {
    type: import_mongoose5.Schema.Types.Mixed,
    required: [true, 'AppSettingsSchema: The "value" field must be required']
  },
  env_variable: {
    type: String
  },
  enabled: {
    type: Boolean
  }
});
AppSettingsSchema.plugin(toJSON_plugin_default);
var AppSettings = import_mongoose5.default.model("VRSAppSettings", AppSettingsSchema);
var AppSettings_model_default = AppSettings;

// src/server/models/Suite.model.ts
var import_mongoose6 = __toESM(require("mongoose"));
var SuiteSchema = new import_mongoose6.Schema({
  name: {
    type: String,
    default: "Others",
    unique: true,
    required: [true, 'SuiteSchema: The "name" field must be required']
  },
  tags: {
    type: [String]
  },
  app: {
    type: import_mongoose6.Schema.Types.ObjectId,
    ref: "VRSApp",
    required: [true, 'SuiteSchema: The "app" field must be required']
  },
  description: {
    type: String
  },
  updatedDate: {
    type: Date,
    default: Date.now
  },
  createdDate: {
    type: Date
  },
  meta: {
    type: Object
  }
});
SuiteSchema.plugin(paginate_plugin_default);
SuiteSchema.plugin(toJSON_plugin_default);
var Suite = import_mongoose6.default.model("VRSSuite", SuiteSchema);
var Suite_model_default = Suite;

// src/server/models/Run.model.ts
var import_mongoose7 = __toESM(require("mongoose"));
var RunSchema = new import_mongoose7.Schema({
  name: {
    type: String,
    required: [true, 'RunSchema: The "name" field must be required']
  },
  app: {
    type: import_mongoose7.Schema.Types.ObjectId,
    ref: "VRSApp",
    required: [true, 'RunSchema: The "app" field must be required']
  },
  ident: {
    type: String,
    unique: true,
    required: [true, 'RunSchema: The "ident" field must be required']
  },
  description: {
    type: String
  },
  updatedDate: {
    type: Date,
    default: Date.now
  },
  createdDate: {
    type: Date
  },
  parameters: {
    type: [String]
  },
  meta: {
    type: Object
  }
});
RunSchema.plugin(paginate_plugin_default);
RunSchema.plugin(toJSON_plugin_default);
var Run = import_mongoose7.default.model("VRSRun", RunSchema);
var Run_model_default = Run;

// src/server/models/User.model.ts
var import_mongoose8 = __toESM(require("mongoose"));
var import_passport_local_mongoose = __toESM(require("passport-local-mongoose"));
var UserSchema = new import_mongoose8.Schema({
  username: {
    type: String,
    unique: true,
    required: [true, 'UserSchema: The "username" field must be required']
  },
  firstName: {
    type: String,
    required: [true, 'UserSchema: The "firstName" field must be required']
  },
  lastName: {
    type: String,
    required: [true, 'UserSchema: The "lastName" field must be required']
  },
  role: {
    type: String,
    enum: ["admin", "reviewer", "user"],
    required: [true, 'UserSchema: The "role" field must be required']
  },
  password: {
    type: String
  },
  token: {
    type: String
  },
  apiKey: {
    type: String
  },
  createdDate: {
    type: Date
  },
  updatedDate: {
    type: Date
  },
  expiration: {
    type: Date
  },
  meta: {
    type: Object
  }
});
UserSchema.statics.isEmailTaken = async function(username, excludeUserId) {
  const user = await this.findOne({ username, _id: { $ne: excludeUserId } });
  return !!user;
};
UserSchema.plugin(toJSON_plugin_default);
UserSchema.plugin(paginate_plugin_default);
UserSchema.plugin(import_passport_local_mongoose.default, { hashField: "password" });
var User = import_mongoose8.default.model("VRSUser", UserSchema);
var User_model_default = User;

// src/server/models/Baseline.model.ts
var import_mongoose9 = __toESM(require("mongoose"));
var BaselineSchema = new import_mongoose9.Schema({
  snapshootId: {
    type: import_mongoose9.Schema.Types.ObjectId
  },
  name: {
    type: String,
    required: [true, 'VRSBaselineSchema: The "name" field must be required']
  },
  app: {
    type: import_mongoose9.Schema.Types.ObjectId,
    ref: "VRSApp",
    required: [true, 'VRSBaselineSchema: The "app" field must be required']
  },
  branch: {
    type: String
  },
  browserName: {
    type: String
  },
  browserVersion: {
    type: String
  },
  browserFullVersion: {
    type: String
  },
  viewport: {
    type: String
  },
  os: {
    type: String
  },
  markedAs: {
    type: String,
    enum: ["bug", "accepted"]
  },
  lastMarkedDate: {
    type: Date
  },
  createdDate: {
    type: Date
  },
  updatedDate: {
    type: Date
  },
  markedById: {
    type: import_mongoose9.Schema.Types.ObjectId,
    ref: "VRSUser"
  },
  markedByUsername: {
    type: String
  },
  ignoreRegions: {
    type: String
  },
  boundRegions: {
    type: String
  },
  matchType: {
    type: String,
    enum: ["antialiasing", "nothing", "colors"]
  },
  meta: {
    type: Object
  }
});
BaselineSchema.plugin(toJSON_plugin_default);
BaselineSchema.plugin(paginate_plugin_default);
var Baseline = import_mongoose9.default.model("VRSBaseline", BaselineSchema);
var Baseline_model_default = Baseline;

// src/server/models/Test.model.ts
var import_mongoose10 = __toESM(require("mongoose"));
var TestSchema = new import_mongoose10.Schema(
  {
    name: {
      type: String,
      required: "TestSchema: the test name is empty"
    },
    description: {
      type: String
    },
    status: {
      type: String
    },
    browserName: {
      type: String
    },
    browserVersion: {
      type: String
    },
    branch: {
      type: String
    },
    tags: {
      type: [String]
    },
    viewport: {
      type: String
    },
    calculatedViewport: {
      type: String
    },
    os: {
      type: String
    },
    app: {
      type: import_mongoose10.Schema.Types.ObjectId,
      ref: "VRSApp",
      required: [true, 'TestSchema: The "app" field must be required']
    },
    blinking: {
      type: Number,
      default: 0
    },
    updatedDate: {
      type: Date
    },
    startDate: {
      type: Date
    },
    checks: [
      {
        type: import_mongoose10.default.Schema.Types.ObjectId,
        ref: "VRSCheck"
      }
    ],
    suite: {
      type: import_mongoose10.Schema.Types.ObjectId,
      ref: "VRSSuite"
    },
    run: {
      type: import_mongoose10.Schema.Types.ObjectId,
      ref: "VRSRun"
    },
    markedAs: {
      type: String,
      enum: ["Bug", "Accepted", "Unaccepted", "Partially"]
    },
    creatorId: {
      type: import_mongoose10.Schema.Types.ObjectId,
      ref: "VRSUser"
    },
    creatorUsername: {
      type: String
    },
    meta: {
      type: Object
    }
  },
  { strictQuery: true }
);
TestSchema.plugin(toJSON_plugin_default);
TestSchema.plugin(paginate_plugin_default);
TestSchema.plugin(paginateDistinct_plugin_default);
var Test = import_mongoose10.default.model("VRSTest", TestSchema);
var Test_model_default = Test;

// src/server/utils/pick.ts
var pick = (object, keys) => {
  return keys.reduce((obj, key) => {
    if (object && Object.prototype.hasOwnProperty.call(object, key)) {
      if (object[key] !== void 0) obj[key] = object[key];
    }
    return obj;
  }, {});
};
var pick_default = pick;

// src/server/utils/isJSON.ts
var isJSON = (text) => {
  if (!text) return false;
  const isValid = /^[\],:{}\s]*$/.test(
    text.replace(/\\["\\\/bfnrtu]/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, "")
  );
  return isValid;
};
var isJSON_default = isJSON;

// src/server/utils/catchAsync.ts
var catchAsync = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch((err) => {
    return next(err);
  });
};
var catchAsync_default = catchAsync;

// src/server/utils/dateToISO8601.ts
var dateToISO8601 = (date) => {
  return new Date(new Date(date)).toISOString().split("T")[0];
};
var dateToISO8601_default = dateToISO8601;

// src/server/utils/ProgressBar.ts
var ProgressBar = class {
  constructor(length) {
    this.length = length;
    this.percentLenght = parseFloat((length / 100).toString());
    this.prevPercent = 0;
    this.currentPercent = 0;
    this.progressString = "";
  }
  isChange(current2) {
    this.currentPercent = parseInt((current2 / this.percentLenght).toString(), 10);
    if (this.prevPercent === this.currentPercent) {
      return false;
    }
    this.prevPercent = this.currentPercent;
    this.progressString += "#";
    return true;
  }
  writeIfChange(index, count, fn, res) {
    if (this.isChange(index)) {
      const placeholderString = Array.from(new Array(99 - this.currentPercent)).reduce((accum) => accum += ".", "");
      fn(`[${this.progressString}${placeholderString}](${index}/${count})`, res);
    }
  }
};

// src/server/utils/ApiError.ts
var ApiError = class extends Error {
  constructor(statusCode, message, isOperational = true, stack = "") {
    super(message);
    this.statusCode = statusCode;
    this.isOperational = isOperational;
    if (stack) {
      this.stack = stack;
    } else {
      Error.captureStackTrace(this, this.constructor);
    }
  }
};
var ApiError_default = ApiError;

// src/server/utils/removeEmptyProperties.ts
var removeEmptyProperties = (obj) => Object.fromEntries(
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  Object.entries(obj).filter(([_, v]) => v != null && v !== "")
);

// src/server/utils/deserializeIfJSON.ts
var import_bson2 = require("bson");
var deserializeIfJSON = (text) => {
  if (isJSON_default(text)) return import_bson2.EJSON.parse(text) || void 0;
  return text;
};
var deserializeIfJSON_default = deserializeIfJSON;

// src/server/utils/prettyCheckParams.ts
var prettyCheckParams = (result) => {
  if (!result.domDump) {
    return JSON.stringify(result);
  }
  const dump = JSON.parse(result.domDump);
  const resObs = { ...result };
  delete resObs.domDump;
  resObs.domDump = `${JSON.stringify(dump).substr(0, 20)}... and about ${dump.length} items]`;
  return JSON.stringify(resObs);
};
var prettyCheckParams_default = prettyCheckParams;

// src/server/utils/waitUntil.ts
var waitUntil = async (cb, attempts = 5, interval = 700) => {
  let result = false;
  let iteration = 0;
  while (result === false) {
    result = await cb();
    await new Promise((r) => setTimeout(r, interval));
    iteration += 1;
    if (iteration > attempts) {
      result = true;
    }
  }
  return result;
};

// src/server/utils/paramsGuard.ts
var paramsGuard = (params, functionName, schema) => {
  const result = schema.safeParse(params);
  if (result.success) {
    return true;
  } else {
    const errorDetails = result.error.format();
    throw new Error(`
        Invalid '${functionName}' parameters: ${JSON.stringify(errorDetails)}
        
 error: ${result.error.stack || result.error}
        
 params: ${JSON.stringify(params, null, 2)}
        `);
  }
};

// src/server/utils/ident.ts
var ident = ["name", "viewport", "browserName", "os", "app", "branch"];

// src/server/utils/buildIdentObject.ts
var MissingIdentFieldError = class extends Error {
  constructor(field) {
    super(`Missing required ident field: ${field}`);
    this.name = "MissingIdentFieldError";
  }
};
var buildIdentObject = (params) => {
  const result = {};
  for (const key of ident) {
    if (key in params && params[key] !== void 0) {
      result[key] = params[key];
    } else {
      throw new MissingIdentFieldError(key);
    }
  }
  return result;
};

// src/server/utils/calculateAcceptedStatus.ts
var calculateAcceptedStatus = async function calculateAcceptedStatus2(testId) {
  const checksInTest = await Check_model_default.find({ test: testId });
  const statuses = checksInTest.map((x) => x.markedAs);
  if (statuses.length < 1) {
    return "Unaccepted";
  }
  let testCalculatedStatus = "Unaccepted";
  if (statuses.some((x) => x === "accepted")) {
    testCalculatedStatus = "Partially";
  }
  if (statuses.every((x) => x === "accepted")) {
    testCalculatedStatus = "Accepted";
  }
  return testCalculatedStatus;
};

// src/server/utils/subDays.ts
var subDays = (date, days) => {
  const result = new Date(date);
  result.setDate(result.getDate() - days);
  return result;
};
var subDays_default = subDays;

// src/server/utils/errMsg.ts
var errMsg = (e) => {
  return String(e instanceof Error ? e.stack : e);
};

// src/server/lib/logger.ts
var import_winston = __toESM(require("winston"));
var import_winston_mongodb = require("winston-mongodb");
var import_chalk = require("chalk");

// src/server/utils/formatISOToDateTime.ts
function formatISOToDateTime(isoDateString) {
  const date = new Date(isoDateString);
  return `${date.toISOString().slice(0, 10)} ${date.toTimeString().slice(0, 8)}`;
}
var formatISOToDateTime_default = formatISOToDateTime;

// src/server/config.ts
var import_fs = __toESM(require("fs"));
var import_dotenv2 = __toESM(require("dotenv"));

// package.json
var version = "2.2.26-alpha.0";

// src/server/config.ts
var import_crypto2 = __toESM(require("crypto"));

// src/server/envConfig.ts
var import_envalid = require("envalid");
var import_crypto = __toESM(require("crypto"));
var import_path = __toESM(require("path"));
var import_dotenv = __toESM(require("dotenv"));
import_dotenv.default.config();
if (!process.env.NODE_ENV) {
  process.env.NODE_ENV = "production";
}
var env = (0, import_envalid.cleanEnv)(process.env, {
  NODE_ENV: (0, import_envalid.str)({ choices: ["development", "production", "test"] }),
  SYNGRISI_DB_URI: (0, import_envalid.str)({ default: "mongodb://127.0.0.1:27017/SyngrisiDb" }),
  SYNGRISI_APP_PORT: (0, import_envalid.port)({ default: 3e3 }),
  SYNGRISI_IMAGES_PATH: (0, import_envalid.str)({ default: import_path.default.join(process.cwd(), "./.snapshots-images") }),
  SYNGRISI_TMP_DIR: (0, import_envalid.str)({ default: import_path.default.join(process.cwd(), ".tmp") }),
  SYNGRISI_HTTP_LOG: (0, import_envalid.bool)({ default: false }),
  SYNGRISI_COVERAGE: (0, import_envalid.bool)({ default: false }),
  SYNGRISI_HOSTNAME: (0, import_envalid.host)({ default: "localhost" }),
  SYNGRISI_AUTH: (0, import_envalid.bool)({ default: true }),
  SYNGRISI_TEST_MODE: (0, import_envalid.bool)({ default: false }),
  SYNGRISI_DISABLE_FIRST_RUN: (0, import_envalid.bool)({ default: false }),
  MONGODB_ROOT_USERNAME: (0, import_envalid.str)({ default: "" }),
  MONGODB_ROOT_PASSWORD: (0, import_envalid.str)({ default: "" }),
  LOGLEVEL: (0, import_envalid.str)({ choices: ["error", "warn", "info", "verbose", "debug", "silly"], default: "debug" }),
  SYNGRISI_PAGINATION_SIZE: (0, import_envalid.num)({ default: 50 }),
  SYNGRISI_DISABLE_DEV_CORS: (0, import_envalid.bool)({ default: true, devDefault: true }),
  SYNGRISI_SESSION_STORE_KEY: (0, import_envalid.str)({ default: import_crypto.default.randomBytes(64).toString("hex") }),
  SYNGRISI_LOG_LEVEL: (0, import_envalid.str)({ default: "debug" }),
  // trunk features
  SYNGRISI_TRUNK_FEATURE_AI_SEVERITY: (0, import_envalid.bool)({ default: false }),
  SYNGRISI_AI_KEY: (0, import_envalid.str)({ default: "" }),
  OPENAI_API_BASE_URL: (0, import_envalid.str)({ default: "https://api.openai.com/v1" }),
  OPENAI_API_KEY: (0, import_envalid.str)({ default: "" })
});

// src/server/data/devices.json
var devices_default = [
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 14 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 14 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 14 Plus",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 14",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 12 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 12 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 12 Mini",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPhone 11 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone XS",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 13 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 13 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 13 Mini",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 13",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 11 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 11",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone XS",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 12 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 12 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 12 Mini",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 12",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 11 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPhone 11",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone XS",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone 11 Pro Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone 11 Pro",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone 11",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone XS",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone XS Max",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone XR",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone XR",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone X",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone 8",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone 8",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone 8",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone 8",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone 8 Plus",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone 8 Plus",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone 7",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "10",
    device: "iPhone 7",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPhone 6S",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone 6S",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone 6S Plus",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone 6",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPhone SE 2022",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPhone SE 2020",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPhone SE",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPad Air 4",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPad 9th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPad Pro 12.9 2022",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPad Pro 12.9 2020",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPad Pro 11 2022",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPad 10th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPad Air 5",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPad Pro 12.9 2021",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPad Pro 12.9 2020",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPad Pro 11 2021",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad Pro 12.9 2020",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "16",
    device: "iPad 8th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPad Pro 12.9 2018",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "15",
    device: "iPad Mini 2021",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "14",
    device: "iPad 8th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad Pro 12.9 2018",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad Pro 11 2020",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad Mini 2019",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad Air 2019",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "13",
    device: "iPad 7th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPad Pro 12.9 2018",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPad Pro 11 2018",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPad Mini 2019",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "12",
    device: "iPad Air 2019",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPad Pro 9.7 2016",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPad Pro 12.9 2017",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPad Mini 4",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPad 6th",
    realMobile: true
  },
  {
    os: "ios",
    os_version: "11",
    device: "iPad 5th",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Samsung Galaxy S22 Ultra",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Samsung Galaxy S22 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Samsung Galaxy S22",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Samsung Galaxy S21",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy S21 Ultra",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy S21",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy S21 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy S20",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy S20 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy S20 Ultra",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy M52",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy M32",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy A52",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy Note 20 Ultra",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy Note 20",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy A51",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy A11",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy S9 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy S10e",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy S10 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy S10",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy Note 10 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy Note 10",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy A10",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.1",
    device: "Samsung Galaxy Note 9",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.1",
    device: "Samsung Galaxy J7 Prime",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.0",
    device: "Samsung Galaxy S9 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.0",
    device: "Samsung Galaxy S9",
    realMobile: true
  },
  {
    os: "android",
    os_version: "7.1",
    device: "Samsung Galaxy Note 8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "7.1",
    device: "Samsung Galaxy A8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "7.0",
    device: "Samsung Galaxy S8 Plus",
    realMobile: true
  },
  {
    os: "android",
    os_version: "7.0",
    device: "Samsung Galaxy S8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "6.0",
    device: "Samsung Galaxy S7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "5.0",
    device: "Samsung Galaxy S6",
    realMobile: true
  },
  {
    os: "android",
    os_version: "13.0",
    device: "Google Pixel 7 Pro",
    realMobile: true
  },
  {
    os: "android",
    os_version: "13.0",
    device: "Google Pixel 7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "13.0",
    device: "Google Pixel 6 Pro",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Google Pixel 6 Pro",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Google Pixel 6",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Google Pixel 5",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Google Pixel 5",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Google Pixel 4",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Google Pixel 4 XL",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Google Pixel 4",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Google Pixel 3",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Google Pixel 3a XL",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Google Pixel 3a",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Google Pixel 3 XL",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Google Pixel 3",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Google Pixel 2",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.0",
    device: "Google Pixel 2",
    realMobile: true
  },
  {
    os: "android",
    os_version: "7.1",
    device: "Google Pixel",
    realMobile: true
  },
  {
    os: "android",
    os_version: "6.0",
    device: "Google Nexus 6",
    realMobile: true
  },
  {
    os: "android",
    os_version: "4.4",
    device: "Google Nexus 5",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "OnePlus 9",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "OnePlus 8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "OnePlus 7T",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "OnePlus 7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "OnePlus 6T",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Xiaomi Redmi Note 11",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Xiaomi Redmi Note 9",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Xiaomi Redmi Note 8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Xiaomi Redmi Note 7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Vivo Y21",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Vivo V21",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Vivo Y50",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Oppo Reno 6",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Oppo A96",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Oppo Reno 3 Pro",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Motorola Moto G71 5G",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Motorola Moto G9 Play",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Motorola Moto G7 Play",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Huawei P30",
    realMobile: true
  },
  {
    os: "android",
    os_version: "12.0",
    device: "Samsung Galaxy Tab S8",
    realMobile: true
  },
  {
    os: "android",
    os_version: "11.0",
    device: "Samsung Galaxy Tab S7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "10.0",
    device: "Samsung Galaxy Tab S7",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy Tab S6",
    realMobile: true
  },
  {
    os: "android",
    os_version: "9.0",
    device: "Samsung Galaxy Tab S5e",
    realMobile: true
  },
  {
    os: "android",
    os_version: "8.1",
    device: "Samsung Galaxy Tab S4",
    realMobile: true
  }
];

// src/server/config.ts
var customDevicesPath = "./server/data/custom_devices.json";
var logsFolder = "./logs";
import_dotenv2.default.config();
var config = {
  version,
  // this isn't used
  getDevices: async () => {
    if (import_fs.default.existsSync(customDevicesPath)) {
      return [...devices_default, ...(await import(customDevicesPath)).default];
    }
    return devices_default;
  },
  defaultImagesPath: env.SYNGRISI_IMAGES_PATH,
  connectionString: env.SYNGRISI_DB_URI || "mongodb://127.0.0.1:27017/SyngrisiDb",
  host: env.SYNGRISI_HOSTNAME,
  port: env.SYNGRISI_APP_PORT || 3e3,
  backupsFolder: "./backups",
  enableHttpLogger: env.SYNGRISI_HTTP_LOG,
  httpLoggerFilePath: `${logsFolder}/http.log`,
  storeSessionKey: env.SYNGRISI_SESSION_STORE_KEY || import_crypto2.default.randomBytes(64).toString("hex"),
  codeCoverage: env.SYNGRISI_COVERAGE,
  disableCors: env.SYNGRISI_DISABLE_DEV_CORS,
  fileUploadMaxSize: 50 * 1024 * 1024,
  testMode: env.SYNGRISI_TEST_MODE,
  jsonLimit: "50mb",
  tmpDir: env.SYNGRISI_TMP_DIR,
  helmet: {
    crossOriginEmbedderPolicy: false,
    crossOriginResourcePolicy: false,
    crossOriginOpenerPolicy: false,
    contentSecurityPolicy: {
      directives: {
        // frameAncestors: ["'self'", "vscode-webview:", "vscode-resource:",  "https:", "http:"],
        // frameSrc: ["'self'", "vscode-webview:", "https:", "http:"],
        // scriptSrc: ["'self'", "'unsafe-inline'"],
        // styleSrc: ["'self'", "'unsafe-inline'"]
        defaultSrc: ["'self'", "*", "'unsafe-inline'", "'unsafe-eval'", "data:", "blob:"],
        frameAncestors: ["'self'", "*"],
        frameSrc: ["'self'", "*"],
        scriptSrc: ["'self'", "*", "'unsafe-inline'", "'unsafe-eval'"],
        styleSrc: ["'self'", "*", "'unsafe-inline'"],
        imgSrc: ["'self'", "*", "data:", "blob:"],
        fontSrc: ["'self'", "*", "data:"],
        connectSrc: ["'self'", "*"]
      }
    }
  }
};
if (!import_fs.default.existsSync(config.defaultImagesPath)) {
  import_fs.default.mkdirSync(config.defaultImagesPath, { recursive: true });
}
if (!import_fs.default.existsSync(logsFolder)) {
  import_fs.default.mkdirSync(logsFolder, { recursive: true });
}

// src/server/lib/logger.ts
var import_path2 = __toESM(require("path"));
var logLevel = env.SYNGRISI_LOG_LEVEL;
function getScriptLine() {
  const stack = new Error().stack;
  if (stack) {
    const stackLines = stack.split("\n");
    let loggerLineIndex = -1;
    for (let i = 0; i < stackLines.length; i++) {
      if (stackLines[i].includes("lib/logger")) {
        loggerLineIndex = i;
      }
    }
    const targetLineIndex = loggerLineIndex + 1;
    if (targetLineIndex >= 0 && targetLineIndex < stackLines.length) {
      const targetLine = stackLines[targetLineIndex];
      const match = targetLine.match(/at\s+(?:.+\s+\()?(.+):(\d+):(\d+)\)?/);
      if (match) {
        const scriptPath = match[1];
        const relativePath = import_path2.default.relative(process.cwd(), scriptPath);
        const lineNumber = match[2];
        return `${relativePath}:${lineNumber}`;
      }
    }
  }
  return "unknown";
}
function createWinstonLogger(opts) {
  return import_winston.default.createLogger({
    transports: [
      new import_winston.default.transports.Console({
        level: logLevel || "silly",
        format: import_winston.default.format.combine(
          import_winston.default.format.colorize(),
          import_winston.default.format.timestamp(),
          import_winston.default.format.ms(),
          import_winston.default.format.metadata(),
          import_winston.default.format.printf((info2) => {
            const user = info2.metadata.user ? (0, import_chalk.blue)(` <${info2.metadata.user}>`) : "";
            const ref = info2.metadata.ref ? (0, import_chalk.gray)(` ${info2.metadata.ref}`) : "";
            const msgType = info2.metadata.msgType ? ` ${info2.metadata.msgType}` : "";
            const itemType = info2.metadata.itemType ? (0, import_chalk.magenta)(` ${info2.metadata.itemType}`) : "";
            const scope = info2.metadata.scope ? (0, import_chalk.magenta)(` [${info2.metadata.scope}] `) : (0, import_chalk.magenta)(` [${getScriptLine()}] `);
            const msg = typeof info2.message === "object" ? `
${JSON.stringify(info2.message, null, 2)}` : info2.message;
            return `${info2.level} ${scope}${formatISOToDateTime_default(info2.metadata.timestamp)} ${info2.metadata.ms}${user}${ref}${msgType}${itemType} '${msg}'`;
          }),
          import_winston.default.format.padLevels()
        )
      }),
      new import_winston.default.transports.MongoDB({
        level: logLevel || "debug",
        format: import_winston.default.format.combine(
          import_winston.default.format.timestamp(),
          import_winston.default.format.json(),
          import_winston.default.format.metadata()
        ),
        options: {
          useUnifiedTopology: true
        },
        db: opts.dbConnectionString,
        collection: "vrslogs"
      })
    ]
  });
}
var Logger = class _Logger {
  constructor(opts = { dbConnectionString: config.connectionString }) {
    this.winstonLogger = createWinstonLogger(opts);
  }
  static mergeMeta(objects) {
    return objects.reduce((acc, obj) => {
      return { ...acc, ...obj };
    }, {});
  }
  log(severity, msg, meta) {
    const mergedMeta = _Logger.mergeMeta(meta);
    if (!mergedMeta.scope) {
      mergedMeta.scope = getScriptLine();
    }
    const formattedMsg = typeof msg === "object" ? JSON.stringify(msg, null, 2) : msg;
    this.winstonLogger.log(severity, formattedMsg, mergedMeta);
  }
  error(msg, ...meta) {
    let message = String(msg);
    let code = 0;
    if (msg instanceof Object) {
      message = JSON.stringify(msg);
    }
    if (msg instanceof Error) {
      message = msg.stack;
    }
    if (msg instanceof ApiError_default) {
      code = msg.statusCode;
    }
    this.log("error", `${code !== 0 ? "[" + code + "]" : ""}${message}
 stacktrace: ${new Error().stack}`, meta);
  }
  warn(msg, ...meta) {
    this.log("warn", `${msg}
 stacktrace: ${new Error().stack}`, meta);
  }
  info(msg, ...meta) {
    this.log("info", msg, meta);
  }
  verbose(msg, ...meta) {
    this.log("verbose", msg, meta);
  }
  debug(msg, ...meta) {
    this.log("debug", msg, meta);
  }
  silly(msg, ...meta) {
    this.log("silly", msg, meta);
  }
};
var logger_default = new Logger();

// src/seeds/initialAppSettings.json
var initialAppSettings_default = [
  {
    name: "first_run",
    label: "First Run",
    description: "Indicates if the application is running the first time",
    type: "Boolean",
    value: "true",
    enabled: true
  },
  {
    name: "authentication",
    label: "Authentication",
    description: "Enable application authentication",
    type: "Boolean",
    value: "false",
    enabled: true
  }
];

// src/server/lib/AppSettings/AppSettings.ts
var AppSettings2 = class {
  constructor() {
    this.model = AppSettings_model_default;
    this.cache = null;
  }
  async init() {
    this.cache = await this.model.find().lean().exec();
    return this;
  }
  ensureInitialized() {
    if (!this.cache) {
      throw new Error("AppSettings is not initialized. Please call init() before using this method.");
    }
  }
  async count() {
    this.ensureInitialized();
    return this.model.countDocuments().exec();
  }
  async loadInitialFromFile() {
    this.ensureInitialized();
    const settings = initialAppSettings_default;
    await this.model.insertMany(settings);
    this.cache = settings;
  }
  async get(name) {
    this.ensureInitialized();
    return this.cache.find((x) => x.name === name) || this.model.findOne({ name }).exec();
  }
  async set(name, value) {
    this.ensureInitialized();
    const item = await this.model.findOneAndUpdate({ name }, { value });
    await item.save();
    const cachedItem = this.cache.find((x) => x.name === name);
    if (cachedItem) {
      cachedItem["value"] = value;
    }
  }
  async enable(name) {
    this.ensureInitialized();
    const item = await this.model.findOneAndUpdate({ name }, { enabled: true });
    await item.save();
    const cachedItem = this.cache.find((x) => x.name === name);
    if (cachedItem) {
      cachedItem["enabled"] = true;
    }
  }
  async disable(name) {
    this.ensureInitialized();
    const item = await this.model.findOneAndUpdate({ name }, { enabled: false });
    await item.save();
    const cachedItem = this.cache.find((x) => x.name === name);
    if (cachedItem) {
      cachedItem["enabled"] = false;
    }
  }
  async isAuthEnabled() {
    this.ensureInitialized();
    return env.SYNGRISI_AUTH || (await this.get("authentication"))?.value === "true";
  }
  async isFirstRun() {
    this.ensureInitialized();
    return (await this.get("first_run"))?.value === "true";
  }
};
var appSettings = new AppSettings2().init();

// src/server/controllers/auth.controller.ts
function getApiKey() {
  return import_uuid_apikey.default.create().apiKey;
}
var apikey = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    user: req?.user?.username || void 0,
    scope: "apikey",
    msgType: "GENERATE_API"
  };
  const apiKey = getApiKey();
  logger_default.debug(
    `generate API Key for user: '${req.user?.username}'`,
    logOpts5
  );
  const hash = (0, import_hasha.default)(apiKey);
  if (!req.user?.username) throw new Error(`Username is empty`);
  const user = await User_model_default.findOne({ username: req.user.username });
  if (!user) throw new Error(`cannot find the user with username: '${req.user.username}'`);
  user.apiKey = hash;
  await user.save();
  res.status(200).json({ apikey: apiKey });
});
var login = catchAsync_default(async (req, res, next) => {
  const logOpts5 = {
    scope: "login",
    msgType: "AUTHENTICATION"
  };
  import_passport.default.authenticate("local", (err, user, info2) => {
    if (err) {
      logger_default.error(`Authentication error: '${err}'`, logOpts5);
      return res.status(import_http_status.default.UNAUTHORIZED).json({ message: "authentication error" });
    }
    if (!user) {
      logger_default.error(`Authentication error: '${info2.message}'`, logOpts5);
      return res.status(import_http_status.default.UNAUTHORIZED).json({ message: `Authentication error: '${info2.message}'` });
    }
    req.logIn(user, (e) => {
      if (e) {
        logger_default.error(e, logOpts5);
        return next(e);
      }
      logger_default.info("user is logged in", { user: user.username });
      return res.status(200).json({ message: "success" });
    });
  })(req, res, next);
});
var logout = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    scope: "logout",
    msgType: "AUTHENTICATION"
  };
  try {
    logger_default.debug(`try to log out user: '${req?.user?.username}'`, logOpts5);
    await req.logout({}, () => res.status(import_http_status.default.OK).json({ message: "success" }));
  } catch (e) {
    logger_default.error(e, logOpts5);
    res.status(import_http_status.default.INTERNAL_SERVER_ERROR).json({ message: "fail" });
  }
});
var changePassword = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    scope: "changePassword",
    msgType: "CHANGE_PASSWORD",
    itemType: "user",
    ref: req?.user?.username
  };
  const { currentPassword, newPassword } = req.body;
  const username = req?.user?.username;
  logger_default.debug(`change password for '${username}', params: '${JSON.stringify(req.body)}'`, logOpts5);
  const user = await User_model_default.findOne({ username });
  if (!user) {
    logger_default.error("user is not logged in", logOpts5);
    return res.status(import_http_status.default.UNAUTHORIZED).json({ message: "user is not logged in" });
  }
  try {
    await user.changePassword(currentPassword, newPassword);
  } catch (e) {
    logger_default.error(e, logOpts5);
    return res.status(import_http_status.default.INTERNAL_SERVER_ERROR).json({ message: errMsg(e) });
  }
  logger_default.debug(`password was successfully changed for user: ${req.user?.username}`, logOpts5);
  return res.status(200).json({ message: "success" });
});
var changePasswordFirstRun = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    scope: "changePasswordFirstRun",
    msgType: "CHANGE_PASSWORD_FIRST_RUN",
    itemType: "user",
    ref: req?.user?.username
  };
  const { newPassword } = req.body;
  const AppSettings3 = await appSettings;
  if (await AppSettings3.isAuthEnabled() && await AppSettings3.isFirstRun()) {
    logger_default.debug(`first run, change password for default 'Administrator', params: '${JSON.stringify(req.body)}'`, logOpts5);
    const user = await User_model_default.findOne({ username: "Administrator" }).exec();
    if (!user) throw new Error(`cannot find the Administrator`);
    logOpts5.ref = String(user?.username);
    await user.setPassword(newPassword);
    await user.save();
    logger_default.debug("password was successfully changed for default Administrator", logOpts5);
    await AppSettings3.set("first_run", false);
    res.status(200).json({ message: "success" });
  } else {
    logger_default.error(`trying to use first run API with no first run state, auth: '${await AppSettings3.isAuthEnabled()}', global settings: '${JSON.stringify(await AppSettings3.get("first_run"))}'`, logOpts5);
    res.status(import_http_status.default.FORBIDDEN).json({ message: "forbidden" });
  }
});

// src/server/utils/validateRequest.ts
var import_http_status2 = __toESM(require("http-status"));
var import_zod = require("zod");

// src/server/utils/ServiceResponse.ts
var ServiceResponse = class {
  constructor(status3, message, responseObject, statusCode) {
    this.success = status3 === 0 /* Success */;
    this.message = message;
    this.responseObject = responseObject;
    this.statusCode = statusCode;
  }
};

// src/server/utils/validateRequest.ts
var logOpts = {
  scope: "validateRequests",
  itemType: "type",
  msgType: "VALIDATION"
};
function getReceivedValueFromRequest(request, path6) {
  let currentValue = request;
  path6.forEach((segment) => {
    currentValue = currentValue[segment];
  });
  return currentValue;
}
var validateRequest = (schema, endpoint = "") => (req, res, next) => {
  try {
    schema.parse({
      body: req.body,
      query: req.query,
      params: req.params
    });
    next();
  } catch (err) {
    if (err instanceof import_zod.ZodError) {
      const errors = err.errors.map((e) => {
        const receivedValue = getReceivedValueFromRequest(
          { body: req.body, query: req.query, params: req.params },
          e.path
        );
        return `
Error path: '${e.path.join(".")}': 
Error ${e.message}, but received ${JSON.stringify(receivedValue)}`;
      }).join(", ");
      const errorMessage = ` ${endpoint ? '\nValidation error in the endpoint: "' + endpoint + '"' : ""}${errors}, 
HTTP PROPERTIES:
	body: ${JSON.stringify(req.body, null, "	")}, 
	query: ${JSON.stringify(req.query, null, "	")}, 
	params: ${JSON.stringify(req.params, null, "	")}`;
      const statusCode = import_http_status2.default.BAD_REQUEST;
      logger_default.error(errorMessage, logOpts);
      res.status(statusCode).send(new ServiceResponse(1 /* Failed */, errorMessage, null, statusCode));
    } else {
      logger_default.error(`Unexpected error: ${errMsg(err)}`, logOpts);
      next(err);
    }
  }
};

// src/server/schemas/Auth.schema.ts
var import_zod_to_openapi2 = require("@asteasolutions/zod-to-openapi");
var import_zod4 = require("zod");

// src/server/schemas/utils/commonValidations.ts
var import_zod3 = require("zod");
var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/common/Version.schema.ts
var import_zod2 = require("zod");
var VersionSchema = import_zod2.z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be in the format "x.y.z"').transform((value) => {
  const parts = value.split(".");
  return {
    major: parseInt(parts[0]),
    minor: parseInt(parts[1]),
    patch: parseInt(parts[2])
  };
});
var Version_schema_default = VersionSchema;

// src/server/schemas/utils/commonValidations.ts
(0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod3.z);
var mongooseIdRegex = /^[0-9a-fA-F]{24}$/;
var id = import_zod3.z.string().regex(mongooseIdRegex, {
  message: "Invalid Mongoose ObjectId format: /^[0-9a-fA-F]{24}$/"
}).openapi({
  description: "baseline ID",
  example: "6bbF35cAB3C59dA969edAe79"
});
var commonValidations = {
  id,
  version: Version_schema_default.openapi({ example: "1.1.2" }),
  positiveNumberString: import_zod3.z.string().refine((value) => {
    const num2 = Number(value);
    return Number.isInteger(num2) && num2 >= 0;
  }, {
    message: "String must be a positive number or 0"
  }),
  password: import_zod3.z.string().min(6).regex(/(?=.*[0-9])/, "Password must include a number").regex(/(?=.*[a-z])/, "Password must include a lowercase letter").regex(/(?=.*[A-Z])/, "Password must include an uppercase letter").refine((value) => {
    return /(?=.*[!@#$%^&*(),.?":{}|<>-])/.test(value);
  }, {
    message: "Password must include a special symbol"
  }).openapi({ example: "Aa1!IJASSNOJ" }),
  username: import_zod3.z.string().min(1).openapi({ example: "john.doe@example.com" }),
  // TODO: workaround TBD
  date: import_zod3.z.string().refine((val) => {
    const date = new Date(val);
    return !isNaN(date.getTime());
  }, {
    message: "Invalid date format"
  }),
  paramsId: { params: import_zod3.z.object({ id }) },
  paramsTestId: { params: import_zod3.z.object({ testid: id }) },
  success: import_zod3.z.object({
    message: import_zod3.z.literal("success")
  })
};

// src/server/schemas/Auth.schema.ts
(0, import_zod_to_openapi2.extendZodWithOpenApi)(import_zod4.z);
var AuthLoginSchema = import_zod4.z.object({
  username: commonValidations.username,
  password: commonValidations.password
});
var AuthLoginSuccessRespSchema = commonValidations.success;
var AuthChangePasswordSchema = import_zod4.z.object({
  currentPassword: commonValidations.password,
  newPassword: commonValidations.password
});
var AuthChangePasswordFirstRunSchema = import_zod4.z.object({
  // currentPassword: commonValidations.password,
  newPassword: commonValidations.password
});
var AuthApiKeyRespSchema = import_zod4.z.object({
  apikey: import_zod4.z.string().regex(/^[A-Z0-9]{7}-[A-Z0-9]{7}-[A-Z0-9]{7}-[A-Z0-9]{7}$/).openapi({ example: "J3QQ400-H7H2V00-2HCH400-M3HK800" })
});
var AuthLogoutRespSchema = commonValidations.success;

// src/server/api-docs/openAPIResponseBuilders.ts
var import_http_status3 = __toESM(require("http-status"));

// src/server/api-docs/serviceResponse.ts
var import_zod5 = require("zod");
var ServiceResponsePaginationSchema = (dataSchema) => import_zod5.z.object({
  results: import_zod5.z.array(dataSchema.optional()),
  page: import_zod5.z.number().openapi({ example: 1 }),
  limit: import_zod5.z.number().openapi({ example: 10 }),
  totalPages: import_zod5.z.number().openapi({ example: 2 }),
  totalResults: import_zod5.z.number().openapi({ example: 12 }),
  timestamp: import_zod5.z.number().openapi({ example: 1718035239731968 })
});

// src/server/api-docs/openAPIResponseBuilders.ts
function createApiResponse(schema, description, statusCode = import_http_status3.default.OK) {
  return {
    [statusCode]: {
      description,
      content: {
        "application/json": {
          schema
        }
      }
    }
  };
}
function createApiEmptyResponse(description, statusCode = import_http_status3.default.OK) {
  return {
    [statusCode]: {
      description
    }
  };
}
function createPaginatedApiResponse(schema, description, statusCode = import_http_status3.default.OK) {
  return {
    [statusCode]: {
      description,
      content: {
        "application/json": {
          schema: ServiceResponsePaginationSchema(schema)
        }
      }
    }
  };
}

// src/server/schemas/SkipValid.schema.ts
var import_zod6 = require("zod");
var SkipValid = import_zod6.z.any();

// src/server/schemas/utils/createRequestBodySchema.ts
var import_zod7 = require("zod");
var createRequestBodySchema = (schema) => import_zod7.z.object({ body: schema });

// src/server/schemas/utils/createRequestOpenApiBodySchema.ts
var createRequestOpenApiBodySchema = (schema) => ({
  content: {
    "application/json": { schema }
  }
});

// src/server/routes/v1/auth.route.ts
var registry = new import_zod_to_openapi3.OpenAPIRegistry();
var router = import_express.default.Router();
registry.registerPath({
  method: "get",
  path: "/v1/auth/logout",
  summary: "Logout the current user.",
  tags: ["Auth"],
  responses: createApiEmptyResponse("Logout success")
});
router.get(
  "/logout",
  validateRequest(SkipValid, "get, /v1/auth/logout"),
  logout
);
registry.registerPath({
  method: "get",
  path: "/v1/auth/apikey",
  summary: "Generate a new API key for the current user.",
  tags: ["Auth"],
  responses: createApiResponse(AuthApiKeyRespSchema, "API Key generated")
});
router.get(
  "/apikey",
  validateRequest(SkipValid, "get, /v1/auth/apikey"),
  apikey
);
registry.registerPath({
  method: "post",
  path: "/v1/auth/login",
  summary: "Login a user with username and password.",
  tags: ["Auth"],
  request: { body: createRequestOpenApiBodySchema(AuthLoginSchema) },
  responses: createApiResponse(AuthLoginSuccessRespSchema, "Login success")
});
router.post(
  "/login",
  validateRequest(createRequestBodySchema(AuthLoginSchema), "post, /v1/auth/login"),
  login
);
registry.registerPath({
  method: "post",
  path: "/v1/auth/change",
  summary: "Change the password for the current user.",
  tags: ["Auth"],
  request: { body: createRequestOpenApiBodySchema(AuthChangePasswordSchema) },
  responses: createApiEmptyResponse("Password changed")
});
router.post(
  "/change",
  validateRequest(createRequestBodySchema(AuthChangePasswordSchema), "post, /v1/auth/change"),
  changePassword
);
registry.registerPath({
  method: "post",
  path: "/v1/auth/change_first_run",
  summary: "Change the password for the first run.",
  tags: ["Auth"],
  request: { body: createRequestOpenApiBodySchema(AuthChangePasswordFirstRunSchema) },
  responses: createApiEmptyResponse("First run password changed")
});
router.post(
  "/change_first_run",
  validateRequest(createRequestBodySchema(AuthChangePasswordFirstRunSchema), "post, /v1/auth/change_first_run"),
  changePasswordFirstRun
);
var auth_route_default = router;

// src/server/routes/v1/app.route.ts
var import_express2 = __toESM(require("express"));
var import_zod_to_openapi7 = require("@asteasolutions/zod-to-openapi");

// src/server/controllers/baseline.controller.ts
var import_http_status9 = __toESM(require("http-status"));

// src/server/services/run.service.ts
var run_service_exports = {};
__export(run_service_exports, {
  remove: () => remove2
});

// src/server/services/test.service.ts
var test_service_exports = {};
__export(test_service_exports, {
  accept: () => accept,
  queryTests: () => queryTests,
  queryTestsDistinct: () => queryTestsDistinct,
  remove: () => remove
});
var queryTests = async (filter, options) => {
  const tests = await Test_model_default.paginate(filter, options);
  return tests;
};
var queryTestsDistinct = async (filter, options) => {
  const tests = await Test_model_default.paginateDistinct({ filter: filter ? JSON.stringify(filter) : null }, options);
  return tests;
};
var remove = async (id2, user) => {
  const logOpts5 = {
    scope: "removeTest",
    itemType: "test",
    ref: id2,
    user: user?.username,
    msgType: "REMOVE"
  };
  logger_default.info(`remove test with, id: '${id2}', user: '${user.username}'`, logOpts5);
  try {
    logger_default.debug(`try to delete all checks associated to test with ID: '${id2}'`, logOpts5);
    const checks = await Check_model_default.find({ test: id2 });
    for (const check of checks) {
      await check_service_exports.remove(check._id, user);
    }
    return Test_model_default.findByIdAndDelete(id2);
  } catch (e) {
    logger_default.error(`cannot remove test with id: ${id2} error: ${e instanceof Error ? e.stack : String(e)}`, logOpts5);
    throw new Error();
  }
};
var accept = async (id2, user) => {
  const logOpts5 = {
    scope: "acceptTest",
    itemType: "test",
    ref: id2,
    user: user?.username,
    msgType: "ACCEPT"
  };
  logger_default.info(`accept test with, id: '${id2}', user: '${user.username}'`, logOpts5);
  const checks = await Check_model_default.find({ test: id2 }).exec();
  for (const check of checks) {
    await check_service_exports.accept(check._id, String(check.actualSnapshotId), user);
  }
  return { message: "success" };
};

// src/server/services/run.service.ts
var import_http_status4 = __toESM(require("http-status"));
var remove2 = async (id2, user) => {
  const logOpts5 = {
    scope: "removeRun",
    itemType: "run",
    ref: id2,
    user: user?.username,
    msgType: "REMOVE"
  };
  logger_default.info(`remove run with, id: '${id2}', user: '${user.username}'`, logOpts5);
  const tests = await Test_model_default.find({ run: id2 }).exec();
  for (const test of tests) {
    await remove(test._id, user);
  }
  const run = await Run_model_default.findByIdAndDelete(id2).exec();
  if (!run) {
    throw new ApiError_default(import_http_status4.default.NOT_FOUND, `cannot remove run with id: '${id2}', not found`);
  }
  return run;
};

// src/server/services/suite.service.ts
var suite_service_exports = {};
__export(suite_service_exports, {
  remove: () => remove3
});
var import_http_status5 = __toESM(require("http-status"));
var remove3 = async (id2, user) => {
  const logOpts5 = {
    scope: "removeSuite",
    itemType: "suite",
    ref: id2,
    user: user?.username,
    msgType: "REMOVE"
  };
  logger_default.info(`remove suite with, id: '${id2}', user: '${user.username}'`, logOpts5);
  const tests = await Test_model_default.find({ suite: id2 }).exec();
  for (const test of tests) {
    await remove(test._id, user);
  }
  const suite = await Suite_model_default.findByIdAndDelete(id2).exec();
  if (!suite) throw new ApiError_default(import_http_status5.default.NOT_FOUND, `cannot remove suite with id: '${id2}', not found`);
  return suite;
};

// src/server/services/logs.service.ts
var logs_service_exports = {};
__export(logs_service_exports, {
  createLogs: () => createLogs,
  distinct: () => distinct,
  queryLogs: () => queryLogs
});
var queryLogs = async (filter, options) => Log_model_default.paginate(filter, options);
var distinct = async (field) => Log_model_default.distinct(field);
var createLogs = async (body) => {
  logger_default[body.level || "debug"](body.message, {
    user: body.user,
    scope: body.scope || "test_scope",
    msgType: body.msgType || "TEST_MSG_TYPE"
  });
  return { message: "success" };
};

// src/server/services/generic.service.ts
var generic_service_exports = {};
__export(generic_service_exports, {
  get: () => get,
  put: () => put
});
var import_mongoose11 = __toESM(require("mongoose"));
var get = async (modelName, filter, options) => {
  const itemModel = import_mongoose11.default.model(modelName);
  return itemModel.paginate(filter, options);
};
var put = async (modelName, id2, options, user) => {
  const itemModel = import_mongoose11.default.model(modelName);
  const logOpts5 = {
    scope: "generic.service.put",
    ref: id2,
    itemType: modelName,
    msgType: "UPDATE",
    user: user?.username
  };
  const opts = removeEmptyProperties(options);
  logger_default.debug(`start update '${modelName}' with id: '${id2}', body: '${JSON.stringify(opts)}'`, logOpts5);
  const item = await itemModel.findByIdAndUpdate(id2, options).exec();
  if (!item) throw new Error(`cannot find the item: ${modelName}, id: ${id2}, options: ${JSON.stringify(options)}`);
  await item.save();
  logger_default.debug(`baseline with id: '${id2}' and opts: '${JSON.stringify(opts)}' was updated`, logOpts5);
  return item;
};

// src/server/services/app.service.ts
var app_service_exports = {};
__export(app_service_exports, {
  get: () => get2
});
var get2 = async (filter, options) => App_model_default.paginate(filter, options);

// src/server/services/tasks.service.ts
var tasks_service_exports = {};
__export(tasks_service_exports, {
  loadTestUser: () => loadTestUser,
  screenshots: () => screenshots,
  status: () => status,
  task_handle_database_consistency: () => task_handle_database_consistency,
  task_handle_old_checks: () => task_handle_old_checks,
  task_remove_old_logs: () => task_remove_old_logs,
  task_test: () => task_test
});
var import_fs2 = __toESM(require("fs"));
var import_string_table = __toESM(require("string-table"));

// src/seeds/testAdmin.json
var testAdmin_default = {
  username: "Test",
  firstName: "Test",
  lastName: "Admin",
  role: "admin",
  openPassw: "123456aA-",
  password: "5b8d4960316d1fb0c92498c90da6c397cdf247cae71f01467a88e2b42d7af6f5ac7ca75d3bea6e3e0078111a2e5dfc1611f9a9a8908a5a3af5bcd64c42989608977de192829bdf8ada113a60f8f0704443c659789761865e29a3103dbf0773f5bf31e4685d475ece56afaceb949b6e7467eaa287a02e4142d095bcbf84acaefe47ee080799a28188890d39d3397e285d8b46c9a0efe9517428825b64ee1ebcc96d92c084733db866c767341381b6254aaa1ef36d1bf3d24e3f5b8d8b6b4080589b130e9c90914a3da74e5b6adf5f569bfd77460abae8ae4f87c2a375397a37f09861b9e114cead0cc34fff2d631fd4294260dea17e4fe098940dbee2cb80c62eb3701d40f5b204de776b8252d55e5f567c599b1fbcdae79278d1f375a4c8244a26a3b721dbeec56c8f39b3eb810942d392aae371ea81ded6b820dd4b489566a33c495f5c291ff238d07202d2ff04c52426828e44af98ec056a42d13f4b166ec170083e2fff9efe2b8cfdde529f3bce56b8427cf2d188861808ad07fd13e073b2a804e818b2882c13f559d52420b49f301263a9de34fe22b6df4a82ae70e7e4c29c88479878d2c21fbb810532532e7ad9a28f610b63033520e703f178e7b44d3e101ec0d4339c085ccc8bb290b3cb996c75c2b8deaacba8098b9ec02c7e47542891da3bd887c31cd8e0bdfa56bb844b1703368afe8dc42d668ff2e3374b939b4f",
  apiKey: "",
  salt: "c6211751bdc372f491a86bcbd8e4196dc393d14e14e5f17019d5c317afd5bc27"
};

// src/server/services/tasks.service.ts
var import_path3 = __toESM(require("path"));
var stringTable = import_string_table.default;
function taskOutput(msg, res) {
  res.write(`${msg.toString()}
`);
  logger_default.debug(msg.toString());
}
function parseHrtimeToSeconds(hrtime) {
  return (hrtime[0] + hrtime[1] / 1e9).toFixed(3);
}
var status = async (currentUser) => {
  const count = await User_model_default.countDocuments().exec();
  logger_default.silly(`server status: check users counts: ${count}`);
  if (count > 1) {
    return { alive: true, currentUser: currentUser?.username };
  }
  return { alive: false };
};
var screenshots = async () => {
  const files = import_fs2.default.readdirSync(config.defaultImagesPath);
  return files;
};
var loadTestUser = async () => {
  const logOpts5 = {
    itemType: "user",
    msgType: "LOAD",
    ref: "Administrator"
  };
  if (!env.SYNGRISI_TEST_MODE) {
    return { message: "the feature works only in test mode" };
  }
  const testAdmin = await User_model_default.findOne({ username: "Test" }).exec();
  if (!testAdmin) {
    logger_default.info("create the test Administrator", logOpts5);
    const admin = await User_model_default.create(testAdmin_default);
    logger_default.info(`test Administrator with id: '${admin._id}' was created`, logOpts5);
    return admin;
  }
  logger_default.info(`test admin is exists: ${JSON.stringify(testAdmin, null, 2)}`, logOpts5);
  return { msg: `already exist '${testAdmin}'` };
};
var task_handle_database_consistency = async (options, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Content-Encoding": "none",
    "x-no-compression": "true"
  });
  try {
    const startTime = process.hrtime();
    taskOutput("- starting...\n", res);
    taskOutput("---------------------------------", res);
    taskOutput("STAGE #1: Calculate Common stats", res);
    taskOutput("get runs data", res);
    const allRunsBefore = await Run_model_default.find().exec();
    taskOutput("get suites data", res);
    const allSuitesBefore = await Suite_model_default.find().exec();
    taskOutput("get tests data", res);
    const allTestsBefore = await Test_model_default.find().lean().exec();
    taskOutput("get checks data", res);
    const allChecksBefore = await Check_model_default.find().lean().exec();
    taskOutput("get snapshots data", res);
    const allSnapshotsBefore = await Snapshot_model_default.find().lean().exec();
    taskOutput("get files data", res);
    const allFilesBefore = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
    taskOutput("-----------------------------", res);
    const beforeStatTable = stringTable.create([
      { item: "suites", count: allSuitesBefore.length },
      { item: "runs", count: allRunsBefore.length },
      { item: "tests", count: allTestsBefore.length },
      { item: "checks", count: allChecksBefore.length },
      { item: "snapshots", count: allSnapshotsBefore.length },
      { item: "files", count: allFilesBefore.length }
    ]);
    res.flush();
    taskOutput(beforeStatTable, res);
    taskOutput("---------------------------------", res);
    taskOutput("STAGE #2: Calculate Inconsistent Items", res);
    taskOutput("> calculate abandoned snapshots", res);
    const abandonedSnapshots = allSnapshotsBefore.filter((sn) => !import_fs2.default.existsSync(import_path3.default.join(config.defaultImagesPath, sn.filename)));
    taskOutput("> calculate abandoned files", res);
    const snapshotsUniqueFiles = Array.from(new Set(allSnapshotsBefore.map((x) => x.filename)));
    const abandonedFiles = [];
    const progress = new ProgressBar(allFilesBefore.length);
    for (const [index, file] of allFilesBefore.entries()) {
      setTimeout(() => {
        progress.writeIfChange(index, allFilesBefore.length, taskOutput, res);
      }, 10);
      if (!snapshotsUniqueFiles.includes(file.toString())) {
        abandonedFiles.push(file);
      }
    }
    taskOutput("> calculate abandoned checks", res);
    const allSnapshotsBeforeIds = allSnapshotsBefore.map((x) => x._id.valueOf());
    const allChecksBeforeLight = allChecksBefore.map((x) => ({
      _id: x._id.valueOf(),
      baselineId: x.baselineId.valueOf(),
      actualSnapshotId: x.actualSnapshotId.valueOf()
    }));
    const abandonedChecks = [];
    const progressChecks = new ProgressBar(allChecksBefore.length);
    for (const [index, check] of allChecksBeforeLight.entries()) {
      progressChecks.writeIfChange(index, allChecksBeforeLight.length, taskOutput, res);
      if (!allSnapshotsBeforeIds.includes(check.baselineId) || !allSnapshotsBeforeIds.includes(check.actualSnapshotId.valueOf())) {
        abandonedChecks.push(check._id.valueOf());
      }
    }
    taskOutput("> calculate empty tests", res);
    const checksUniqueTests = (await Check_model_default.find().lean().distinct("test").exec()).map((x) => x.valueOf());
    const emptyTests = [];
    for (const [index, test] of allTestsBefore.entries()) {
      if (!checksUniqueTests.includes(test._id.valueOf())) {
        emptyTests.push(test._id.valueOf());
      }
    }
    taskOutput("> calculate empty runs", res);
    const checksUniqueRuns = (await Check_model_default.find().distinct("run").exec()).map((x) => x.valueOf());
    const emptyRuns = [];
    for (const run of allRunsBefore) {
      if (!checksUniqueRuns.includes(run._id.valueOf())) {
        emptyRuns.push(run._id.valueOf());
      }
    }
    taskOutput("> calculate empty suites", res);
    const checksUniqueSuites = (await Check_model_default.find().distinct("suite").exec()).map((x) => x.valueOf());
    const emptySuites = [];
    for (const suite of allSuitesBefore) {
      if (!checksUniqueSuites.includes(suite._id.valueOf())) {
        emptySuites.push(suite._id.valueOf());
      }
    }
    taskOutput("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", res);
    taskOutput("Current inconsistent items:", res);
    const inconsistentStatTable = stringTable.create([
      { item: "empty suites", count: emptySuites.length },
      { item: "empty runs", count: emptyRuns.length },
      { item: "empty tests", count: emptyTests.length },
      { item: "abandoned checks", count: abandonedChecks.length },
      { item: "abandoned snapshots", count: abandonedSnapshots.length },
      { item: "abandoned files", count: abandonedFiles.length }
    ]);
    taskOutput(inconsistentStatTable, res);
    if (options.clean) {
      taskOutput("---------------------------------", res);
      taskOutput("STAGE #3: Remove non consistent items", res);
      taskOutput("> remove empty suites", res);
      await Suite_model_default.deleteMany({ _id: { $in: emptySuites } });
      taskOutput("> remove empty runs", res);
      await Run_model_default.deleteMany({ _id: { $in: emptyRuns } });
      taskOutput("> remove empty tests", res);
      await Test_model_default.deleteMany({ _id: { $in: emptyTests } });
      taskOutput("> remove abandoned checks", res);
      await Check_model_default.deleteMany({ _id: { $in: abandonedChecks } });
      taskOutput("> remove abandoned snapshots", res);
      await Snapshot_model_default.deleteMany({ _id: { $in: abandonedSnapshots } });
      taskOutput("> remove abandoned files", res);
      await Promise.all(abandonedFiles.map((filename) => import_fs2.promises.unlink(import_path3.default.join(config.defaultImagesPath, filename))));
      const allFilesAfter = import_fs2.default.readdirSync(config.defaultImagesPath, { withFileTypes: true }).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
      taskOutput("STAGE #4: Calculate Common stats after cleaning", res);
      taskOutput("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~", res);
      taskOutput("Current items:", res);
      const afterStatTable = stringTable.create([
        { item: "suites", count: await Suite_model_default.countDocuments() },
        { item: "runs", count: await Run_model_default.countDocuments() },
        { item: "tests", count: await Test_model_default.countDocuments() },
        { item: "checks", count: await Check_model_default.countDocuments() },
        { item: "snapshots", count: await Snapshot_model_default.countDocuments() },
        { item: "files", count: allFilesAfter.length }
      ]);
      taskOutput(afterStatTable, res);
    }
    const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
    taskOutput(`> Done in ${elapsedSeconds} seconds, ${elapsedSeconds / 60} min`, res);
    taskOutput("- end...\n", res);
  } catch (e) {
    const errMsg2 = e instanceof Error ? e.message : String(e);
    logger_default.error(errMsg2);
    taskOutput(errMsg2, res);
  } finally {
    res.end();
  }
};
var task_remove_old_logs = async (options, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Content-Encoding": "none"
  });
  const trashHoldDate = subDays_default(/* @__PURE__ */ new Date(), parseInt(options.days, 10));
  const filter = { timestamp: { $lt: trashHoldDate } };
  const allLogsCountBefore = await Log_model_default.find({}).countDocuments();
  const oldLogsCount = await Log_model_default.find(filter).countDocuments();
  taskOutput(`- the count of all documents is: '${allLogsCountBefore}'
`, res);
  taskOutput(`- the count of documents to be removed is: '${oldLogsCount}'
`, res);
  if (options.statistics === "false") {
    taskOutput(`- will remove all logs older that: '${options.days}' days, '${dateToISO8601_default(trashHoldDate)}'
`, res);
    await Log_model_default.deleteMany(filter);
    const allLogsCountAfter = await Log_model_default.find({}).countDocuments();
    taskOutput(`- the count of all documents now is: '${allLogsCountAfter}'
`, res);
  }
  taskOutput("> Done", res);
  res.end();
};
var task_handle_old_checks = async (options, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Content-Encoding": "none"
  });
  try {
    const startTime = process.hrtime();
    taskOutput("- starting...\n", res);
    taskOutput("STAGE #1 Calculate common stats", res);
    const trashHoldDate = subDays_default(/* @__PURE__ */ new Date(), parseInt(options.days, 10));
    taskOutput("> get all checks data", res);
    const allChecksBefore = await Check_model_default.find().lean().exec();
    taskOutput("> get snapshots data", res);
    const allSnapshotsBefore = await Snapshot_model_default.find().lean().exec();
    taskOutput("> get files data", res);
    const allFilesBefore = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
    taskOutput("> get old checks data", res);
    const oldChecks = await Check_model_default.find({ createdDate: { $lt: trashHoldDate } }).lean().exec();
    taskOutput(">>> collect all baselineIds for old Checks ", res);
    const oldSnapshotsBaselineIdIds = oldChecks.map((x) => x.baselineId).filter((x) => x);
    taskOutput(">>> collect all actualSnapshotId for old Checks ", res);
    const oldSnapshotsActualSnapshotIdIds = oldChecks.map((x) => x.actualSnapshotId).filter((x) => x);
    taskOutput(">>> collect all diffId for old Checks ", res);
    const oldSnapshotsDiffIds = oldChecks.map((x) => x.diffId).filter((x) => x);
    taskOutput(">>> calculate all unique snapshots ids for old Checks ", res);
    const allOldSnapshotsUniqueIds = Array.from(/* @__PURE__ */ new Set([...oldSnapshotsBaselineIdIds, ...oldSnapshotsActualSnapshotIdIds, ...oldSnapshotsDiffIds])).map((x) => x.valueOf());
    taskOutput(">>> collect all old snapshots", res);
    const oldSnapshots = await Snapshot_model_default.find({ _id: { $in: allOldSnapshotsUniqueIds } }).lean();
    const outTable = stringTable.create([
      { item: "all checks", count: allChecksBefore.length },
      { item: "all snapshots", count: allSnapshotsBefore.length },
      { item: "all files", count: allFilesBefore.length },
      { item: `checks older than: '${options.days}' days`, count: oldChecks.length },
      { item: "old snapshots baseline ids", count: oldSnapshotsBaselineIdIds.length },
      { item: "old snapshots actual snapshotId", count: oldSnapshotsActualSnapshotIdIds.length },
      { item: "old snapshots diffIds", count: oldSnapshotsDiffIds.length },
      { item: "all old snapshots unique Ids", count: allOldSnapshotsUniqueIds.length },
      { item: "all old snapshots", count: oldSnapshots.length }
    ]);
    taskOutput(outTable, res);
    if (options.remove === "true") {
      taskOutput(`STAGE #2 Remove checks that older that: '${options.days}' days, '${dateToISO8601_default(trashHoldDate)}'
`, res);
      taskOutput("> remove checks", res);
      const checkRemovingResult = await Check_model_default.deleteMany({ createdDate: { $lt: trashHoldDate } });
      taskOutput(`>>> removed: '${checkRemovingResult.deletedCount}'`, res);
      taskOutput("> remove snapshots", res);
      taskOutput(">> collect data to removing", res);
      taskOutput(">>> get all baselines snapshots id`s", res);
      const baselinesSnapshotsIds = await Baseline_model_default.find({}).distinct("snapshootId");
      taskOutput(">>> get all checks snapshots baselineId", res);
      const checksSnapshotsBaselineId = await Check_model_default.find({}).distinct("baselineId");
      taskOutput(">>> get all checks snapshots actualSnapshotId", res);
      const checksSnapshotsActualSnapshotId = await Check_model_default.find({}).distinct("actualSnapshotId");
      taskOutput(">> remove baselines snapshots", res);
      taskOutput(">> remove all old snapshots that not related to new baseline and check items", res);
      const removedByBaselineSnapshotsResult = await Snapshot_model_default.deleteMany({
        $and: [
          { _id: { $nin: checksSnapshotsBaselineId } },
          { _id: { $nin: checksSnapshotsActualSnapshotId } },
          { _id: { $nin: baselinesSnapshotsIds } },
          { _id: { $in: oldSnapshotsBaselineIdIds } }
        ]
      });
      taskOutput(`>>> removed: '${removedByBaselineSnapshotsResult.deletedCount}'`, res);
      taskOutput(">> remove actual snapshots", res);
      taskOutput(">> remove all old snapshots that not related to new baseline and check items", res);
      const removedByActualSnapshotsResult = await Snapshot_model_default.deleteMany({
        $and: [
          { _id: { $nin: checksSnapshotsBaselineId } },
          { _id: { $nin: checksSnapshotsActualSnapshotId } },
          { _id: { $nin: baselinesSnapshotsIds } },
          { _id: { $in: oldSnapshotsActualSnapshotIdIds } }
        ]
      });
      taskOutput(`>>> removed: '${removedByActualSnapshotsResult.deletedCount}'`, res);
      taskOutput(">> remove all old diff snapshots", res);
      const removedByDiffSnapshotsResult = await Snapshot_model_default.deleteMany({
        $and: [
          { _id: { $in: oldSnapshotsDiffIds } }
        ]
      });
      taskOutput(`>>> removed: '${removedByDiffSnapshotsResult.deletedCount}'`, res);
      taskOutput("> remove files", res);
      taskOutput(">>> collect all old snapshots filenames", res);
      const oldSnapshotsUniqueFilenames = Array.from(new Set(oldSnapshots.map((x) => x.filename)));
      taskOutput(`>> found: ${oldSnapshotsUniqueFilenames.length}`, res);
      taskOutput("> get all current snapshots filenames", res);
      const allCurrentSnapshotsFilenames = await Snapshot_model_default.find().distinct("filename").exec();
      taskOutput(">> calculate interception between all current snapshot filenames and old shapshots filenames", res);
      const arrayIntersection = (arr1, arr2) => arr1.filter((x) => arr2.includes(x));
      const filesInterception = arrayIntersection(allCurrentSnapshotsFilenames, oldSnapshotsUniqueFilenames);
      taskOutput(`>> found: ${filesInterception.length}`, res);
      taskOutput(">> calculate filenames to remove", res);
      const arrayDiff = (arr1, arr2) => arr1.filter((x) => !arr2.includes(x));
      const filesToDelete = arrayDiff(oldSnapshotsUniqueFilenames, filesInterception);
      taskOutput(`>> found: ${filesToDelete.length}`, res);
      taskOutput(`>> remove these files: ${filesToDelete.length}`, res);
      await Promise.all(filesToDelete.map((filename) => import_fs2.promises.unlink(import_path3.default.join(config.defaultImagesPath, filename))));
      taskOutput(`>> done: ${filesToDelete.length}`, res);
      taskOutput("STAGE #3 Calculate common stats after Removing", res);
      taskOutput("> get all checks data", res);
      const allChecksAfter = await Check_model_default.find().lean().exec();
      taskOutput("> get snapshots data", res);
      const allSnapshotsAfter = await Snapshot_model_default.find().lean().exec();
      taskOutput("> get files data", res);
      const allFilesAfter = (await import_fs2.promises.readdir(config.defaultImagesPath, { withFileTypes: true })).filter((item) => !item.isDirectory()).map((x) => x.name).filter((x) => x.includes(".png"));
      const outTableAfter = stringTable.create([
        { item: "all checks", count: allChecksAfter.length },
        { item: "all snapshots", count: allSnapshotsAfter.length },
        { item: "all files", count: allFilesAfter.length }
      ]);
      taskOutput(outTableAfter, res);
    }
    const elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
    taskOutput(`> done in ${elapsedSeconds} seconds ${elapsedSeconds / 60} min`, res);
  } catch (e) {
    const errMsg2 = e instanceof Error ? e.message : String(e);
    logger_default.error(errMsg2);
    taskOutput(errMsg2, res);
  } finally {
    res.end();
  }
};
var task_test = async (options = "empty", req, res) => {
  res.writeHead(200, {
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Content-Encoding": "none"
  });
  const x = 1e3;
  let isAborted = false;
  req.on("close", () => {
    isAborted = true;
  });
  for (let i = 0; i < x; i += 1) {
    taskOutput(`- Task Output: '${i}', options: ${options}
`, res);
    if (isAborted) {
      taskOutput("the task was aborted\n", res);
      logger_default.warn("the task was aborted");
      res.flush();
      return res.end();
    }
  }
  return res.end();
};

// src/server/services/client.service.ts
var client_service_exports = {};
__export(client_service_exports, {
  createCheck: () => createCheck,
  endSession: () => endSession,
  getBaselines: () => getBaselines,
  getIdent: () => getIdent,
  startSession: () => startSession
});
var import_fs3 = __toESM(require("fs"));
var import_hasha2 = __toESM(require("hasha"));

// src/server/lib/dbItems/updateItem.ts
var import_mongoose12 = __toESM(require("mongoose"));
async function updateItem(itemType, filter, params) {
  const logOpts5 = {
    scope: "updateItem",
    msgType: "UPDATE",
    itemType
  };
  logger_default.debug(`update item type: '${itemType}', filter: '${JSON.stringify(filter)}', params: '${JSON.stringify(params)}'`, logOpts5);
  const itemModel = await import_mongoose12.default.model(itemType).findOne(filter);
  const updatedItem = await itemModel?.updateOne(params);
  logger_default.debug(`'${itemType}' was updated: '${JSON.stringify(updatedItem)}'`, { ...logOpts5, ...{ ref: String(itemModel?._id) } });
  return updatedItem;
}

// src/server/lib/dbItems/updateItemDate.ts
var import_mongoose13 = __toESM(require("mongoose"));
var logOpts2 = {
  scope: "dbitems",
  msgType: "DB"
};
async function updateItemDate(mdClass, id2) {
  logger_default.debug(`update date for the item: '${mdClass}' with id: '${id2}'`, logOpts2);
  const itemModel = await import_mongoose13.default.model(mdClass).findById(id2);
  const updatedItem = await itemModel?.updateOne({ updatedDate: Date.now() });
  logger_default.debug(`'${mdClass}' date updated: '${JSON.stringify(itemModel)}'`, logOpts2);
  return updatedItem;
}

// src/server/lib/dbItems/createItemIfNotExist.ts
var import_mongoose14 = __toESM(require("mongoose"));
async function createItemIfNotExist(modelName, params, logsMeta = {}) {
  const logOpts5 = {
    scope: "createItemIfNotExist",
    msgType: "CREATE",
    itemType: modelName
  };
  try {
    const itemModel = import_mongoose14.default.model(modelName);
    const options = {
      upsert: true,
      new: true,
      setDefaultsOnInsert: true
    };
    await itemModel.init();
    const item = await itemModel.findOneAndUpdate(params, params, options);
    logger_default.info(`ORM item '${modelName}' was created: '${JSON.stringify(item)}'`, { ...logOpts5, ...{ ref: String(item?._id) }, ...logsMeta });
    return item;
  } catch (e) {
    logger_default.debug(`cannot create '${modelName}' ORM item, error: '${e.stack || e}'`, { ...logOpts5, ...logsMeta });
  }
  return null;
}

// src/server/lib/dbItems/createItemProm.ts
var import_mongoose15 = __toESM(require("mongoose"));
var logOpts3 = {
  scope: "dbitems",
  msgType: "DB"
};
async function createItemProm(modelName, params) {
  try {
    const itemModel = import_mongoose15.default.model(modelName);
    logger_default.debug(`start to create ORM item via promise: '${modelName}', params: '${JSON.stringify(params)}'`, logOpts3);
    const item = await itemModel.create(params);
    return item;
  } catch (e) {
    const errMsg2 = `cannot create '${modelName}', error: '${e.stack || e}'`;
    logger_default.error(errMsg2, logOpts3);
    throw new Error(errMsg2);
  }
}

// src/server/lib/dbItems/createTest.ts
async function createTest(params) {
  return createItemProm("VRSTest", params);
}

// src/server/lib/dbItems/createSuiteIfNotExist.ts
async function createSuiteIfNotExist(params, logsMeta = {}) {
  const logOpts5 = {
    scope: "createSuiteIfNotExist",
    msgType: "CREATE",
    itemType: "VRSSuite"
  };
  if (!params.name || !params.app) throw new Error(`Cannot create suite, wrong params: '${JSON.stringify(params)}'`);
  logger_default.debug(`try to create suite if exist, params: '${JSON.stringify(params)}'`, { ...logOpts5, ...logsMeta });
  let suite = await Suite_model_default.findOne({ name: params.name }).exec();
  if (suite) {
    logger_default.debug(`suite already exist: '${JSON.stringify(params)}'`, { ...logOpts5, ...logsMeta });
    return suite;
  }
  suite = await Suite_model_default.create(params);
  logger_default.debug(`suite with name: '${params.name}' was created`, { ...logOpts5, ...logsMeta });
  return suite;
}

// src/server/lib/dbItems/createRunIfNotExist.ts
async function createRunIfNotExist(params, logsMeta = {}) {
  const logOpts5 = {
    scope: "createRunIfNotExist",
    msgType: "CREATE",
    itemType: "VRSRun"
  };
  let run;
  try {
    if (!params.name || !params.app || !params.ident) {
      throw new Error(`Cannot create run, wrong params: '${JSON.stringify(params)}'`);
    }
    logger_default.debug(`try to create run if exist, params: '${JSON.stringify(params)}'`, { ...logOpts5, ...logsMeta });
    run = await Run_model_default.findOne({ ident: params.ident }).exec();
    if (run) {
      logger_default.debug(`run already exist: '${JSON.stringify(params)}'`, { ...logOpts5, ...logsMeta });
      return run;
    }
    run = await Run_model_default.create({
      ...params,
      createdDate: params.createdDate || /* @__PURE__ */ new Date()
    });
    logger_default.debug(`run with name: '${params.name}' was created: ${run}`, { ...logOpts5, ...logsMeta });
    return run;
  } catch (e) {
    if (e.code === 11e3) {
      logger_default.warn(`run key duplication collision: '${JSON.stringify(params)}', error: '${errMsg(e)}'`, { ...logOpts5, ...logsMeta });
      run = await Run_model_default.findOne({ name: params.name, ident: params.ident });
      logger_default.warn(`run key duplication collision, found: '${JSON.stringify(run)}'`, { ...logOpts5, ...logsMeta });
      if (run) return run;
    }
    logger_default.error(`cannot create run, params: '${JSON.stringify(params)}', error: '${errMsg(e)}', obj: ${JSON.stringify(e)}`, { ...logOpts5, ...logsMeta });
    throw e;
  }
}

// src/server/lib/сomparison/compareImagesNode.ts
var import_node_resemble = __toESM(require("@syngrisi/node-resemble.js"));
async function streamToBuffer(stream) {
  return new Promise((resolve, reject) => {
    const data = [];
    stream.on("data", (chunk) => {
      data.push(chunk);
    });
    stream.on("end", () => {
      resolve(Buffer.concat(data));
    });
    stream.on("error", (err) => {
      reject(err);
    });
  });
}
function compareImages(image1, image2, options) {
  return new Promise((resolve, reject) => {
    try {
      const ignoreTransform = {
        antialiasing: "ignoreAntialiasing",
        colors: "ignoreColors",
        nothing: "ignoreNothing"
      };
      const ignoreMethod = ignoreTransform[options.ignore] ? ignoreTransform[options.ignore] : "ignoreNothing";
      const outputOpts = options.output;
      import_node_resemble.default.outputSettings(outputOpts);
      let ignoredRect;
      if (options.ignoreRectangles) {
        ignoredRect = options.ignoreRectangles.map((it) => {
          delete it.name;
          return [it.left, it.top, it.right - it.left, it.bottom - it.top];
        });
      }
      (0, import_node_resemble.default)(image1).compareTo(image2)[ignoreMethod]().ignoreRectangles(ignoredRect).onComplete(async (data) => {
        console.log(data);
        const stream = await data.getDiffImage();
        const buffer = await streamToBuffer(stream.pack());
        data.getBuffer = function() {
          return buffer;
        };
        resolve(data);
      });
    } catch (e) {
      reject(e);
    }
  });
}

// src/server/lib/сomparison/comparator.ts
var DEFAULT_OPTIONS = {
  output: {
    largeImageThreshold: 0,
    outputDiff: true,
    errorType: "flat",
    transparency: 0
  },
  ignore: "nothing"
};
async function makeDiff(imgData1, imgData2, options = {}) {
  const opts = Object.assign(DEFAULT_OPTIONS, options);
  opts.ignoreRectangles = options.ignoredBoxes;
  const compareData = await compareImages(imgData1, imgData2, opts);
  return compareData;
}
async function getDiff(baselineOrigin, actualOrigin, opts = {}) {
  const logOpts5 = {
    scope: "getDiff",
    itemType: "image",
    msgType: "GET_DIFF"
  };
  try {
    const executionTimer = process.hrtime();
    logger_default.debug(`SAMPLE #1: ${process.hrtime(executionTimer).toString()}`, logOpts5);
    const directDiff = await makeDiff(baselineOrigin, actualOrigin, opts);
    logger_default.debug(`SAMPLE #2: ${process.hrtime(executionTimer).toString()}`, logOpts5);
    directDiff.executionTotalTime = process.hrtime(executionTimer).toString();
    logger_default.debug(`SAMPLE #3: ${process.hrtime(executionTimer).toString()}`, logOpts5);
    logger_default.debug(`the diff is: ${JSON.stringify(directDiff, null, 4)}`, logOpts5);
    return directDiff;
  } catch (e) {
    logger_default.error(errMsg(e), logOpts5);
    throw new Error(errMsg(e));
  }
}

// src/server/services/client.service.ts
var import_http_status6 = __toESM(require("http-status"));
var import_http_status7 = __toESM(require("http-status"));
var import_path4 = __toESM(require("path"));
async function updateTest(id2, update4) {
  const logOpts5 = {
    scope: "updateTest",
    itemType: "test",
    msgType: "UPDATE",
    ref: id2
  };
  logger_default.debug(`update test id '${id2}' with params '${JSON.stringify(update4)}'`, logOpts5);
  const updatedDate = update4.updatedDate || Date.now();
  const test = await Test_model_default.findByIdAndUpdate(
    id2,
    { ...update4, updatedDate }
  ).exec();
  await test?.save();
  return test;
}
var startSession = async (params, username) => {
  const logOpts5 = {
    scope: "createTest",
    user: username,
    itemType: "test",
    msgType: "CREATE"
  };
  logger_default.info(`create test with name '${params.name}', params: '${JSON.stringify(params)}'`, logOpts5);
  const opts = removeEmptyProperties({
    name: params.name,
    status: "Running",
    app: params.app,
    tags: params.tags && JSON.parse(params.tags),
    branch: params.branch,
    viewport: params.viewport,
    browserName: params.browser,
    browserVersion: params.browserVersion,
    browserFullVersion: params.browserFullVersion,
    os: params.os,
    startDate: /* @__PURE__ */ new Date(),
    updatedDate: /* @__PURE__ */ new Date()
  });
  try {
    const app = await createItemIfNotExist(
      "VRSApp",
      { name: params.app },
      { user: username, itemType: "app" }
    );
    opts.app = app._id;
    const run = await createRunIfNotExist(
      { name: params.run, ident: params.runident, app: app._id },
      { user: username, itemType: "run" }
    );
    opts.run = run._id;
    const suite = await createSuiteIfNotExist(
      { name: params.suite || "Others", app: app._id, createdDate: /* @__PURE__ */ new Date() },
      { user: username, itemType: "suite" }
    );
    opts.suite = suite._id;
    const test = await createTest(opts);
    return test;
  } catch (e) {
    logger_default.error(`cannot start session '${params.name}', params: '${JSON.stringify(params)}', error: ${errMsg(e)}`, logOpts5);
    throw e;
  }
};
var endSession = async (testId, username) => {
  const logOpts5 = {
    scope: "stopSession",
    msgType: "END_SESSION",
    user: username,
    itemType: "test",
    ref: testId
  };
  await waitUntil(async () => (await Check_model_default.find({ test: testId }).exec()).filter((ch) => ch.status.toString() !== "pending").length > 0);
  const sessionChecks = await Check_model_default.find({ test: testId }).lean().exec();
  const checksStatuses = sessionChecks.map((x) => x.status[0]);
  let status3 = "not set";
  if (checksStatuses.some((st2) => st2 === "failed")) {
    status3 = "Failed";
  }
  if (checksStatuses.some((st2) => st2 === "passed") && !checksStatuses.some((st2) => st2 === "failed")) {
    status3 = "Passed";
  }
  if (checksStatuses.some((st2) => st2 === "new") && !checksStatuses.some((st2) => st2 === "failed")) {
    status3 = "Passed";
  }
  if (checksStatuses.some((st2) => st2 === "blinking") && !checksStatuses.some((st2) => st2 === "failed")) {
    status3 = "Passed";
  }
  if (checksStatuses.every((st2) => st2 === "new")) {
    status3 = "New";
  }
  const blinking = checksStatuses.filter((g) => g === "blinking").length;
  const testParams = {
    status: status3,
    blinking
    // calculatedViewport,
  };
  logger_default.info(`the session is over, the test will be updated with parameters: '${JSON.stringify(testParams)}'`, logOpts5);
  const updatedTest = await updateTest(testId, testParams);
  const result = updatedTest?.toObject();
  return result;
};
async function getAcceptedBaseline(params) {
  const identFieldsAccepted = Object.assign(buildIdentObject(params), { markedAs: "accepted" });
  const acceptedBaseline = await Baseline_model_default.findOne(identFieldsAccepted, {}, { sort: { createdDate: -1 } });
  logger_default.debug(`acceptedBaseline: '${acceptedBaseline ? JSON.stringify(acceptedBaseline) : "not found"}'`, { itemType: "baseline" });
  if (acceptedBaseline) return acceptedBaseline;
  return null;
}
async function getLastSuccessCheck(identifier) {
  const condition = [{
    ...identifier,
    status: "new"
  }, {
    ...identifier,
    status: "passed"
  }];
  return (await Check_model_default.find({ $or: condition }).sort({ updatedDate: -1 }).limit(1))[0];
}
async function getNotPendingChecksByIdent(identifier) {
  return Check_model_default.find({
    ...identifier,
    status: { $ne: "pending" }
  }).sort({ updatedDate: -1 }).exec();
}
async function getSnapshotByImgHash(hash) {
  return Snapshot_model_default.findOne({ imghash: hash });
}
async function createSnapshot(parameters) {
  const logOpts5 = {
    scope: "createSnapshot",
    itemType: "snapshot",
    msgType: "CREATE"
  };
  const { name, fileData, hashCode } = parameters;
  const opts = { name };
  if (fileData === null) throw new ApiError_default(import_http_status6.default.BAD_REQUEST, `cannot create the snapshot, the 'fileData' is not set, name: '${name}'`);
  opts.imghash = hashCode || (0, import_hasha2.default)(fileData);
  const snapshot = new Snapshot_model_default(opts);
  const filename = `${snapshot.id}.png`;
  const imagePath = import_path4.default.join(config.defaultImagesPath, filename);
  logger_default.debug(`save screenshot for: '${name}' snapshot to: '${imagePath}'`, logOpts5);
  await import_fs3.promises.writeFile(imagePath, fileData);
  snapshot.filename = filename;
  await snapshot.save();
  logger_default.debug(`snapshot was saved: '${JSON.stringify(snapshot)}'`, { ...logOpts5, ...{ ref: snapshot._id } });
  return snapshot;
}
async function cloneSnapshot(sourceSnapshot, name) {
  const { filename } = sourceSnapshot;
  const hashCode = sourceSnapshot.imghash;
  const newSnapshot = new Snapshot_model_default({ name, filename, imghash: hashCode });
  await newSnapshot.save();
  return newSnapshot;
}
async function compareSnapshots(baselineSnapshot, actual, opts = {}) {
  const logOpts5 = {
    scope: "compareSnapshots",
    ref: baselineSnapshot.id,
    itemType: "snapshot",
    msgType: "COMPARE"
  };
  try {
    logger_default.debug(`compare baseline and actual snapshots with ids: [${baselineSnapshot.id}, ${actual.id}]`, logOpts5);
    logger_default.debug(`current baseline snapshot: ${JSON.stringify(baselineSnapshot)}`, logOpts5);
    let diff;
    if (baselineSnapshot.imghash === actual.imghash) {
      logger_default.debug(`baseline and actual snapshot have the identical image hashes: '${baselineSnapshot.imghash}'`, logOpts5);
      diff = {
        isSameDimensions: true,
        dimensionDifference: { width: 0, height: 0 },
        rawMisMatchPercentage: 0,
        misMatchPercentage: "0.00",
        analysisTime: 0,
        executionTotalTime: "0",
        getBuffer: null
      };
    } else {
      const baselinePath = import_path4.default.join(config.defaultImagesPath, baselineSnapshot.filename);
      const actualPath = import_path4.default.join(config.defaultImagesPath, actual.filename);
      const baselineData = await import_fs3.promises.readFile(baselinePath);
      const actualData = await import_fs3.promises.readFile(actualPath);
      logger_default.debug(`baseline path: ${baselinePath}`, logOpts5);
      logger_default.debug(`actual path: ${actualPath}`, logOpts5);
      const options = opts;
      const baseline = await Baseline_model_default.findOne({ snapshootId: baselineSnapshot._id }).exec();
      if (baseline) {
        if (baseline.ignoreRegions) {
          logger_default.debug(`ignore regions: '${baseline.ignoreRegions}', type: '${typeof baseline.ignoreRegions}'`);
          options.ignoredBoxes = JSON.parse(baseline.ignoreRegions);
        }
        options.ignore = baseline.matchType || "nothing";
      }
      diff = await getDiff(baselineData, actualData, options);
    }
    logger_default.silly(`the diff is: '${JSON.stringify(diff, null, 2)}'`);
    if (diff.rawMisMatchPercentage.toString() !== "0") {
      logger_default.debug(`images are different, ids: [${baselineSnapshot.id}, ${actual.id}], rawMisMatchPercentage: '${diff.rawMisMatchPercentage}'`);
    }
    if (diff.stabMethod && diff.vOffset) {
      if (diff.stabMethod === "downup") {
        actual.vOffset = -diff.vOffset;
        await actual.save();
      }
      if (diff.stabMethod === "updown") {
        baselineSnapshot.vOffset = -diff.vOffset;
        await baselineSnapshot.save();
      }
    }
    return diff;
  } catch (e) {
    const errMsg2 = `cannot compare snapshots: ${e}
 ${e instanceof Error ? e.stack : e}`;
    logger_default.error(errMsg2, logOpts5);
    throw new Error(String(e));
  }
}
var isBaselineValid = (baseline) => {
  const keys = [
    "name",
    "app",
    "branch",
    "browserName",
    "viewport",
    "os",
    "createdDate",
    "lastMarkedDate",
    "markedAs",
    "markedById",
    "markedByUsername",
    "snapshootId"
  ];
  for (const key of keys) {
    if (!baseline[key]) {
      logger_default.error(`invalid baseline, the '${key}' property is empty`);
      return false;
    }
  }
  return true;
};
var updateCheckParamsFromBaseline = (params, baseline) => {
  const updatedParams = { ...params };
  updatedParams.baselineId = baseline.snapshootId.toString();
  updatedParams.markedAs = baseline.markedAs;
  updatedParams.markedDate = baseline.lastMarkedDate?.toString();
  updatedParams.markedByUsername = baseline.markedByUsername;
  return updatedParams;
};
var prepareActualSnapshot = async (checkParam, snapshotFoundedByHashcode, logOpts5) => {
  let currentSnapshot;
  const fileData = checkParam.files ? checkParam.files.file.data : null;
  if (snapshotFoundedByHashcode) {
    const fullFilename = import_path4.default.join(config.defaultImagesPath, snapshotFoundedByHashcode.filename);
    if (!import_fs3.default.existsSync(fullFilename)) {
      throw new Error(`Couldn't find the baseline file: '${fullFilename}'`);
    }
    logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' is already exists, will clone it`, logOpts5);
    if (!checkParam.name) throw new ApiError_default(import_http_status6.default.BAD_REQUEST, `Cannot prepareActualSnapshot name is empty, hashe: ${checkParam.hashCode}`);
    currentSnapshot = await cloneSnapshot(snapshotFoundedByHashcode, checkParam.name);
  } else {
    logger_default.debug(`snapshot with such hashcode: '${checkParam.hashCode}' does not exists, will create it`, logOpts5);
    currentSnapshot = await createSnapshot({ name: checkParam.name, fileData, hashCode: checkParam.hashCode });
  }
  return currentSnapshot;
};
async function isNeedFiles(checkParam, logOpts5) {
  const snapshotFoundedByHashcode = await getSnapshotByImgHash(checkParam.hashCode);
  if (!checkParam.hashCode && !checkParam.files) {
    logger_default.debug("hashCode or files parameters should be present", logOpts5);
    return { needFilesStatus: true, snapshotFoundedByHashcode };
  }
  if (!checkParam.files && !snapshotFoundedByHashcode) {
    logger_default.debug(`cannot find the snapshot with hash: '${checkParam.hashCode}'`, logOpts5);
    return { needFilesStatus: true, snapshotFoundedByHashcode };
  }
  return { needFilesStatus: false, snapshotFoundedByHashcode };
}
async function inspectBaseline(newCheckParams, storedBaseline, checkIdent, currentSnapshot, logOpts5) {
  let currentBaselineSnapshot = null;
  const params = {};
  params.failReasons = [];
  if (storedBaseline !== null) {
    logger_default.debug(`a baseline for check name: '${newCheckParams.name}', id: '${storedBaseline.snapshootId}' is already exists`, logOpts5);
    if (!isBaselineValid(storedBaseline)) {
      newCheckParams.failReasons.push("invalid_baseline");
    }
    Object.assign(params, updateCheckParamsFromBaseline(newCheckParams, storedBaseline));
    currentBaselineSnapshot = await Snapshot_model_default.findById(storedBaseline.snapshootId);
    if (!currentBaselineSnapshot) throw new ApiError_default(import_http_status6.default.INTERNAL_SERVER_ERROR, `Cannot find the snapshot with id: ${storedBaseline.snapshootId}`);
  } else {
    const checksWithSameIdent = await getNotPendingChecksByIdent(checkIdent);
    if (checksWithSameIdent.length > 0) {
      logger_default.error(`checks with ident'${JSON.stringify(checkIdent)}' exist, but baseline is absent`, logOpts5);
      params.failReasons.push("not_accepted");
      params.baselineId = currentSnapshot.id.toString();
      currentBaselineSnapshot = currentSnapshot;
    } else {
      params.baselineId = currentSnapshot.id;
      params.status = "new";
      currentBaselineSnapshot = currentSnapshot;
      logger_default.debug(`create the new check with params: '${prettyCheckParams_default(params)}'`, logOpts5);
    }
  }
  return { inspectBaselineParams: params, currentBaselineSnapshot };
}
var ignoreDifferentResolutions = ({ height, width }) => {
  if (width === 0 && height === -1) return true;
  if (width === 0 && height === 1) return true;
  return false;
};
var compare = async (expectedSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser) => {
  const logOpts5 = {
    scope: "createCheck.compare",
    user: currentUser.username,
    itemType: "check",
    msgType: "COMPARE"
  };
  const executionTimer = process.hrtime();
  const compareResult = {};
  compareResult.failReasons = [...newCheckParams.failReasons];
  let checkCompareResult;
  let diffSnapshot = null;
  const areSnapshotsDifferent = (result) => result.rawMisMatchPercentage.toString() !== "0";
  const areSnapshotsWrongDimensions = (result) => !result.isSameDimensions && !ignoreDifferentResolutions(result.dimensionDifference);
  if (newCheckParams.status !== "new" && !compareResult.failReasons.includes("not_accepted")) {
    try {
      logger_default.debug(`'the check with name: '${newCheckParams.name}' isn't new, make comparing'`, logOpts5);
      checkCompareResult = await compareSnapshots(expectedSnapshot, actualSnapshot, { vShifting: newCheckParams.vShifting });
      logger_default.silly(`ignoreDifferentResolutions: '${ignoreDifferentResolutions(checkCompareResult.dimensionDifference)}'`);
      logger_default.silly(`dimensionDifference: '${JSON.stringify(checkCompareResult.dimensionDifference)}`);
      if (areSnapshotsDifferent(checkCompareResult) || areSnapshotsWrongDimensions(checkCompareResult)) {
        let logMsg;
        if (areSnapshotsWrongDimensions(checkCompareResult)) {
          logMsg = "snapshots have different dimensions";
          compareResult.failReasons.push("wrong_dimensions");
        }
        if (areSnapshotsDifferent(checkCompareResult)) {
          logMsg = "snapshots have differences";
          compareResult.failReasons.push("different_images");
        }
        if (logMsg) logger_default.debug(logMsg, logOpts5);
        logger_default.debug(`saving diff snapshot for check with name: '${newCheckParams.name}'`, logOpts5);
        if (!skipSaveOnCompareError) {
          diffSnapshot = await createSnapshot({
            name: newCheckParams.name,
            fileData: checkCompareResult.getBuffer()
          });
          compareResult.diffId = diffSnapshot.id;
          compareResult.diffSnapshot = diffSnapshot;
        }
        compareResult.status = "failed";
      } else {
        compareResult.status = "passed";
      }
      checkCompareResult.totalCheckHandleTime = process.hrtime(executionTimer).toString();
      compareResult.result = JSON.stringify(checkCompareResult, null, "	");
    } catch (e) {
      compareResult.status = "failed";
      compareResult.result = JSON.stringify({ server_error: `error during comparing - ${errMsg(e)}` });
      compareResult.failReasons.push("internal_server_error");
      throw new ApiError_default(import_http_status6.default.INTERNAL_SERVER_ERROR, `error during comparing: ${errMsg(e)}`);
    }
  }
  if (compareResult.failReasons.length > 0) {
    compareResult.status = "failed";
  }
  return compareResult;
};
var createCheckParams = (checkParam, suite, app, test, currentUser) => ({
  test: test.id,
  name: checkParam.name,
  status: "pending",
  viewport: checkParam.viewport,
  browserName: checkParam.browserName,
  browserVersion: checkParam.browserVersion,
  browserFullVersion: checkParam.browserFullVersion,
  os: checkParam.os,
  updatedDate: Date.now(),
  suite: suite.id,
  app: app.id,
  branch: checkParam.branch,
  domDump: checkParam.domDump,
  run: test.run.toString(),
  creatorId: currentUser._id.toString(),
  creatorUsername: currentUser.username,
  hashCode: checkParam.hashCode,
  failReasons: []
});
var createCheck = async (checkParam, test, suite, app, currentUser, skipSaveOnCompareError = false) => {
  const logOpts5 = {
    scope: "createCheck",
    user: currentUser.username,
    itemType: "check",
    msgType: "CREATE"
  };
  let actualSnapshot;
  let currentBaselineSnapshot;
  const newCheckParams = createCheckParams(checkParam, suite, app, test, currentUser);
  const checkIdent = buildIdentObject(newCheckParams);
  let check = null;
  const totalCheckHandleTime = 0;
  const addCheck = (test2, check2) => {
    if (test2.checks) {
      test2.checks.push(check2.id);
    } else {
      test2.checks = [check2.id];
    }
  };
  try {
    const { needFilesStatus, snapshotFoundedByHashcode } = await isNeedFiles(checkParam, logOpts5);
    if (needFilesStatus) return { status: "needFiles" };
    actualSnapshot = await prepareActualSnapshot(checkParam, snapshotFoundedByHashcode, logOpts5);
    newCheckParams.actualSnapshotId = actualSnapshot.id;
    logger_default.info(`find a baseline for the check with identifier: '${JSON.stringify(checkIdent)}'`, logOpts5);
    const storedBaseline = await getAcceptedBaseline(checkIdent);
    const inspectBaselineResult = await inspectBaseline(newCheckParams, storedBaseline, checkIdent, actualSnapshot, logOpts5);
    Object.assign(newCheckParams, inspectBaselineResult.inspectBaselineParams);
    currentBaselineSnapshot = inspectBaselineResult.currentBaselineSnapshot;
    const compareResult = await compare(currentBaselineSnapshot, actualSnapshot, newCheckParams, skipSaveOnCompareError, currentUser);
    Object.assign(newCheckParams, compareResult);
    logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts5);
    check = await Check_model_default.create(newCheckParams);
    const savedCheck = await check.save();
    logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts5);
    logOpts5.ref = String(check.id);
    logger_default.debug(`update test with check id: '${check.id}'`, logOpts5);
    addCheck(test, check);
    test.markedAs = await calculateAcceptedStatus(check.test);
    test.updatedDate = /* @__PURE__ */ new Date();
    await test.save();
    logger_default.debug("update suite and run", logOpts5);
    await updateItemDate("VRSSuite", check.suite);
    await updateItemDate("VRSRun", check.run);
    const lastSuccessCheck = await getLastSuccessCheck(checkIdent);
    const checkObject = savedCheck.toObject();
    const result = {
      ...checkObject,
      currentSnapshot: actualSnapshot,
      expectedSnapshot: currentBaselineSnapshot,
      diffSnapshot: compareResult.diffSnapshot,
      executeTime: totalCheckHandleTime,
      lastSuccess: lastSuccessCheck ? lastSuccessCheck.id : null
    };
    return result;
  } catch (e) {
    newCheckParams.status = "failed";
    newCheckParams.result = `{ "server error": "${errMsg(e)}" }`;
    newCheckParams.failReasons.push("internal_server_error");
    if (!check) {
      logger_default.debug(`create the new check document with params: '${prettyCheckParams_default(newCheckParams)}'`, logOpts5);
      check = await Check_model_default.create(newCheckParams);
      await check.save();
    } else {
      check.set(newCheckParams);
      await check.save();
    }
    logger_default.debug(`the check with id: '${check.id}', was created, will updated with data during creating process`, logOpts5);
    logOpts5.ref = check.id;
    logger_default.debug(`update test with check id: '${check.id}'`, logOpts5);
    addCheck(test, check);
    await test.save();
    throw new ApiError_default(import_http_status7.default.INTERNAL_SERVER_ERROR, errMsg(e));
  }
};
var getIdent = () => ident;
var getBaselines = async (filter, options) => {
  const logOpts5 = {
    scope: "getBaselines",
    itemType: "baseline",
    msgType: "GET"
  };
  const app = await App_model_default.findOne({ name: filter.app });
  if (!app) {
    logger_default.error(`Cannot find the app: '${filter.app}'`, logOpts5);
    return {};
  }
  filter.app = app._id;
  logger_default.debug(`Get baselines with filter: '${JSON.stringify(filter)}', options: '${JSON.stringify(options)}'`, logOpts5);
  return Baseline_model_default.paginate(filter, options);
};

// src/server/services/user.service.ts
var user_service_exports = {};
__export(user_service_exports, {
  createUser: () => createUser2,
  deleteUserById: () => deleteUserById,
  getUserByEmail: () => getUserByEmail,
  getUserById: () => getUserById,
  queryUsers: () => queryUsers,
  updateUserById: () => updateUserById
});
var import_http_status8 = __toESM(require("http-status"));
var createUser2 = async (userBody) => {
  if (await User_model_default.isEmailTaken(userBody.username)) {
    throw new ApiError_default(import_http_status8.default.BAD_REQUEST, "Email already taken");
  }
  const logOpts5 = {
    msgType: "CREATE",
    itemType: "user",
    ref: userBody.username,
    scope: "createUser"
  };
  logger_default.debug(`create the user with name '${userBody.username}', params: '${JSON.stringify(userBody)}'`, logOpts5);
  const user = await User_model_default.create({ ...userBody, createdDate: Date.now() });
  const updatedUser = await user.setPassword(userBody.password);
  await updatedUser.save();
  logger_default.debug(`password for user: '${userBody.username}' set successfully`, logOpts5);
  const userWithSelectedFields = await User_model_default.findById(updatedUser._id).select("username firstName lastName role createdDate updatedDate createdDate").exec();
  return userWithSelectedFields;
};
var queryUsers = async (filter, options) => {
  const users = await User_model_default.paginate(filter, options);
  return users;
};
var getUserById = async (id2) => User_model_default.findById(id2).select("username firstName lastName role createdDate updatedDate createdDate").exec();
var getUserByEmail = async (email) => User_model_default.findOne({ email });
var updateUserById = async (userId, updateBody) => {
  const logOpts5 = {
    msgType: "UPDATE",
    itemType: "user",
    scope: "updateUserById",
    ref: userId
  };
  logger_default.info(`update user with id: '${userId}' name '${updateBody.username}', params: '${JSON.stringify(updateBody)}'`, logOpts5);
  const user = await getUserById(userId);
  if (!user) {
    throw new ApiError_default(import_http_status8.default.NOT_FOUND, "User not found");
  }
  if (updateBody.email && await User_model_default.isEmailTaken(updateBody.email, userId)) {
    throw new ApiError_default(import_http_status8.default.BAD_REQUEST, "Email already taken");
  }
  if (updateBody.password) {
    logger_default.debug(`update password for '${updateBody.username}'`, logOpts5);
    await user.setPassword(updateBody.password);
    await user.save();
    logger_default.debug(`password for '${updateBody.username}' was updated`, logOpts5);
  }
  logger_default.debug(`user '${updateBody.username}' was updated successfully`, logOpts5);
  const { password, ...newupdateBody } = updateBody;
  Object.assign(user, {
    ...newupdateBody,
    updatedDate: Date.now()
  });
  await user.save();
  return user;
};
var deleteUserById = async (userId) => User_model_default.findByIdAndDelete(userId).exec();

// src/server/services/check.service.ts
var check_service_exports = {};
__export(check_service_exports, {
  accept: () => accept2,
  remove: () => remove5,
  update: () => update
});

// src/server/services/snapshot.service.ts
var import_fs4 = __toESM(require("fs"));
var import_path5 = __toESM(require("path"));
var logOpts4 = {
  scope: "snapshot_helper",
  msgType: "API"
};
var removeSnapshotFile = async (snapshot) => {
  let relatedSnapshots;
  if (snapshot.filename) {
    relatedSnapshots = await Snapshot_model_default.find({ filename: snapshot.filename });
    logger_default.debug(`there are '${relatedSnapshots.length}' snapshots with filename: '${snapshot.filename}'`, logOpts4);
  }
  const isLastSnapshotFile = () => {
    if (!snapshot.filename) {
      return true;
    }
    return relatedSnapshots.length === 0;
  };
  logger_default.debug({ isLastSnapshotFile: isLastSnapshotFile() });
  if (isLastSnapshotFile()) {
    const imagePath = import_path5.default.join(config.defaultImagesPath, snapshot.filename);
    logger_default.silly(`path: ${imagePath}`, logOpts4);
    if (import_fs4.default.existsSync(imagePath)) {
      logger_default.debug(`removing file: '${imagePath}'`, logOpts4, {
        msgType: "REMOVE",
        itemType: "file"
      });
      import_fs4.default.unlinkSync(imagePath);
    }
  }
};
var remove4 = async (id2) => {
  const logOpts5 = {
    scope: "removeSnapshot",
    msgType: "REMOVE",
    itemType: "snapshot",
    ref: id2
  };
  logger_default.silly(`deleting snapshot with id: '${id2}'`, logOpts5);
  if (!id2) {
    logger_default.warn("id is empty");
    return;
  }
  const snapshot = await Snapshot_model_default.findById(id2).lean().exec();
  if (!snapshot) {
    logger_default.warn(`cannot find snapshot with id: '${id2}'`);
    return;
  }
  const baseline = await Baseline_model_default.findOne({ snapshootId: id2 });
  if (baseline) {
    logger_default.debug(`snapshot: '${id2}' is related to a baseline, skipping deletion`, logOpts5);
    return;
  }
  logger_default.debug(`snapshot: '${id2}' is not related to a baseline, attempting to remove it`, logOpts5);
  await Snapshot_model_default.findByIdAndDelete(id2);
  logger_default.debug(`snapshot: '${id2}' was removed`, logOpts5);
  const imagePath = import_path5.default.join(config.defaultImagesPath, snapshot.filename);
  logger_default.debug(`attempting to remove snapshot file, id: '${snapshot._id}', filename: '${imagePath}'`, logOpts5);
  await removeSnapshotFile(snapshot);
};

// src/server/services/check.service.ts
async function calculateTestStatus(testId) {
  const checksInTest = await Check_model_default.find({ test: testId });
  const statuses = checksInTest.map((x) => x.status[0]);
  let testCalculatedStatus = "Failed";
  if (statuses.every((x) => x === "new" || x === "passed")) {
    testCalculatedStatus = "Passed";
  }
  if (statuses.every((x) => x === "new")) {
    testCalculatedStatus = "New";
  }
  return testCalculatedStatus;
}
var validateBaselineParam = (params) => {
  const mandatoryParams = ["markedAs", "markedById", "markedByUsername", "markedDate"];
  for (const param of mandatoryParams) {
    if (!params[param]) {
      const errMsg2 = `invalid baseline parameters, '${param}' is empty, params: ${JSON.stringify(params)}`;
      logger_default.error(errMsg2);
      throw new Error(errMsg2);
    }
  }
};
async function createNewBaseline(params) {
  const logOpts5 = {
    scope: "createNewBaseline",
    msgType: "CREATE"
  };
  validateBaselineParam(params);
  const identFields = buildIdentObject(params);
  const lastBaseline = await Baseline_model_default.findOne(identFields).exec();
  const sameBaseline = await Baseline_model_default.findOne({ ...identFields, snapshootId: params.actualSnapshotId }).exec();
  const baselineParams = lastBaseline?.ignoreRegions ? { ...identFields, ignoreRegions: lastBaseline.ignoreRegions } : identFields;
  if (sameBaseline) {
    logger_default.debug(`the baseline with same ident and snapshot id: ${params.actualSnapshotId} already exist`, logOpts5);
  } else {
    logger_default.debug(`the baseline with same ident and snapshot id: ${params.actualSnapshotId} does not exist,
         create new one, baselineParams: ${JSON.stringify(baselineParams)}`, logOpts5);
  }
  logger_default.silly({ sameBaseline });
  const resultedBaseline = sameBaseline || await Baseline_model_default.create(baselineParams);
  resultedBaseline.markedAs = params.markedAs;
  resultedBaseline.markedById = params.markedById;
  resultedBaseline.markedByUsername = params.markedByUsername;
  resultedBaseline.lastMarkedDate = params.markedDate;
  resultedBaseline.createdDate = /* @__PURE__ */ new Date();
  resultedBaseline.snapshootId = params.actualSnapshotId;
  return resultedBaseline.save();
}
var accept2 = async (id2, baselineId, user) => {
  const logOpts5 = {
    msgType: "ACCEPT",
    itemType: "check",
    ref: id2,
    user: user?.username,
    scope: "accept"
  };
  logger_default.debug(`accept check: ${id2}`, logOpts5);
  const check = await Check_model_default.findById(id2).exec();
  if (!check) throw new Error(`cannot find check with id: ${id2}`);
  const test = await Test_model_default.findById(check.test).exec();
  if (!test) throw new Error(`cannot find test with id: ${check.test}`);
  check.markedById = user._id;
  check.markedByUsername = user.username;
  check.markedDate = /* @__PURE__ */ new Date();
  check.markedAs = "accepted";
  check.status = check.status[0] === "new" ? ["new"] : ["passed"];
  check.updatedDate = /* @__PURE__ */ new Date();
  logger_default.debug(`update check with options: '${JSON.stringify(check.toObject())}'`, logOpts5);
  await createNewBaseline(check.toObject());
  await check.save();
  const testCalculatedStatus = await calculateTestStatus(String(check.test));
  const testCalculatedAcceptedStatus = await calculateAcceptedStatus(check.test);
  test.status = testCalculatedStatus;
  test.markedAs = testCalculatedAcceptedStatus;
  test.updatedDate = /* @__PURE__ */ new Date();
  await Suite_model_default.findByIdAndUpdate(check.suite, { updatedDate: Date.now() });
  logger_default.debug(`update test with status: '${testCalculatedStatus}', marked: '${testCalculatedAcceptedStatus}'`, logOpts5, {
    msgType: "UPDATE",
    itemType: "test",
    ref: test._id
  });
  await test.save();
  await check.save();
  logger_default.debug(`check with id: '${id2}' was updated`, logOpts5);
  return check;
};
async function removeCheck(id2, user) {
  const logMeta = {
    scope: "removeCheck",
    itemType: "check",
    ref: id2,
    msgType: "REMOVE",
    user: user?.username
  };
  try {
    const check = await Check_model_default.findByIdAndDelete(id2).exec();
    if (!check) throw new Error(`cannot find check with id: ${id2}`);
    logger_default.debug(`check with id: '${id2}' was removed, update test: ${check.test}`, logMeta);
    const test = await Test_model_default.findById(check.test).exec();
    if (!test) throw new Error(`cannot find test with id: ${check.test}`);
    const testCalculatedStatus = await calculateTestStatus(String(check.test));
    const testCalculatedAcceptedStatus = await calculateAcceptedStatus(check.test);
    test.status = testCalculatedStatus;
    test.markedAs = testCalculatedAcceptedStatus;
    test.updatedDate = /* @__PURE__ */ new Date();
    await updateItemDate("VRSSuite", check.suite);
    await test.save();
    if (check.baselineId && String(check.baselineId) !== "undefined") {
      logger_default.debug(`try to remove the snapshot, baseline: ${check.baselineId}`, logMeta);
      await remove4(check.baselineId.toString());
    }
    if (check.actualSnapshotId && String(check.baselineId) !== "undefined") {
      logger_default.debug(`try to remove the snapshot, actual: ${check.actualSnapshotId}`, logMeta);
      await remove4(check.actualSnapshotId.toString());
    }
    if (check.diffId && String(check.baselineId) !== "undefined") {
      logger_default.debug(`try to remove snapshot, diff: ${check.diffId}`, logMeta);
      await remove4(check.diffId.toString());
    }
    return check;
  } catch (e) {
    const errMsg2 = `cannot remove a check with id: '${id2}', error: '${e instanceof Error ? e.stack : String(e)}'`;
    logger_default.error(errMsg2, logMeta);
    throw new Error(errMsg2);
  }
}
var remove5 = async (id2, user) => {
  const logOpts5 = {
    scope: "removeCheck",
    itemType: "check",
    ref: id2,
    user: user?.username,
    msgType: "REMOVE"
  };
  logger_default.info(`remove check with, id: '${id2}', user: '${user.username}'`, logOpts5);
  return removeCheck(id2, user);
};
var update = async (id2, opts, user) => {
  const logMeta = {
    msgType: "UPDATE",
    itemType: "check",
    ref: id2,
    user,
    scope: "updateCheck"
  };
  logger_default.debug(`update check with id '${id2}' with params '${JSON.stringify(opts, null, 2)}'`, logMeta);
  const check = await Check_model_default.findOneAndUpdate({ _id: id2 }, opts, { new: true }).exec();
  if (!check) throw new Error(`cannot find check with id: ${id2}`);
  const test = await Test_model_default.findOne({ _id: check.test }).exec();
  if (!test) throw new Error(`cannot find test with id: ${check.test}`);
  test.status = await calculateTestStatus(String(check.test));
  await updateItemDate("VRSCheck", check);
  await updateItemDate("VRSTest", test);
  await test.save();
  await check.save();
  return check;
};

// src/server/controllers/baseline.controller.ts
var get3 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
  const result = await generic_service_exports.get("VRSBaseline", filter, options);
  res.send(result);
});
var put2 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status9.default.BAD_REQUEST, "Cannot update the baseline - Id not found");
  const result = await generic_service_exports.put("VRSBaseline", id2, req.body, req?.user);
  res.send(result);
});

// src/server/controllers/check.controller.ts
var import_http_status10 = __toESM(require("http-status"));
var get4 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
  if (req.user?.role === "user") {
    filter.creatorUsername = req.user?.username;
  }
  const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
  const result = await generic_service_exports.get("VRSCheck", filter, options);
  res.send(result);
});
var getViaPost = catchAsync_default(async (req, res) => {
  const filter = req.body.filter ? pick_default(req.body, ["filter"]).filter : {};
  const options = req.body.options ? pick_default(req.body, ["options"]).options : {};
  const result = await generic_service_exports.get("VRSCheck", filter, options);
  res.send(result);
});
var update2 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot accept the check - Id not found");
  const opts = removeEmptyProperties(req.body);
  const user = req?.user?.username;
  const result = await check_service_exports.update(id2, opts, user);
  res.send(result);
});
var accept3 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot accept the check - Id not found");
  if (!req.body.baselineId) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, `Cannot accept the check: ${id2} - new Baseline Id not found`);
  const result = await check_service_exports.accept(id2, req.body.baselineId, req?.user);
  res.send(result);
});
var remove6 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status10.default.BAD_REQUEST, "Cannot remove the check - Id not found");
  const result = await check_service_exports.remove(id2, req?.user);
  res.send(result);
});

// src/server/controllers/client.controller.ts
var import_http_status11 = __toESM(require("http-status"));

// src/server/schemas/CreateCheck.shema.ts
var import_zod8 = require("zod");
var createCheckParamsSchema = import_zod8.z.object({
  branch: import_zod8.z.string().min(1),
  appName: import_zod8.z.string().min(1),
  suitename: import_zod8.z.string().min(1),
  testid: import_zod8.z.string().regex(/^[a-f0-9]{24}$/),
  // Regex for 24 hex characters
  name: import_zod8.z.string().min(1),
  viewport: import_zod8.z.string().regex(/^\d+x\d+$/),
  // "WidthxHeight" format
  browserName: import_zod8.z.string().min(1),
  browserVersion: import_zod8.z.string().min(1),
  browserFullVersion: import_zod8.z.string(),
  os: import_zod8.z.string().min(1),
  hashcode: import_zod8.z.string().length(128)
  // Assuming hashcode is always 128 chars length
});

// src/server/schemas/GetBaseline.shema.ts
var import_zod9 = require("zod");
var RequiredIdentOptionsSchema = import_zod9.z.object({
  name: import_zod9.z.string().min(1),
  viewport: import_zod9.z.string().min(3),
  browserName: import_zod9.z.string().min(1),
  os: import_zod9.z.string().min(1),
  app: import_zod9.z.string().min(1),
  branch: import_zod9.z.string().min(1)
});
var IdentJSONStringSchema = import_zod9.z.string().optional().refine((data) => {
  if (!data) return false;
  try {
    const parsed = JSON.parse(data);
    RequiredIdentOptionsSchema.parse(parsed);
    return true;
  } catch (e) {
    return false;
  }
}, {
  message: "Invalid JSON string or does not match the required schema"
}).openapi({
  description: "baseline filter based on ident",
  example: '{"name": "Login page", "viewport": "1366x768", "browserName": "chrome", "os": "macOS", "app": "My App", "branch": "master"}'
});

// src/server/schemas/App.schema.ts
var import_zod_to_openapi4 = require("@asteasolutions/zod-to-openapi");
var import_zod10 = require("zod");
(0, import_zod_to_openapi4.extendZodWithOpenApi)(import_zod10.z);
var registry2 = new import_zod_to_openapi4.OpenAPIRegistry();
var AppInfoRespSchema = import_zod10.z.object({
  version: commonValidations.version
});
var AppRespSchema = import_zod10.z.object({
  _id: commonValidations.id,
  id: commonValidations.id,
  name: import_zod10.z.string().min(1, "AppRespSchema: the name is empty").openapi({ example: "Admin Panel" })
});

// src/server/controllers/client.controller.ts
var startSession2 = catchAsync_default(async (req, res) => {
  const params = pick_default(
    req.body,
    [
      "name",
      "status",
      "app",
      "tags",
      "branch",
      "viewport",
      "browser",
      "browserVersion",
      "browserFullVersion",
      "os",
      "run",
      "runident",
      "suite"
    ]
  );
  const result = await client_service_exports.startSession(params, String(req?.user?.username));
  res.send(result);
});
var endSession2 = catchAsync_default(async (req, res) => {
  const testId = req.params.testid;
  if (!testId || testId === "undefined") {
    throw new ApiError_default(import_http_status11.default.BAD_REQUEST, "Cannot stop test Session testId is empty");
  }
  const result = await client_service_exports.endSession(testId, String(req?.user?.username));
  res.send(result);
});
var createCheck2 = catchAsync_default(async (req, res) => {
  const params = req.body;
  paramsGuard(params, "createCheck, params", createCheckParamsSchema);
  const apiKey = req.headers.apikey;
  const currentUser = await User_model_default.findOne({ apiKey });
  if (!currentUser) throw new ApiError_default(import_http_status11.default.NOT_FOUND, `cannot get current user by API`);
  const logOpts5 = {
    scope: "createCheck",
    user: currentUser.username,
    itemType: "check",
    msgType: "CREATE"
  };
  logger_default.info(`start to create check: '${params.name}'`, logOpts5);
  logger_default.debug(`try to find test with id: '${params.testid}'`, logOpts5);
  const test = await Test_model_default.findById(params.testid);
  if (!test) {
    const errMsg2 = `can't find test with id: '${params.testid}', parameters: '${JSON.stringify(req.body)}', username: '${currentUser.username}', apiKey: ${apiKey}`;
    throw new ApiError_default(import_http_status11.default.NOT_FOUND, errMsg2);
  }
  const app = await App_model_default.findOne({ name: params.appName });
  if (!app) throw new ApiError_default(import_http_status11.default.NOT_FOUND, `cannot get the app: ${params.appName}`);
  const suite = await Suite_model_default.findOne({ name: params.suitename });
  if (!suite) throw new ApiError_default(import_http_status11.default.NOT_FOUND, `cannot get the suite: ${params.suitename}`);
  await updateItem("VRSTest", { _id: test.id }, {
    suite: suite.id,
    creatorId: currentUser._id,
    creatorUsername: currentUser.username
  });
  const result = await client_service_exports.createCheck(
    {
      branch: params.branch,
      hashCode: params.hashcode,
      // testId: params.testid,
      name: params.name,
      viewport: params.viewport,
      browserName: params.browserName,
      browserVersion: params.browserVersion,
      browserFullVersion: params.browserFullVersion,
      os: params.os,
      files: req.files,
      domDump: params.domdump,
      vShifting: params.vShifting
    },
    test,
    suite,
    app,
    currentUser
  );
  if (result.status === "needFiles") {
    res.status(206).json({
      status: "requiredFileData",
      message: "could not find a snapshot with such a hash code, please add image file data and resend request",
      hashCode: params.hashcode
    });
    return;
  }
  res.json(result);
});
var getIdent2 = catchAsync_default(async (req, res) => {
  const result = client_service_exports.getIdent();
  res.send(result);
});
var getBaselines2 = catchAsync_default(async (req, res) => {
  const filter = pick_default(
    req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : {},
    ["name", "viewport", "browserName", "os", "app", "branch"]
  );
  paramsGuard(filter, "getBaseline, filter", RequiredIdentOptionsSchema);
  const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
  const result = await client_service_exports.getBaselines(filter, options);
  res.send(result);
});
var getSnapshots = catchAsync_default(async (req, res) => {
  const filter = pick_default(
    req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : {},
    ["_id", "name", "imghash", "createdDate", "filename", "id"]
  );
  const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
  const result = await generic_service_exports.get("VRSSnapshot", filter, options);
  res.send(result);
});

// src/server/controllers/logs.controller.ts
var import_http_status12 = __toESM(require("http-status"));
var import_bson3 = require("bson");
var getLogs = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? import_bson3.EJSON.parse(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await logs_service_exports.queryLogs(filter, options);
  res.send(result);
});
var distinct2 = catchAsync_default(async (req, res) => {
  const { field } = pick_default(req.query, ["field"]);
  const result = await logs_service_exports.distinct(String(field));
  res.send(result);
});
var createLog = catchAsync_default(async (req, res) => {
  const user = await logs_service_exports.createLogs(req.body);
  res.status(import_http_status12.default.CREATED).send(user);
});

// src/server/controllers/snapshots.controller.ts
var import_bson4 = require("bson");
var get5 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? import_bson4.EJSON.parse(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await generic_service_exports.get("VRSSnapshot", filter, options);
  res.send(result);
});

// src/server/controllers/tasks.controller.ts
var task_test2 = catchAsync_default(async (req, res) => {
  const { options } = pick_default(req.query, ["options"]);
  await tasks_service_exports.task_test(String(options), req, res);
});
var task_handle_old_checks2 = catchAsync_default(async (req, res) => {
  const options = pick_default(req.query, ["days", "remove"]);
  await tasks_service_exports.task_handle_old_checks(options, res);
});
var task_handle_database_consistency2 = catchAsync_default(async (req, res) => {
  const options = pick_default(req.query, ["days", "clean"]);
  await tasks_service_exports.task_handle_database_consistency(options, res);
});
var task_remove_old_logs2 = catchAsync_default(async (req, res) => {
  const options = pick_default(req.query, ["days", "statistics"]);
  await tasks_service_exports.task_remove_old_logs(options, res);
});
var status2 = catchAsync_default(async (req, res) => {
  res.send(await tasks_service_exports.status(req.user));
});
var screenshots2 = catchAsync_default(async (req, res) => {
  res.send(await tasks_service_exports.screenshots());
});
var loadTestUser2 = catchAsync_default(async (req, res) => {
  res.send(await tasks_service_exports.loadTestUser());
});

// src/server/controllers/test.controller.ts
var import_http_status13 = __toESM(require("http-status"));
var getTest = catchAsync_default(async (req, res) => {
  const filter = {
    ...deserializeIfJSON_default(String(req.query.base_filter)),
    ...deserializeIfJSON_default(String(req.query.filter))
  };
  if (req.user?.role === "user") {
    filter.creatorUsername = req.user?.username;
  }
  const options = pick_default(req.query, ["sortBy", "limit", "page", "populate"]);
  const result = await test_service_exports.queryTests(filter, options);
  res.status(import_http_status13.default.OK).send(result);
});
var distinct_with_filter = catchAsync_default(async (req, res) => {
  const filter = req.query.filter ? deserializeIfJSON_default(String(req.query.filter)) : void 0;
  const options = { ...pick_default(req.query, ["sortBy", "limit", "page", "populate"]), field: req.params.field };
  const result = await test_service_exports.queryTestsDistinct(filter, options);
  res.status(import_http_status13.default.OK).send(result);
});
var distinct3 = catchAsync_default(async (req, res) => {
  const filter = {};
  const options = { ...pick_default(req.query, ["sortBy", "limit", "page", "populate"]), field: req.params.id };
  const result = await test_service_exports.queryTestsDistinct(filter, options);
  res.status(import_http_status13.default.OK).send(result);
});
var remove7 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status13.default.BAD_REQUEST, "Cannot remove the test - Id not found");
  if (!req.user) throw new ApiError_default(import_http_status13.default.BAD_REQUEST, "Cannot remove the test - req.user is empty");
  const result = await test_service_exports.remove(id2, req?.user);
  res.send(result);
});
var accept4 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!id2) throw new ApiError_default(import_http_status13.default.BAD_REQUEST, "Cannot accept the check - Id not found");
  if (!req.user) throw new ApiError_default(import_http_status13.default.BAD_REQUEST, "Cannot accept the check - req.user is empty");
  const result = await test_service_exports.accept(id2, req?.user);
  res.send(result);
});

// src/server/controllers/users.controller.ts
var users_controller_exports = {};
__export(users_controller_exports, {
  create: () => create,
  current: () => current,
  get: () => get6,
  getById: () => getById,
  remove: () => remove8,
  update: () => update3
});
var import_http_status14 = __toESM(require("http-status"));
var import_bson5 = require("bson");
var current = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    scope: "users",
    msgType: "GET_CURRENT_USER"
  };
  logger_default.debug(`current user is: '${req?.user?.username || "not_logged"}'`, logOpts5);
  res.status(import_http_status14.default.OK).json({
    id: req?.user?.id,
    username: req?.user?.username,
    firstName: req?.user?.firstName,
    lastName: req?.user?.lastName,
    role: req?.user?.role
  });
});
var get6 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? import_bson5.EJSON.parse(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await user_service_exports.queryUsers(filter, options);
  res.send(result);
});
var getById = catchAsync_default(async (req, res) => {
  const user = await user_service_exports.getUserById(req.params.userId);
  res.send(user);
});
var create = catchAsync_default(async (req, res) => {
  const logOpts5 = {
    scope: "users",
    msgType: "CREATE"
  };
  try {
    const userData = pick_default(req.body, [
      "username",
      "firstName",
      "lastName",
      "role",
      "password",
      "apiKey",
      "expiration",
      "meta"
    ]);
    const user = await user_service_exports.createUser(userData);
    res.status(import_http_status14.default.CREATED).send(user);
  } catch (e) {
    if (e instanceof ApiError_default && e.statusCode) {
      logger_default.error(e, logOpts5);
      res.status(e.statusCode).json({ message: e.message });
    } else {
      logger_default.error(errMsg(e), logOpts5);
      throw e;
    }
  }
});
var update3 = catchAsync_default(async (req, res) => {
  const user = await user_service_exports.updateUserById(req.params.userId, req.body);
  res.send(user);
});
var remove8 = catchAsync_default(async (req, res) => {
  await user_service_exports.deleteUserById(req.params.userId);
  res.status(import_http_status14.default.NO_CONTENT).send();
});

// src/server/controllers/app.controller.ts
var app_controller_exports = {};
__export(app_controller_exports, {
  get: () => get7,
  info: () => info
});
var import_http_status15 = __toESM(require("http-status"));
var info = catchAsync_default(async (req, res) => {
  res.status(import_http_status15.default.OK).json({ version: config.version });
});
var get7 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? deserializeIfJSON_default(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await app_service_exports.get(filter, options);
  res.send(result);
});

// src/server/controllers/settings.controller.ts
var getSettings = catchAsync_default(async (req, res) => {
  const AppSettings3 = await appSettings;
  const result = AppSettings3.cache;
  res.json(result);
});
var updateSetting = catchAsync_default(async (req, res) => {
  const AppSettings3 = await appSettings;
  const { name } = req.params;
  await AppSettings3.set(name, req.body.value);
  if (req.body.enabled === false) {
    await AppSettings3.disable(name);
  } else {
    await AppSettings3.enable(name);
  }
  res.json({ message: "success" });
});

// src/server/controllers/runs.controller.ts
var import_bson6 = require("bson");
var get8 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? import_bson6.EJSON.parse(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await generic_service_exports.get("VRSRun", filter, options);
  res.send(result);
});
var remove9 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!req.user) throw new Error("req.user is empty");
  const result = await run_service_exports.remove(id2, req?.user);
  res.send(result);
});

// src/server/controllers/suite.controller.ts
var import_bson7 = require("bson");
var get9 = catchAsync_default(async (req, res) => {
  const filter = typeof req.query.filter === "string" ? import_bson7.EJSON.parse(req.query.filter) : {};
  const options = pick_default(req.query, ["sortBy", "limit", "page"]);
  const result = await generic_service_exports.get("VRSSuite", filter, options);
  res.send(result);
});
var remove10 = catchAsync_default(async (req, res) => {
  const { id: id2 } = req.params;
  if (!req.user) throw new Error("req.user is empty");
  const result = await suite_service_exports.remove(id2, req?.user);
  res.send(result);
});

// src/server/schemas/common/RequestPagination.schema.ts
var import_zod_to_openapi6 = require("@asteasolutions/zod-to-openapi");
var import_zod12 = require("zod");

// src/server/schemas/common/requestQueryFilterSchema.schema.ts
var import_zod_to_openapi5 = require("@asteasolutions/zod-to-openapi");
var import_zod11 = require("zod");
(0, import_zod_to_openapi5.extendZodWithOpenApi)(import_zod11.z);
var requestQueryFilterSchema = import_zod11.z.string().optional().refine((data) => {
  if (!data) return false;
  try {
    const parsed = JSON.parse(data);
    const valueSchema = import_zod11.z.lazy(() => import_zod11.z.union([
      import_zod11.z.string(),
      import_zod11.z.number(),
      import_zod11.z.boolean(),
      import_zod11.z.array(import_zod11.z.any()),
      import_zod11.z.record(import_zod11.z.any())
    ]));
    const schema = import_zod11.z.record(valueSchema);
    schema.parse(parsed);
    return true;
  } catch (e) {
    return false;
  }
}, {
  message: "Invalid JSON string or does not match the required schema"
}).openapi({ example: '{"key1": "value1", "key2": 123, "key3": true, "$and":[{"name":"CheckName"}]}' });

// src/server/schemas/common/RequestPagination.schema.ts
(0, import_zod_to_openapi6.extendZodWithOpenApi)(import_zod12.z);
var RequestPaginationSchema = import_zod12.z.object({
  filter: requestQueryFilterSchema.optional(),
  limit: commonValidations.positiveNumberString.optional().openapi({ example: "10" }),
  page: commonValidations.positiveNumberString.optional().openapi({ example: "1" }),
  sortBy: import_zod12.z.string().optional().openapi({ example: "name:desc" }),
  populate: import_zod12.z.string().optional().openapi({ example: "test" })
});

// src/server/schemas/utils/createRequestQuerySchema.ts
var import_zod13 = require("zod");
var createRequestQuerySchema = (schema) => import_zod13.z.object({ query: schema });

// src/server/routes/v1/app.route.ts
var registry3 = new import_zod_to_openapi7.OpenAPIRegistry();
var router2 = import_express2.default.Router();
registry3.registerPath({
  method: "get",
  path: "/v1/app/info",
  summary: "The current Syngrisi instance information.",
  tags: ["App"],
  responses: createApiResponse(AppInfoRespSchema, "Success")
});
router2.get(
  "/info",
  validateRequest(SkipValid, "get, /v1/app/info"),
  app_controller_exports.info
);
registry3.registerPath({
  method: "get",
  path: "/v1/app",
  summary: "List of applications (projects) with pagination, and optional filtering and sorting.",
  tags: ["App"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(AppRespSchema, "Success")
});
router2.get(
  "/",
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/app"),
  app_controller_exports.get
);
var app_route_default = router2;

// src/server/routes/v1/tests.route.ts
var import_express3 = __toESM(require("express"));
var import_zod_to_openapi8 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Test.schema.ts
var import_zod14 = require("zod");
var TestGetSchema = import_zod14.z.object({
  _id: commonValidations.id,
  name: import_zod14.z.string().min(1).openapi({
    description: "Name of the test",
    example: "Get IP"
  }),
  status: import_zod14.z.string().openapi({
    description: "Status of the test",
    example: "Failed"
  }),
  browserName: import_zod14.z.string().openapi({
    description: "Name of the browser",
    example: "chrome"
  }),
  browserVersion: import_zod14.z.string().openapi({
    description: "Version of the browser",
    example: "125"
  }),
  branch: import_zod14.z.string().openapi({
    description: "Branch name",
    example: "master"
  }),
  tags: import_zod14.z.array(import_zod14.z.string()).openapi({
    description: "Tags associated with the test",
    example: ["@smoke", "@regression"]
  }),
  viewport: import_zod14.z.string().openapi({
    description: "Viewport size",
    example: "1366x768"
  }),
  os: import_zod14.z.string().openapi({
    description: "Operating system",
    example: "macOS"
  }),
  app: commonValidations.id.openapi({
    description: "Application identifier",
    example: "6651dd45b9c3e1e0b8c1ce26"
  }),
  blinking: import_zod14.z.number().openapi({
    description: "Blinking count",
    example: 0
  }),
  updatedDate: commonValidations.date.openapi({
    description: "Last update date of the test",
    example: "2024-06-13T19:55:40.108Z"
  }),
  startDate: commonValidations.date.openapi({
    description: "Start date of the test",
    example: "2024-06-13T19:54:28.409Z"
  }),
  checks: import_zod14.z.array(commonValidations.id).openapi({
    description: "List of checks associated with the test",
    example: ["666b4e7e421977cbf466b458", "666b4ebc421977cbf466b47c"]
  }),
  suite: commonValidations.id.openapi({
    description: "Suite identifier",
    example: "666b3b828833d0cf24a670d7"
  }),
  run: commonValidations.id.openapi({
    description: "Run identifier",
    example: "666b4e74421977cbf466b443"
  }),
  creatorId: commonValidations.id.openapi({
    description: "Creator identifier",
    example: "66519e582c2c701cc438ce59"
  }),
  creatorUsername: import_zod14.z.string().openapi({
    description: "Username of the creator",
    example: "Guest"
  }),
  markedAs: import_zod14.z.string().openapi({
    description: "Marked as status",
    example: "Unaccepted"
  }),
  calculatedViewport: import_zod14.z.string().openapi({
    description: "Calculated viewport size",
    example: "1366x768"
  }),
  id: commonValidations.id.openapi({
    description: "ID of the test",
    example: "666b4e74421977cbf466b446"
  })
});
var UpdateTestSchema = TestGetSchema.omit({ id: true, _id: true }).partial();
var TestAcceptSchema = import_zod14.z.object({
  id: commonValidations.id
});
var validIds = [
  "suite",
  "run",
  "markedAs",
  "creatorId",
  "creatorUsername",
  "name",
  "status",
  "browserName",
  "browserVersion",
  "branch",
  "tags",
  "viewport",
  "os",
  "app",
  "startDate"
];
var TestDistinctRequestFieldParamsSchema = import_zod14.z.object({
  field: import_zod14.z.enum(validIds).openapi({
    description: "Parameter identifier",
    example: "suite"
  })
});

// src/server/middlewares/ensureLogin/ensureLoggedIn.ts
var handleBasicAuth = async (req) => {
  const logOpts5 = {
    scope: "handleBasicAuth",
    msgType: "AUTH_API"
  };
  if (req.isAuthenticated()) {
    return { type: "success", status: 200 };
  }
  const AppSettings3 = await appSettings;
  if (!await AppSettings3.isAuthEnabled()) {
    const guest = await User_model_default.findOne({ username: "Guest" });
    const result2 = new Promise((resolve) => {
      req.logIn(guest, (err) => {
        if (err) {
          logger_default.error(`cannot find guest user: '${err}'`, logOpts5);
          resolve({
            type: "redirect",
            status: 301,
            value: `/auth?=Error: cannot find guest user: ${err}`,
            user: null
          });
        } else {
          resolve({
            type: "success",
            status: 200,
            value: "",
            user: guest
          });
        }
      });
    });
    return result2;
  }
  const result = {
    type: "error",
    status: 400,
    value: "",
    user: null
  };
  if (await AppSettings3.isAuthEnabled() && await AppSettings3.isFirstRun() && !env.SYNGRISI_DISABLE_FIRST_RUN) {
    logger_default.info("first run, set admin password", logOpts5);
    result.type = "redirect";
    result.status = 301;
    result.value = "/auth/change?first_run=true";
    return result;
  }
  if (await AppSettings3.isAuthEnabled()) {
    logger_default.info(`user is not authenticated, will redirected - ${req.originalUrl}`, logOpts5);
    result.type = "redirect";
    result.status = 301;
    if (req?.originalUrl !== "/") {
      result.value = `/auth?origin=${encodeURIComponent(req.originalUrl)}`;
      return result;
    }
    result.value = "/auth";
    return result;
  }
};
function ensureLoggedIn(options) {
  return async (req, res, next) => {
    const result = await handleBasicAuth(req);
    req.user = result.user || req.user;
    if (result.type === "success") {
      return next();
    }
    res.status(result.status).redirect(result.value);
    return next("redirect");
  };
}
var handleAPIAuth = async (hashedApiKey) => {
  const logOpts5 = {
    scope: "handleAPIAuth",
    msgType: "AUTH_API"
  };
  const result = {
    status: 400,
    type: "error",
    value: "",
    user: null
  };
  const AppSettings3 = await appSettings;
  if (!await AppSettings3.isAuthEnabled()) {
    const guest = await User_model_default.findOne({ username: "Guest" });
    if (!guest) {
      logger_default.error("cannot find Guest user", logOpts5);
      result.type = "error";
      result.value = "cannot find Guest user";
      return result;
    }
    logger_default.debug("authentication disabled", logOpts5, { user: "Guest" });
    result.type = "success";
    result.user = guest;
    result.status = 200;
    return result;
  }
  if (!hashedApiKey) {
    logger_default.debug("API key missing", logOpts5);
    result.type = "error";
    result.status = 401;
    result.value = "API key missing";
    return result;
  }
  const user = await User_model_default.findOne({ apiKey: hashedApiKey });
  if (!user) {
    logger_default.error(`wrong API key: ${hashedApiKey}`, logOpts5);
    result.type = "error";
    result.status = 401;
    result.value = "wrong API key";
    return result;
  }
  logger_default.debug("authenticated", { ...logOpts5, ...{ user: user?.username } });
  result.type = "success";
  result.status = 200;
  result.user = user;
  return result;
};
function ensureApiKey() {
  const logOpts5 = {
    scope: "ensureApiKey",
    msgType: "AUTH_API"
  };
  return async (req, res, next) => {
    logger_default.silly(`headers: ${JSON.stringify(req.headers, null, "..")}`, logOpts5);
    logger_default.silly(`SYNGRISI_AUTH: '${env.SYNGRISI_AUTH}'`);
    const hashedApiKey = req.headers.apikey || req.query.apikey;
    const result = await handleAPIAuth(hashedApiKey);
    req.user = req.user || result.user;
    req.headers.apikey = result?.user?.apiKey || req?.headers?.apikey;
    if (result.type !== "success") {
      logger_default.info(`${result.value} - ${req.originalUrl}`, logOpts5);
      res.status(result.status).json({ error: result.value });
      return next(new Error(result.value));
    }
    return next();
  };
}
function ensureLoggedInOrApiKey() {
  return async (req, res, next) => {
    const basicAuthResult = await handleBasicAuth(req);
    const hashedApiKey = req.headers.apikey || req.query.apikey;
    const apiKeyResult = await handleAPIAuth(hashedApiKey);
    req.user = req.user || apiKeyResult.user;
    if (basicAuthResult.type !== "success" && apiKeyResult.type !== "success") {
      logger_default.info(`Unauthorized - ${req.originalUrl}`);
      res.status(401).json({ error: `Unauthorized - ${req.originalUrl}` });
      return next(new Error(`Unauthorized - ${req.originalUrl}`));
    }
    return next();
  };
}

// src/server/schemas/utils/createRequestParamsSchema.ts
var import_zod15 = require("zod");
var createRequestParamsSchema = (schema) => import_zod15.z.object({ params: schema });
var getByIdParamsSchema = (id2 = "id") => createRequestParamsSchema(
  import_zod15.z.object({ [id2]: commonValidations.id })
);

// src/server/schemas/TestDistinct.schema.ts
var import_zod16 = require("zod");
var validIds2 = [
  "suite",
  "run",
  "markedAs",
  "creatorId",
  "creatorUsername",
  "name",
  "status",
  "browserName",
  "browserVersion",
  "branch",
  "tags",
  "viewport",
  "os",
  "app",
  "startDate",
  "filter"
];
var TestDistinctRequestParamsSchema = import_zod16.z.object({
  id: import_zod16.z.enum(validIds2).openapi({
    description: "Parameter identifier",
    example: "suite"
  })
});
var TestDistinctResponseSchema = import_zod16.z.object({
  name: import_zod16.z.string().min(1).openapi({
    description: "Distinct field value",
    example: "chrome"
  })
});

// src/server/routes/v1/tests.route.ts
var registry4 = new import_zod_to_openapi8.OpenAPIRegistry();
var router3 = import_express3.default.Router();
registry4.registerPath({
  method: "get",
  path: "/v1/tests",
  summary: "Get list of tests",
  tags: ["Tests"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(TestGetSchema, "Success")
});
router3.get(
  "/",
  ensureLoggedIn(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/checks"),
  getTest
);
registry4.registerPath({
  method: "get",
  path: "/v1/tests/distinct/{field}",
  summary: "List of certain unique fields across all tests",
  tags: ["Tests"],
  request: { params: TestDistinctRequestFieldParamsSchema, query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(TestDistinctResponseSchema, "Success")
});
router3.get(
  "/distinct/:field",
  ensureLoggedIn(),
  validateRequest(
    createRequestParamsSchema(TestDistinctRequestFieldParamsSchema).merge(
      createRequestQuerySchema(RequestPaginationSchema)
    ),
    "get, /distinct/:field"
  ),
  distinct_with_filter
);
registry4.registerPath({
  method: "delete",
  path: "/v1/tests/{id}",
  summary: "Delete a test by ID",
  tags: ["Tests"],
  request: commonValidations.paramsId,
  responses: createApiResponse(TestGetSchema, "Success")
});
router3.delete(
  "/:id",
  ensureLoggedIn(),
  // validateRequest(getByIdParamsSchema(), '/v1/runs/{id}'),
  validateRequest(getByIdParamsSchema(), "delete, /v1/tests/{id}"),
  remove7
);
registry4.registerPath({
  method: "put",
  path: "/v1/tests/accept/{id}",
  summary: "Accept a test by ID",
  tags: ["Tests"],
  request: commonValidations.paramsId,
  // request: { params: TestDistinctRequestParamsSchema, body: createRequestOpenApiBodySchema(TestAcceptSchema) },
  responses: createApiResponse(commonValidations.success, "Success")
});
router3.put(
  "/accept/:id",
  ensureLoggedIn(),
  validateRequest(getByIdParamsSchema(), "put, /v1/tests/accept/{id}"),
  accept4
);
var tests_route_default = router3;

// src/server/routes/v1/users.route.ts
var import_express4 = __toESM(require("express"));
var import_http_status17 = __toESM(require("http-status"));
var import_zod_to_openapi10 = require("@asteasolutions/zod-to-openapi");

// src/server/middlewares/authorization.ts
var import_http_status16 = __toESM(require("http-status"));
var authorization = (type) => {
  const types = {
    admin: catchAsync_default(async (req, res, next) => {
      const AppSettings3 = await appSettings;
      if (!await AppSettings3.isAuthEnabled()) {
        return next();
      }
      if (req.user?.role === "admin") {
        logger_default.silly(`user: '${req.user?.username}' was successfully authorized, type: '${type}'`);
        return next();
      }
      logger_default.warn(`user authorization: '${req.user?.username}' wrong role, type: '${type}'`);
      throw new ApiError_default(import_http_status16.default.FORBIDDEN, "Authorization Error - wrong Role");
    }),
    user: catchAsync_default(async (req, res, next) => {
      const AppSettings3 = await appSettings;
      if (!await AppSettings3.isAuthEnabled()) {
        return next();
      }
      if (req.user?.role === "admin") {
        logger_default.silly(`user: '${req.user?.username}' was successfully authorized, type: '${type}'`);
        return next();
      }
      if (type === "user" && (req.user?.role === "user" || req.user?.role === "reviewer")) {
        logger_default.silly(`user: '${req.user?.username}' was successfully authorized, type: '${type}'`);
        return next();
      }
      logger_default.warn(`user authorization: '${req.user?.username}' wrong role, type: '${type}'`);
      throw new ApiError_default(import_http_status16.default.FORBIDDEN, "Authorization Error - wrong Role");
    })
  };
  if (types[type]) return types[type];
  return catchAsync_default(
    () => {
      logger_default.error(JSON.stringify(new ApiError_default(import_http_status16.default.FORBIDDEN, "Wrong type of authorization")));
      throw new ApiError_default(import_http_status16.default.FORBIDDEN, "Authorization Error - wrong type of authorization");
    }
  );
};

// src/server/middlewares/compressionFilter.ts
var import_compression = __toESM(require("compression"));

// src/server/schemas/User.schema.ts
var import_zod_to_openapi9 = require("@asteasolutions/zod-to-openapi");
var import_zod17 = require("zod");
(0, import_zod_to_openapi9.extendZodWithOpenApi)(import_zod17.z);
var UserSchema2 = import_zod17.z.object({
  username: import_zod17.z.string().min(1, "UserSchema: the username name is empty").openapi({ example: "johndoe@example.com" }),
  firstName: import_zod17.z.string().min(1, "UserSchema: the firstName name is empty").openapi({ example: "John" }),
  lastName: import_zod17.z.string().min(1, "UserSchema: the lastName name is empty").openapi({ example: "Doe" }),
  role: import_zod17.z.enum(["admin", "reviewer", "user"]),
  password: import_zod17.z.string().optional(),
  token: import_zod17.z.string().optional(),
  apiKey: import_zod17.z.string().optional(),
  createdDate: import_zod17.z.date().optional().openapi({ example: "2024-05-25T15:23:21.150Z" }),
  updatedDate: import_zod17.z.date().optional().openapi({ example: "2024-05-26T15:23:21.150Z" }),
  expiration: import_zod17.z.date().optional(),
  meta: import_zod17.z.record(import_zod17.z.any()).optional(),
  _id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" }),
  id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" })
});
var UserCreateReqSchema = import_zod17.z.object({
  username: import_zod17.z.string().min(1, "UserSchema: the username name is empty").openapi({ example: "johndoe@example.com" }),
  firstName: import_zod17.z.string().min(1, "UserSchema: the firstName name is empty").openapi({ example: "John" }),
  lastName: import_zod17.z.string().min(1, "UserSchema: the lastName name is empty").openapi({ example: "Doe" }),
  role: import_zod17.z.enum(["admin", "reviewer", "user"]),
  email: import_zod17.z.string().optional(),
  password: import_zod17.z.string()
});
var UserCurrentRespSchema = import_zod17.z.object({
  _id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" }),
  id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" }),
  username: import_zod17.z.string().min(1, "UserSchema: the username name is empty").openapi({ example: "johndoe@example.com" }),
  firstName: import_zod17.z.string().min(1, "UserSchema: the firstName name is empty").openapi({ example: "John" }),
  lastName: import_zod17.z.string().min(1, "UserSchema: the lastName name is empty").openapi({ example: "Doe" }),
  role: import_zod17.z.enum(["admin", "reviewer", "user"])
});
var UserGetRespSchema = UserCurrentRespSchema;
var UserCreateRespSchema = import_zod17.z.object({
  username: import_zod17.z.string().min(1, "UserSchema: the username name is empty").openapi({ example: "johndoe@example.com" }),
  firstName: import_zod17.z.string().min(1, "UserSchema: the firstName name is empty").openapi({ example: "John" }),
  lastName: import_zod17.z.string().min(1, "UserSchema: the lastName name is empty").openapi({ example: "Doe" }),
  role: import_zod17.z.enum(["admin", "reviewer", "user"]),
  createdDate: import_zod17.z.date().optional().openapi({ example: "2024-05-25T15:23:21.150Z" }),
  updatedDate: import_zod17.z.date().optional().openapi({ example: "2024-05-26T15:23:21.150Z" }),
  _id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" }),
  id: commonValidations.id.openapi({ example: "6bbF35cAB3C59dA969edAe79" })
});

// src/server/routes/v1/users.route.ts
var registry5 = new import_zod_to_openapi10.OpenAPIRegistry();
var router4 = import_express4.default.Router();
registry5.registerPath({
  method: "get",
  path: "/v1/users/current",
  summary: "Retrieve current user details.",
  tags: ["Users"],
  responses: createApiResponse(UserCurrentRespSchema, "Success")
});
router4.get(
  "/current",
  validateRequest(SkipValid, "get, /v1/users/current"),
  users_controller_exports.current
);
registry5.registerPath({
  method: "get",
  path: "/v1/users/",
  summary: "List users with pagination, and optional filtering and sorting.",
  tags: ["Users"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(UserSchema2, "Success")
});
registry5.registerPath({
  method: "post",
  path: "/v1/users/",
  summary: "Create a new user.",
  tags: ["Users"],
  request: { body: createRequestOpenApiBodySchema(UserCreateReqSchema) },
  responses: createApiResponse(UserCreateRespSchema, "Success")
});
router4.route("/").get(
  ensureLoggedIn(),
  authorization("user"),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/users/"),
  users_controller_exports.get
).post(
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(createRequestBodySchema(UserCreateReqSchema), "post, /v1/users/"),
  users_controller_exports.create
);
registry5.registerPath({
  method: "get",
  path: "/v1/users/{userId}",
  summary: "Retrieve user details by user ID.",
  tags: ["Users"],
  request: { params: getByIdParamsSchema("userId") },
  responses: createApiResponse(UserGetRespSchema, "Success")
});
registry5.registerPath({
  method: "patch",
  path: "/v1/users/{userId}",
  summary: "Update user details by user ID.",
  tags: ["Users"],
  request: { params: getByIdParamsSchema("userId"), body: createRequestOpenApiBodySchema(UserSchema2) },
  responses: createApiResponse(UserGetRespSchema, "Success")
});
registry5.registerPath({
  method: "delete",
  path: "/v1/users/{userId}",
  summary: "Remove user by user ID.",
  tags: ["Users"],
  request: { params: getByIdParamsSchema("userId") },
  responses: createApiEmptyResponse("No Content", import_http_status17.default.NO_CONTENT)
});
router4.route("/:userId").get(
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(getByIdParamsSchema("userId"), "get, /v1/users/{userId}"),
  users_controller_exports.getById
).patch(
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(getByIdParamsSchema("userId"), "patch, /v1/users/{userId}"),
  users_controller_exports.update
).delete(
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(getByIdParamsSchema("userId"), "delete, /v1/users/{userId}"),
  users_controller_exports.remove
);
var users_route_default = router4;

// src/server/routes/v1/logs.route.ts
var import_express5 = __toESM(require("express"));
var import_zod_to_openapi11 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Logs.schema.ts
var import_zod18 = require("zod");
var LogGetSchema = import_zod18.z.object({
  _id: commonValidations.id,
  level: import_zod18.z.string().min(1).openapi({
    description: "Log level",
    example: "info"
  }),
  message: import_zod18.z.string().min(1).openapi({
    description: "Log message",
    example: "User logged in"
  }),
  timestamp: commonValidations.date.openapi({
    description: "Timestamp of the log entry",
    example: "2024-05-26T10:49:19.896Z"
  }),
  meta: import_zod18.z.object({}).optional().openapi({
    description: "Additional metadata for the log entry",
    example: { userId: "66519e582c2c701cc438ce59" }
  }),
  id: commonValidations.id
});
var LogCreateSchema = import_zod18.z.object({
  level: import_zod18.z.string().min(1).openapi({
    description: "Log level",
    example: "info"
  }).optional(),
  message: import_zod18.z.string().min(1).openapi({
    description: "Log message",
    example: "User logged in"
  }).optional(),
  meta: import_zod18.z.object({}).optional().openapi({
    description: "Additional metadata for the log entry",
    example: { userId: "66519e582c2c701cc438ce59" }
  })
});
var LogCreateRespSchema = commonValidations.success;
var LogDistinctSchema = import_zod18.z.object({
  field: import_zod18.z.string().min(1).openapi({
    description: "Field name for distinct query",
    example: "level"
  })
});
var LogDistinctResponseSchema = import_zod18.z.array(import_zod18.z.string()).openapi({
  description: "Array of distinct log levels",
  example: ["debug", "error", "info", "warn"]
});

// src/server/routes/v1/logs.route.ts
var import_http_status18 = __toESM(require("http-status"));
var registry6 = new import_zod_to_openapi11.OpenAPIRegistry();
var router5 = import_express5.default.Router();
registry6.registerPath({
  method: "get",
  path: "/v1/logs",
  summary: "List of logs with pagination, and optional filtering and sorting.",
  tags: ["Logs"],
  responses: createPaginatedApiResponse(LogGetSchema, "Success")
});
router5.get(
  "/",
  ensureLoggedIn(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/logs"),
  getLogs
);
registry6.registerPath({
  method: "get",
  path: "/v1/logs/distinct",
  summary: "Get distinct log fields",
  tags: ["Logs"],
  request: { query: createRequestQuerySchema(LogDistinctSchema) },
  responses: createApiResponse(LogDistinctResponseSchema, "Success")
});
router5.get(
  "/distinct",
  ensureLoggedIn(),
  validateRequest(createRequestQuerySchema(LogDistinctSchema), "get, /v1/logs/distinct"),
  distinct2
);
registry6.registerPath({
  method: "post",
  path: "/v1/logs",
  summary: "Create a new log entry",
  tags: ["Logs"],
  request: { body: createRequestOpenApiBodySchema(LogCreateSchema) },
  responses: createApiResponse(LogCreateRespSchema, "Success", import_http_status18.default.CREATED)
});
router5.post(
  "/",
  ensureLoggedIn(),
  validateRequest(createRequestBodySchema(LogCreateSchema), "post, /v1/logs"),
  createLog
);
var logs_route_default = router5;

// src/server/routes/v1/runs.route.ts
var import_express6 = __toESM(require("express"));
var import_zod_to_openapi13 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Runs.schema.ts
var import_zod19 = require("zod");
var RunResponseSchema = import_zod19.z.object({
  _id: commonValidations.id,
  name: import_zod19.z.string().min(1).openapi({
    description: "Name of the run",
    example: "DEBUG (VIKTAR)"
  }),
  app: commonValidations.id.openapi({
    description: "App identifier",
    example: "6651dd45b9c3e1e0b8c1ce26"
  }),
  ident: import_zod19.z.string().uuid().openapi({
    description: "Identifier for the run",
    example: "7a930247-e422-4833-8ab6-b136c23d07e9"
  }),
  createdDate: import_zod19.z.string().datetime().openapi({
    description: "Creation date of the run",
    example: "2024-05-25T13:15:26.592Z"
  }),
  parameters: import_zod19.z.array(import_zod19.z.unknown()).openapi({
    description: "Parameters of the run",
    example: []
  }),
  updatedDate: import_zod19.z.string().datetime().openapi({
    description: "Last update date of the run",
    example: "2024-05-25T13:15:30.969Z"
  }),
  id: commonValidations.id.openapi({
    description: "Run identifier",
    example: "6651e46e85f83573a821d1f4"
  })
});
var RunGetSchema = import_zod19.z.object({
  _id: commonValidations.id,
  name: import_zod19.z.string().min(1).openapi({
    description: "Name of the run",
    example: "Sample Run"
  })
  // additional fields here...
});

// src/server/schemas/common/ApiError.schema.ts
var import_zod_to_openapi12 = require("@asteasolutions/zod-to-openapi");
var import_zod20 = require("zod");
(0, import_zod_to_openapi12.extendZodWithOpenApi)(import_zod20.z);
var ApiErrorSchema = import_zod20.z.object({
  name: import_zod20.z.string().openapi({
    description: "Name of the error type",
    example: "Error"
  }),
  message: import_zod20.z.string().openapi({
    description: "Detailed message describing the error",
    example: "cannot remove run with id: '6651e46e85f83573a821d1f4', not found"
  }),
  status: import_zod20.z.number().openapi({
    description: "HTTP status code that corresponds to the error",
    example: 404
  }),
  stacktrace: import_zod20.z.string().openapi({
    description: "Stack trace of the error for debugging purposes",
    example: "Error: cannot remove run with id: '6651e46e85f83573a821d1f4', not found\\n    at Object.remove2 (/Users/exadel/Projects/SYNGRISI/packages/syngrisi/src/server/services/run.service.ts:27:15)\\n    at processTicksAndRejections (node:internal/process/task_queues:95:5)\\n    at /Users/exadel/Projects/SYNGRISI/packages/syngrisi/src/server/controllers/runs.controller.ts:25:20"
  })
});

// src/server/routes/v1/runs.route.ts
var import_http_status19 = __toESM(require("http-status"));
var registry7 = new import_zod_to_openapi13.OpenAPIRegistry();
var router6 = import_express6.default.Router();
registry7.registerPath({
  method: "get",
  path: "/v1/runs",
  summary: "List of runs with pagination, and optional filtering and sorting.",
  tags: ["Runs"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(RunResponseSchema, "Success")
});
router6.get(
  "/",
  ensureLoggedIn(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/runs"),
  get8
);
registry7.registerPath({
  method: "delete",
  path: "/v1/runs/{id}",
  summary: "Remove a run by ID",
  description: "Remove a run by ID",
  tags: ["Runs"],
  request: commonValidations.paramsId,
  responses: {
    ...createApiResponse(RunResponseSchema, "Success"),
    ...createApiResponse(ApiErrorSchema, "ApiError", import_http_status19.default.NOT_FOUND)
  }
});
router6.delete(
  "/:id",
  ensureLoggedIn(),
  validateRequest(getByIdParamsSchema(), "delete, /v1/runs/{id}"),
  remove9
);
var runs_route_default = router6;

// src/server/routes/v1/snapshots.route.ts
var import_express7 = __toESM(require("express"));
var import_zod_to_openapi14 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Snapshots.schema.ts
var import_zod21 = require("zod");
var SnapshotSchema2 = import_zod21.z.object({
  _id: commonValidations.id,
  name: import_zod21.z.string().min(1).openapi({
    description: "Name of the snapshot",
    example: "Login page"
  }),
  filename: import_zod21.z.string().min(1).openapi({
    description: "Filename of the snapshot",
    example: "6651dd4f7c9186e315910b24.png"
  }),
  imghash: import_zod21.z.string().min(1).openapi({
    description: "Image hash of the snapshot",
    example: "96e8359554f12142bc19e44288295aa67a59cd128e242b6756651bf8e3d9f34caa7f587367ca8e5cdcfbaaf180adfd8825250fc7485784c41de11a9c08c1f9ab"
  }),
  createdDate: import_zod21.z.string().datetime().openapi({
    description: "Creation date of the snapshot",
    example: "2024-05-25T13:15:30.946Z"
  }),
  id: commonValidations.id.openapi({
    description: "Snapshot identifier",
    example: "6651e47285f83573a821d20e"
  }),
  stabMethod: import_zod21.z.string().optional(),
  vOffset: import_zod21.z.number().optional()
});
var SnapshotsResponseSchema = import_zod21.z.array(
  SnapshotSchema2
);

// src/server/routes/v1/snapshots.route.ts
var registry8 = new import_zod_to_openapi14.OpenAPIRegistry();
var router7 = import_express7.default.Router();
registry8.registerPath({
  method: "get",
  path: "/v1/snapshots",
  summary: "List of snapshots with pagination, and optional filtering and sorting.",
  tags: ["Snapshots"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(SnapshotsResponseSchema, "Success")
});
router7.get(
  "/",
  ensureLoggedIn(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/snapshots"),
  get5
);
var snapshots_route_default = router7;

// src/server/routes/v1/checks.route.ts
var import_express8 = __toESM(require("express"));
var import_zod_to_openapi15 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Check.schema.ts
var import_zod22 = require("zod");
var CheckGetSchema = import_zod22.z.object({
  _id: commonValidations.id,
  name: import_zod22.z.string().min(1).openapi({
    description: "Name of the check",
    example: "Sample Check"
  }),
  test: commonValidations.id.openapi({
    description: "Test identifier",
    example: "666acbe24fe1d2a67424ff60"
  }),
  suite: commonValidations.id.openapi({
    description: "Suite identifier",
    example: "6651dd457c9186e315910b00"
  }),
  app: commonValidations.id.openapi({
    description: "Application identifier",
    example: "6651dd45b9c3e1e0b8c1ce26"
  }),
  branch: import_zod22.z.string().min(1).openapi({
    description: "Branch name",
    example: "master"
  }),
  baselineId: commonValidations.id.openapi({
    description: "Baseline identifier",
    example: "6656ee01bac26a33185c9488"
  }),
  actualSnapshotId: commonValidations.id.openapi({
    description: "Actual snapshot identifier",
    example: "666acbf04fe1d2a67424ffa4"
  }),
  diffId: commonValidations.id.openapi({
    description: "Difference identifier",
    example: "666acbf04fe1d2a67424ffa9"
  }),
  updatedDate: commonValidations.date.openapi({
    description: "Last update date of the check",
    example: "2024-06-13T10:37:36.264Z"
  }),
  status: import_zod22.z.array(import_zod22.z.string().min(1)).openapi({
    description: "Status of the check",
    example: ["failed"]
  }),
  browserName: import_zod22.z.string().min(1).openapi({
    description: "Browser name used for the check",
    example: "chrome"
  }),
  browserVersion: import_zod22.z.string().min(1).openapi({
    description: "Browser version used for the check",
    example: "125"
  }),
  browserFullVersion: import_zod22.z.string().min(1).openapi({
    description: "Full browser version used for the check",
    example: "125.0.6422.142"
  }),
  viewport: import_zod22.z.string().min(1).openapi({
    description: "Viewport size used for the check",
    example: "1366x768"
  }),
  os: import_zod22.z.string().min(1).openapi({
    description: "Operating system used for the check",
    example: "macOS"
  }),
  result: import_zod22.z.string().openapi({
    description: "Result of the check",
    example: '{\n	"isSameDimensions": false,\n	"dimensionDifference": {\n		"width": 24,\n		"height": 8\n	},\n	"rawMisMatchPercentage": 67.38024135551241,\n	"misMatchPercentage": "67.38",\n	"analysisTime": 99,\n	"executionTotalTime": "0,398753687",\n	"totalCheckHandleTime": "0,431217924"\n}'
  }),
  run: commonValidations.id.openapi({
    description: "Run identifier",
    example: "666acbe24fe1d2a67424ff5d"
  }),
  markedAs: import_zod22.z.string().min(1).openapi({
    description: "Status marked for the check",
    example: "accepted"
  }),
  markedDate: commonValidations.date.openapi({
    description: "Marked date of the check",
    example: "2024-06-13T07:19:32.246Z"
  }),
  markedByUsername: import_zod22.z.string().min(1).openapi({
    description: "Username of the user who marked the check",
    example: "Administrator"
  }),
  creatorId: commonValidations.id.openapi({
    description: "Identifier of the user who created the check",
    example: "66519e582c2c701cc438ce59"
  }),
  creatorUsername: import_zod22.z.string().min(1).openapi({
    description: "Username of the user who created the check",
    example: "Guest"
  }),
  failReasons: import_zod22.z.array(import_zod22.z.string().min(1)).openapi({
    description: "Reasons for the check failure",
    example: ["wrong_dimensions", "different_images"]
  }),
  createdDate: commonValidations.date.openapi({
    description: "Creation date of the check",
    example: "2024-06-13T10:37:36.721Z"
  }),
  id: commonValidations.id
});
var CheckUpdateSchema = CheckGetSchema.omit({ id: true, _id: true }).partial();
var CheckAcceptSchema = import_zod22.z.object({
  baselineId: commonValidations.id.openapi({
    description: "Baseline identifier to accept the check",
    example: "6651ec20917e9ce26f7c0849"
  })
});

// src/server/routes/v1/checks.route.ts
var registry9 = new import_zod_to_openapi15.OpenAPIRegistry();
var router8 = import_express8.default.Router();
registry9.registerPath({
  method: "get",
  path: "/v1/checks",
  summary: "List of checks with pagination, and optional filtering and sorting.",
  tags: ["Checks"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(CheckGetSchema, "Success")
});
router8.get(
  "/",
  ensureLoggedInOrApiKey(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/checks"),
  get4
);
registry9.registerPath({
  method: "delete",
  path: "/v1/checks/{id}",
  summary: "Delete a check by ID",
  tags: ["Checks"],
  request: commonValidations.paramsId,
  responses: createApiResponse(CheckGetSchema, "Success")
});
router8.delete(
  "/:id",
  ensureLoggedInOrApiKey(),
  validateRequest(getByIdParamsSchema(), "delete, /v1/checks/{id}"),
  remove6
);
registry9.registerPath({
  method: "put",
  path: "/v1/checks/{id}",
  summary: "Update a check by ID",
  tags: ["Checks"],
  request: { params: commonValidations.paramsId.params, body: createRequestOpenApiBodySchema(CheckUpdateSchema) },
  responses: createApiResponse(CheckGetSchema, "Success")
});
router8.put(
  "/:id",
  ensureLoggedInOrApiKey(),
  validateRequest(getByIdParamsSchema().merge(createRequestBodySchema(CheckUpdateSchema)), "put, /v1/checks/{id}"),
  update2
);
registry9.registerPath({
  method: "put",
  path: "/v1/checks/{id}/accept",
  summary: "Accept a check by ID",
  tags: ["Checks"],
  request: { params: commonValidations.paramsId.params, body: createRequestOpenApiBodySchema(CheckAcceptSchema) },
  responses: createApiResponse(CheckGetSchema, "Success")
});
router8.put(
  "/:id/accept",
  ensureLoggedInOrApiKey(),
  validateRequest(createRequestBodySchema(CheckAcceptSchema), "put, /v1/checks/{id}/accept"),
  accept3
);
var checks_route_default = router8;

// src/server/routes/v1/baselines.route.ts
var import_express9 = __toESM(require("express"));
var import_zod_to_openapi16 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Baseline.schema.ts
var import_zod23 = require("zod");
var BaselineGetSchema = import_zod23.z.object({
  _id: commonValidations.id,
  name: import_zod23.z.string().min(1).openapi({
    description: "Name of the baseline",
    example: "Green Button"
  }),
  app: commonValidations.id.openapi({
    description: "Application identifier for the baseline",
    example: "6651dd45b9c3e1e0b8c1ce26"
  }),
  branch: import_zod23.z.string().min(1).openapi({
    description: "Branch name for the baseline",
    example: "master"
  }),
  browserName: import_zod23.z.string().min(1).openapi({
    description: "Browser name used for the baseline",
    example: "chrome"
  }),
  viewport: import_zod23.z.string().min(1).openapi({
    description: "Viewport size used for the baseline",
    example: "1366x768"
  }),
  os: import_zod23.z.string().min(1).openapi({
    description: "Operating system used for the baseline",
    example: "macOS"
  }),
  createdDate: commonValidations.date.openapi({
    description: "Creation date of the baseline",
    example: "2024-05-26T10:49:19.896Z"
  }),
  lastMarkedDate: commonValidations.date.openapi({
    description: "Last marked date of the baseline",
    example: "2024-05-26T10:49:19.852Z"
  }),
  markedAs: import_zod23.z.string().min(1).openapi({
    description: "Status marked for the baseline",
    example: "accepted"
  }),
  markedById: commonValidations.id.openapi({
    description: "Identifier of the user who marked the baseline",
    example: "66519e582c2c701cc438ce59"
  }),
  markedByUsername: import_zod23.z.string().min(1).openapi({
    description: "Username of the user who marked the baseline",
    example: "Guest"
  }),
  snapshootId: commonValidations.id.openapi({
    description: "Snapshot identifier for the baseline",
    example: "6651ec20917e9ce26f7c0849"
  }),
  id: commonValidations.id
});
var BaselinePutSchema = import_zod23.z.object({
  name: import_zod23.z.string().min(1).openapi({
    description: "Name of the baseline",
    example: "Green Button"
  }).optional(),
  branch: import_zod23.z.string().min(1).openapi({
    description: "Branch name for the baseline",
    example: "master"
  }).optional(),
  browserName: import_zod23.z.string().min(1).openapi({
    description: "Browser name used for the baseline",
    example: "chrome"
  }).optional(),
  viewport: import_zod23.z.string().min(1).openapi({
    description: "Viewport size used for the baseline",
    example: "1366x768"
  }).optional(),
  os: import_zod23.z.string().min(1).openapi({
    description: "Operating system used for the baseline",
    example: "macOS"
  }).optional(),
  createdDate: commonValidations.date.openapi({
    description: "Creation date of the baseline",
    example: "2024-05-26T10:49:19.896Z"
  }).optional(),
  lastMarkedDate: commonValidations.date.openapi({
    description: "Last marked date of the baseline",
    example: "2024-05-26T10:49:19.852Z"
  }).optional(),
  markedAs: import_zod23.z.string().min(1).openapi({
    description: "Status marked for the baseline",
    example: "accepted"
  }).optional(),
  markedById: commonValidations.id.openapi({
    description: "Identifier of the user who marked the baseline",
    example: "66519e582c2c701cc438ce59"
  }).optional(),
  markedByUsername: import_zod23.z.string().min(1).openapi({
    description: "Username of the user who marked the baseline",
    example: "Guest"
  }).optional()
});

// src/server/routes/v1/baselines.route.ts
var registry10 = new import_zod_to_openapi16.OpenAPIRegistry();
var router9 = import_express9.default.Router();
registry10.registerPath({
  method: "get",
  path: "/v1/baselines",
  summary: "List of baselines with pagination, and optional filtering and sorting.",
  tags: ["Baselines"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(BaselineGetSchema, "Success")
});
router9.get(
  "/",
  ensureLoggedInOrApiKey(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/baselines"),
  get3
);
registry10.registerPath({
  method: "put",
  path: "/v1/baselines/{id}",
  summary: "Only for testing purposes for now",
  tags: ["Baselines"],
  request: { params: commonValidations.paramsId.params, body: createRequestOpenApiBodySchema(BaselinePutSchema) },
  responses: createApiEmptyResponse("Success")
});
router9.put(
  "/:id",
  ensureLoggedIn(),
  validateRequest(getByIdParamsSchema().merge(createRequestBodySchema(BaselinePutSchema)), "put, /v1/baselines/{id}"),
  put2
);
var baselines_route_default = router9;

// src/server/routes/v1/suites.route.ts
var import_express10 = __toESM(require("express"));
var import_zod_to_openapi17 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Suite.schema.ts
var import_zod24 = require("zod");
var SuiteGetSchema = import_zod24.z.object({
  _id: commonValidations.id,
  name: import_zod24.z.string().min(1).openapi({
    description: "Name of the suite",
    example: "Smoke tests"
  }),
  tags: import_zod24.z.array(import_zod24.z.string()).openapi({
    description: "Tags associated with the suite",
    example: []
  }),
  app: commonValidations.id.openapi({
    description: "Application identifier",
    example: "666b3b82db17d34ecdbd06f6"
  }),
  createdDate: commonValidations.date.openapi({
    description: "Creation date of the suite",
    example: "2024-06-13T18:33:38.617Z"
  }),
  updatedDate: commonValidations.date.openapi({
    description: "Last update date of the suite",
    example: "2024-06-13T19:55:40.114Z"
  }),
  id: commonValidations.id.openapi({
    description: "ID of the suite",
    example: "666b3b828833d0cf24a670d7"
  })
});

// src/server/routes/v1/suites.route.ts
var import_http_status20 = __toESM(require("http-status"));
var registry11 = new import_zod_to_openapi17.OpenAPIRegistry();
var router10 = import_express10.default.Router();
registry11.registerPath({
  method: "get",
  path: "/v1/suites",
  summary: "List of suites",
  tags: ["Suites"],
  responses: createPaginatedApiResponse(SuiteGetSchema, "Success")
});
router10.get(
  "/",
  ensureLoggedIn(),
  validateRequest(SkipValid, "get, /v1/suites"),
  get9
);
registry11.registerPath({
  method: "delete",
  path: "/v1/suites/{id}",
  summary: "Delete a suite by ID",
  tags: ["Suites"],
  request: commonValidations.paramsId,
  responses: {
    ...createApiResponse(SuiteGetSchema, "Success"),
    ...createApiResponse(ApiErrorSchema, "ApiError", import_http_status20.default.NOT_FOUND)
  }
});
router10.delete(
  "/:id",
  ensureLoggedIn(),
  validateRequest(getByIdParamsSchema(), "delete, /v1/suites/{id}"),
  remove10
);
var suites_route_default = router10;

// src/server/routes/v1/settings.route.ts
var import_express11 = __toESM(require("express"));
var import_zod_to_openapi18 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Settings.schema.ts
var import_zod25 = require("zod");
var SettingsGetSchema = import_zod25.z.object({
  name: import_zod25.z.string().min(1).openapi({
    description: "Name of the setting",
    example: "example_setting"
  }),
  value: import_zod25.z.any().openapi({
    description: "Value of the setting",
    example: "example_value"
  }),
  description: import_zod25.z.string().optional().openapi({
    description: "Description of the setting",
    example: "This is an example setting."
  })
});
var SettingsUpdateSchema = import_zod25.z.object({
  value: import_zod25.z.any().openapi({
    description: "New value for the setting",
    example: "new_example_value"
  }),
  enabled: import_zod25.z.boolean().optional().openapi({
    description: "Enable or disable the setting",
    example: true
  })
});
var SettingsResponseSchema = import_zod25.z.array(
  import_zod25.z.object({
    _id: commonValidations.id,
    name: import_zod25.z.string().min(1).openapi({
      description: "Name of the setting",
      example: "first_run"
    }),
    label: import_zod25.z.string().min(1).openapi({
      description: "Label of the setting",
      example: "First Run"
    }),
    description: import_zod25.z.string().min(1).openapi({
      description: "Description of the setting",
      example: "Indicates if the application is running the first time"
    }),
    type: import_zod25.z.string().min(1).openapi({
      description: "Type of the setting",
      example: "Boolean"
    }),
    value: import_zod25.z.any().openapi({
      description: "Value of the setting",
      example: false
    }),
    enabled: import_zod25.z.boolean().openapi({
      description: "Indicates if the setting is enabled",
      example: true
    }),
    __v: import_zod25.z.number().openapi({
      description: "Version key",
      example: 0
    })
  })
);
var SettingsNameParamSchema = import_zod25.z.object({
  name: import_zod25.z.string().min(1).openapi({
    description: "Name of the setting to update",
    example: "example_setting"
  })
});

// src/server/routes/v1/settings.route.ts
var registry12 = new import_zod_to_openapi18.OpenAPIRegistry();
var router11 = import_express11.default.Router();
registry12.registerPath({
  method: "get",
  path: "/v1/settings",
  summary: "Get application settings",
  tags: ["Settings"],
  responses: createApiResponse(SettingsResponseSchema, "Success")
});
router11.get(
  "/",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(SkipValid, "get, /v1/settings"),
  getSettings
);
registry12.registerPath({
  method: "patch",
  path: "/v1/settings/{name}",
  summary: "Update a setting by name",
  tags: ["Settings"],
  request: { params: SettingsNameParamSchema, body: createRequestOpenApiBodySchema(SettingsUpdateSchema) },
  responses: createApiResponse(commonValidations.success, "Success")
});
var validateSchema = createRequestParamsSchema(SettingsNameParamSchema).merge(createRequestBodySchema(SettingsUpdateSchema));
router11.patch(
  "/:name",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(validateSchema, "patch, /v1/settings/{name}"),
  updateSetting
);
var settings_route_default = router11;

// src/server/routes/v1/test_distinct.route.ts
var import_express12 = __toESM(require("express"));
var import_zod_to_openapi19 = require("@asteasolutions/zod-to-openapi");
var registry13 = new import_zod_to_openapi19.OpenAPIRegistry();
var router12 = import_express12.default.Router();
registry13.registerPath({
  method: "get",
  path: "/v1/test-distinct/{id}",
  summary: "[Obsolete use '/v1/test/distict' instead] List of certain unique fields across all tests",
  tags: ["Tests"],
  request: { params: TestDistinctRequestParamsSchema, query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(TestDistinctResponseSchema, "Success")
});
router12.get(
  "/:id",
  ensureLoggedIn(),
  validateRequest(createRequestParamsSchema(TestDistinctRequestParamsSchema), "get, /v1/test-distinct/{id}"),
  distinct3
);
var test_distinct_route_default = router12;

// src/server/routes/v1/tasks.route.ts
var import_express13 = __toESM(require("express"));
var import_zod_to_openapi20 = require("@asteasolutions/zod-to-openapi");
var registry14 = new import_zod_to_openapi20.OpenAPIRegistry();
var router13 = import_express13.default.Router();
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/task_test",
  summary: "Test task endpoint",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/task_test",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(SkipValid, "get, /v1/tasks/task_test"),
  task_test2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/task_handle_old_checks",
  summary: "Handle old checks task",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/task_handle_old_checks",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(SkipValid, "get, /v1/tasks/task_handle_old_checks"),
  task_handle_old_checks2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/task_handle_database_consistency",
  summary: "Handle database consistency task",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/task_handle_database_consistency",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(SkipValid, "get, /v1/tasks/task_handle_database_consistency"),
  task_handle_database_consistency2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/task_remove_old_logs",
  summary: "Remove old logs task",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/task_remove_old_logs",
  ensureLoggedIn(),
  authorization("admin"),
  validateRequest(SkipValid, "get, /v1/tasks/task_remove_old_logs"),
  task_remove_old_logs2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/loadTestUser",
  summary: "Load test user",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/loadTestUser",
  ensureLoggedIn(),
  validateRequest(SkipValid, "get, /v1/tasks/loadTestUser"),
  loadTestUser2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/status",
  summary: "Get status task, only for the test cases",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/status",
  validateRequest(SkipValid, "get, /v1/tasks/status"),
  status2
);
registry14.registerPath({
  method: "get",
  path: "/v1/tasks/screenshots",
  summary: "Get screenshots task",
  tags: ["Tasks"],
  responses: createApiResponse(SkipValid, "Success")
});
router13.get(
  "/screenshots",
  validateRequest(SkipValid, "get, /v1/tasks/screenshots"),
  screenshots2
);
var tasks_route_default = router13;

// src/server/routes/v1/client.route.ts
var import_express14 = __toESM(require("express"));
var import_zod_to_openapi21 = require("@asteasolutions/zod-to-openapi");

// src/server/schemas/Client.schema.ts
var import_zod26 = require("zod");
var ClientStartSessionSchema = import_zod26.z.object({
  name: import_zod26.z.string().min(1).openapi({
    description: "Name of the session",
    example: "Login test"
  }),
  app: import_zod26.z.string().min(1).openapi({
    description: "Application name",
    example: "My project"
  }),
  tags: import_zod26.z.string().openapi({
    description: "Tags associated with the session",
    example: '["@smoke", "@PJ-231"]'
  }).optional(),
  branch: import_zod26.z.string().min(1).openapi({
    description: "Branch name",
    example: "master"
  }),
  viewport: import_zod26.z.string().min(1).openapi({
    description: "Viewport size",
    example: "1366x768"
  }),
  browser: import_zod26.z.string().min(1).openapi({
    description: "Browser name",
    example: "chrome"
  }),
  browserVersion: import_zod26.z.string().min(1).openapi({
    description: "Browser version",
    example: "125"
  }),
  browserFullVersion: import_zod26.z.string().min(1).openapi({
    description: "Browser full version",
    example: "125.12.56.001"
  }).optional(),
  os: import_zod26.z.string().min(1).openapi({
    description: "Operating system",
    example: "macOS"
  }),
  run: import_zod26.z.string().min(1).openapi({
    description: "Run name",
    example: "Build #123"
  }),
  runident: import_zod26.z.string().min(1).openapi({
    description: "Run identifier",
    example: "978ee42c-78f8-40f4-8954-51ebc08d1718"
  }),
  suite: import_zod26.z.string().min(1).openapi({
    description: "Suite name",
    example: "Smoke tests"
  })
});
var ClientStartSessionResponseSchema = import_zod26.z.object({
  name: import_zod26.z.string().openapi({
    description: "Name of the session",
    example: "Login test"
  }),
  status: import_zod26.z.string().openapi({
    description: "Status of the session",
    example: "Running"
  }),
  browserName: import_zod26.z.string().openapi({
    description: "Browser name",
    example: "chrome"
  }),
  browserVersion: import_zod26.z.string().openapi({
    description: "Browser version",
    example: "125"
  }),
  branch: import_zod26.z.string().openapi({
    description: "Branch name",
    example: "master"
  }),
  tags: import_zod26.z.array(import_zod26.z.string()).openapi({
    description: "Tags associated with the session",
    example: ["@smoke", "@PJ-231"]
  }),
  viewport: import_zod26.z.string().openapi({
    description: "Viewport size",
    example: "1366x768"
  }),
  os: import_zod26.z.string().openapi({
    description: "Operating system",
    example: "macOS"
  }),
  app: import_zod26.z.string().openapi({
    description: "Application identifier",
    example: "666b3b82db17d34ecdbd06f6"
  }),
  blinking: import_zod26.z.number().openapi({
    description: "Blinking count",
    example: 0
  }),
  updatedDate: import_zod26.z.string().openapi({
    description: "Last updated date",
    example: "2024-06-13T18:34:28.121Z"
  }),
  startDate: import_zod26.z.string().openapi({
    description: "Start date of the session",
    example: "2024-06-13T18:34:28.121Z"
  }),
  checks: import_zod26.z.array(import_zod26.z.any()).openapi({
    description: "Checks associated with the session",
    example: []
  }),
  suite: import_zod26.z.string().openapi({
    description: "Suite identifier",
    example: "666b3b828833d0cf24a670d7"
  }),
  run: import_zod26.z.string().openapi({
    description: "Run identifier",
    example: "666b244a70a6fb0a4368b59e"
  }),
  _id: commonValidations.id.openapi({
    description: "Identifier of the session",
    example: "666b3bb49e0c25666d76e0c4"
  }),
  id: commonValidations.id.openapi({
    description: "Identifier of the session",
    example: "666b3bb49e0c25666d76e0c4"
  })
});
var ClientEndSessionSchema = import_zod26.z.object({
  testid: commonValidations.id
});
var ClientCreateCheckSchema = import_zod26.z.object({
  testid: commonValidations.id.openapi({
    description: "Test identifier",
    example: "666b2e1e93ca920ef5985b47"
  }),
  name: import_zod26.z.string().openapi({
    description: "Name of the check",
    example: "Login page"
  }),
  appName: import_zod26.z.string().openapi({
    description: "Application name",
    example: "My App"
  }),
  branch: import_zod26.z.string().openapi({
    description: "Branch name",
    example: "master"
  }),
  suitename: import_zod26.z.string().openapi({
    description: "Suite name",
    example: "Smoke tests"
  }),
  viewport: import_zod26.z.string().openapi({
    description: "Viewport size",
    example: "1366x768"
  }),
  browserName: import_zod26.z.string().openapi({
    description: "Browser name",
    example: "chrome"
  }),
  browserVersion: import_zod26.z.string().openapi({
    description: "Browser version",
    example: "125"
  }),
  browserFullVersion: import_zod26.z.string().openapi({
    description: "Full browser version",
    example: "125.0.6422.142"
  }),
  os: import_zod26.z.string().openapi({
    description: "Operating system",
    example: "macOS"
  }),
  hashcode: import_zod26.z.string().openapi({
    description: "Hash of the snapshot - In the first phase, only the hash is sent, in case the snapshot is already in the Syngrisi database",
    example: "ef6ff7c6e6fd536de877c02cf61381e5a1111a24c9d21c1c2a0c0c06fdd2f01271da8880da80a1caa7c123ce3256068c40055753d70bd1dbc558d088f90cd398"
  })
});
var SnapshotSchema3 = import_zod26.z.object({
  name: import_zod26.z.string().openapi({
    description: "Name of the snapshot",
    example: "Login page"
  }),
  filename: import_zod26.z.string().openapi({
    description: "Filename of the snapshot",
    example: "666b12d859ac872b495af4b0.png"
  }),
  imghash: import_zod26.z.string().openapi({
    description: "Image hash of the snapshot",
    example: "ef6ff7c6e6fd536de877c02cf61381e5a1111a24c9d21c1c2a0c0c06fdd2f01271da8880da80a1caa7c123ce3256068c40055753d70bd1dbc558d088f90cd398"
  }),
  _id: commonValidations.id.openapi({
    description: "Identifier of the snapshot",
    example: "666b4ebc421977cbf466b478"
  }),
  createdDate: import_zod26.z.string().openapi({
    description: "Creation date",
    example: "2024-06-13T19:55:40.068Z"
  }),
  id: commonValidations.id.openapi({
    description: "Identifier of the snapshot",
    example: "666b4ebc421977cbf466b478"
  })
});
var ClientCreateCheckResponseSchema = import_zod26.z.object({
  name: import_zod26.z.string().openapi({
    description: "Name of the check",
    example: "Login page"
  }),
  test: commonValidations.id.openapi({
    description: "Test identifier",
    example: "666b4e74421977cbf466b446"
  }),
  suite: commonValidations.id.openapi({
    description: "Suite identifier",
    example: "666b3b828833d0cf24a670d7"
  }),
  app: commonValidations.id.openapi({
    description: "Application identifier",
    example: "6651dd45b9c3e1e0b8c1ce26"
  }),
  branch: import_zod26.z.string().openapi({
    description: "Branch name",
    example: "master"
  }),
  baselineId: commonValidations.id.openapi({
    description: "Baseline identifier",
    example: "666b4ebc421977cbf466b478"
  }),
  actualSnapshotId: commonValidations.id.openapi({
    description: "Actual snapshot identifier",
    example: "666b4ebc421977cbf466b478"
  }),
  updatedDate: import_zod26.z.string().openapi({
    description: "Last updated date",
    example: "2024-06-13T19:55:40.061Z"
  }),
  status: import_zod26.z.array(import_zod26.z.string()).openapi({
    description: "Status of the check",
    example: ["new"]
  }),
  browserName: import_zod26.z.string().openapi({
    description: "Browser name",
    example: "chrome"
  }),
  browserVersion: import_zod26.z.string().openapi({
    description: "Browser version",
    example: "125"
  }),
  browserFullVersion: import_zod26.z.string().openapi({
    description: "Full browser version",
    example: "125.0.6422.142"
  }),
  viewport: import_zod26.z.string().openapi({
    description: "Viewport size",
    example: "1366x768"
  }),
  os: import_zod26.z.string().openapi({
    description: "Operating system",
    example: "macOS"
  }),
  result: import_zod26.z.string().openapi({
    description: "Result of the check",
    example: "{}"
  }),
  run: commonValidations.id.openapi({
    description: "Run identifier",
    example: "666b4e74421977cbf466b443"
  }),
  creatorId: commonValidations.id.openapi({
    description: "Creator identifier",
    example: "66519e582c2c701cc438ce59"
  }),
  creatorUsername: import_zod26.z.string().openapi({
    description: "Creator username",
    example: "Guest"
  }),
  failReasons: import_zod26.z.array(import_zod26.z.any()).openapi({
    description: "Reasons for failure",
    example: []
  }),
  _id: commonValidations.id.openapi({
    description: "Identifier of the check",
    example: "666b4ebc421977cbf466b47c"
  }),
  createdDate: import_zod26.z.string().openapi({
    description: "Creation date",
    example: "2024-06-13T19:55:40.082Z"
  }),
  currentSnapshot: SnapshotSchema3,
  expectedSnapshot: SnapshotSchema3,
  lastSuccess: commonValidations.id.openapi({
    description: "Identifier of the last successful check",
    example: "666b4ebc421977cbf466b47c"
  })
});
var ClientGetIdentSchema = import_zod26.z.array(import_zod26.z.string()).openapi({
  description: "Set of fields that identify checks and baselines",
  example: ["name", "viewport", "browserName", "os", "app", "branch"]
});
var ClientGetBaselinesSchema = import_zod26.z.object({
  baselines: import_zod26.z.array(import_zod26.z.object({
    id: commonValidations.id,
    name: import_zod26.z.string().openapi({
      description: "Name of the baseline",
      example: "A-A-A"
    }),
    app: commonValidations.id.openapi({
      description: "Application identifier",
      example: "6651dd45b9c3e1e0b8c1ce26"
    }),
    branch: import_zod26.z.string().openapi({
      description: "Branch name",
      example: "master"
    }),
    browserName: import_zod26.z.string().openapi({
      description: "Browser name",
      example: "chrome"
    }),
    viewport: import_zod26.z.string().openapi({
      description: "Viewport size",
      example: "1366x768"
    }),
    os: import_zod26.z.string().openapi({
      description: "Operating system",
      example: "macOS"
    }),
    createdDate: import_zod26.z.string().openapi({
      description: "Creation date",
      example: "2024-06-13T15:59:44.479Z"
    }),
    lastMarkedDate: import_zod26.z.string().openapi({
      description: "Last marked date",
      example: "2024-06-13T15:59:44.381Z"
    }),
    markedAs: import_zod26.z.string().openapi({
      description: "Marked status",
      example: "accepted"
    }),
    markedById: commonValidations.id.openapi({
      description: "Identifier of the user who marked the baseline",
      example: "66519e1682764a892a1a0031"
    }),
    markedByUsername: import_zod26.z.string().openapi({
      description: "Username of the user who marked the baseline",
      example: "Administrator"
    }),
    snapshootId: commonValidations.id.openapi({
      description: "Snapshot identifier",
      example: "666b12d859ac872b495af4b0"
    }),
    _id: commonValidations.id.openapi({
      description: "Identifier of the baseline",
      example: "666b177059ac872b495af63d"
    })
  }))
});
var ClientGetSnapshotsSchema = import_zod26.z.object({
  snapshots: import_zod26.z.array(import_zod26.z.object({
    id: commonValidations.id,
    name: import_zod26.z.string()
  }))
});

// src/server/routes/v1/client.route.ts
var registry15 = new import_zod_to_openapi21.OpenAPIRegistry();
var router14 = import_express14.default.Router();
registry15.registerPath({
  method: "post",
  path: "/v1/client/startSession",
  summary: "Start a client session",
  tags: ["Client"],
  request: { body: createRequestOpenApiBodySchema(ClientStartSessionSchema) },
  responses: createApiResponse(ClientStartSessionResponseSchema, "Success")
});
router14.post(
  "/startSession",
  ensureApiKey(),
  validateRequest(createRequestBodySchema(ClientStartSessionSchema), "/v1/client/startSession"),
  startSession2
);
registry15.registerPath({
  method: "post",
  path: "/v1/client/stopSession/{testid}",
  summary: "Stop a client session by test ID",
  tags: ["Client"],
  request: commonValidations.paramsTestId,
  responses: createApiResponse(ClientStartSessionResponseSchema, "Success")
});
router14.post(
  "/stopSession/:testid",
  ensureApiKey(),
  // validateRequest(SkipValid, '/v1/client/stopSession/{testid}'),
  validateRequest(getByIdParamsSchema("testid"), "/v1/client/stopSession/{testid}"),
  endSession2
);
registry15.registerPath({
  method: "post",
  path: "/v1/client/createCheck",
  summary: "Create a client check",
  tags: ["Client"],
  request: { body: createRequestOpenApiBodySchema(ClientCreateCheckSchema) },
  responses: createApiResponse(ClientCreateCheckResponseSchema, "Success")
});
router14.post(
  "/createCheck",
  ensureApiKey(),
  validateRequest(createRequestBodySchema(ClientCreateCheckSchema), "/v1/client/createCheck"),
  createCheck2
);
registry15.registerPath({
  method: "get",
  path: "/v1/client/getIdent",
  summary: "Set of fields that identify checks and baselines",
  tags: ["Client"],
  responses: createApiResponse(ClientGetIdentSchema, "Success")
});
router14.get(
  "/getIdent",
  ensureApiKey(),
  validateRequest(SkipValid, "get, /v1/client/getIdent"),
  getIdent2
);
var ExtRequestBaselineSchema = RequestPaginationSchema.extend(
  {
    filter: IdentJSONStringSchema
  }
);
registry15.registerPath({
  method: "get",
  path: "/v1/client/baselines",
  summary: "Get client baselines",
  tags: ["Client"],
  // request: { query: RequestPaginationSchema },
  request: { query: ExtRequestBaselineSchema },
  responses: createPaginatedApiResponse(ClientGetBaselinesSchema, "Success")
});
router14.get(
  "/baselines",
  ensureApiKey(),
  validateRequest(createRequestQuerySchema(ExtRequestBaselineSchema), "get, /v1/client/baselines"),
  getBaselines2
);
registry15.registerPath({
  method: "get",
  path: "/v1/client/snapshots",
  summary: "Get client snapshots",
  tags: ["Client"],
  request: { query: RequestPaginationSchema },
  responses: createPaginatedApiResponse(ClientGetSnapshotsSchema, "Success")
});
router14.get(
  "/snapshots",
  ensureApiKey(),
  validateRequest(createRequestQuerySchema(RequestPaginationSchema), "get, /v1/client/snapshots"),
  getSnapshots
);
var client_route_default = router14;

// src/server/routes/v1/index.route.ts
var router15 = import_express15.default.Router();
var defaultRoutes = [
  {
    path: "/auth",
    route: auth_route_default
  },
  {
    path: "/client",
    route: client_route_default
  },
  {
    path: "/tasks",
    route: tasks_route_default
  },
  {
    path: "/users",
    route: users_route_default
  },
  {
    path: "/app",
    route: app_route_default
  },
  {
    path: "/tests",
    route: tests_route_default
  },
  {
    path: "/logs",
    route: logs_route_default
  },
  {
    path: "/runs",
    route: runs_route_default
  },
  {
    path: "/snapshots",
    route: snapshots_route_default
  },
  {
    path: "/checks",
    route: checks_route_default
  },
  {
    path: "/baselines",
    route: baselines_route_default
  },
  {
    path: "/suites",
    route: suites_route_default
  },
  {
    path: "/settings",
    route: settings_route_default
  },
  {
    path: "/test-distinct",
    route: test_distinct_route_default
  }
];
defaultRoutes.forEach((route) => {
  router15.use(route.path, route.route);
});
var index_route_default = router15;
//# sourceMappingURL=index.route.js.map