"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "createApiv1", {
    enumerable: true,
    get: function() {
        return createApiv1;
    }
});
const _express = /*#__PURE__*/ _interop_require_default(require("express"));
const _middleware = require("@tamanu/shared/permissions/middleware");
const _settings = require("@tamanu/settings");
const _audit = require("@tamanu/database/utils/audit");
const _suggestions = require("@tamanu/shared/services/suggestions");
const _auth = require("../../middleware/auth");
const _expressasynchandler = /*#__PURE__*/ _interop_require_default(require("express-async-handler"));
const _zod = /*#__PURE__*/ _interop_require_wildcard(require("zod"));
const _errors = require("@tamanu/errors");
const _logging = require("@tamanu/shared/services/logging");
const _rolesToPermissions = require("@tamanu/shared/permissions/rolesToPermissions");
const _lodash = require("lodash");
const _allergy = require("./allergy");
const _appointments = require("./appointments");
const _asset = require("./asset");
const _attachment = require("./attachment");
const _certificateNotification = require("./certificateNotification");
const _changePassword = require("./changePassword");
const _department = require("./department");
const _diagnosis = require("./diagnosis");
const _encounter = require("./encounter");
const _facility = require("./facility");
const _familyHistory = require("./familyHistory");
const _imaging = require("./imaging");
const _invoice = require("./invoice");
const _labs = require("./labs");
const _labRequestLog = require("./labRequestLog");
const _location = require("./location");
const _locationAssignments = require("./locationAssignments");
const _locationGroup = require("./locationGroup");
const _medication = require("./medication");
const _note = require("./note");
const _ongoingCondition = require("./ongoingCondition");
const _patient = require("./patient");
const _patientFacility = require("./patientFacility");
const _template = require("./template");
const _procedure = require("./procedure");
const _program = require("./program");
const _programRegistry = require("./programRegistry");
const _referenceData = require("./referenceData");
const _referral = require("./referral");
const _reportRequest = require("./reportRequest");
const _reports = require("./reports");
const _resetPassword = require("./resetPassword");
const _scheduledVaccine = require("./scheduledVaccine");
const _survey = require("./survey");
const _surveyResponse = require("./surveyResponse");
const _surveyResponseAnswer = require("./surveyResponseAnswer");
const _sync = require("./sync");
const _syncHealth = require("./syncHealth");
const _triage = require("./triage");
const _user = require("./user");
const _vitals = require("./vitals");
const _translation = require("./translation");
const _upcomingVaccinations = require("./upcomingVaccinations");
const _telegramRoutes = require("./telegram/telegramRoutes");
const _tasks = require("./task/tasks");
const _notifications = require("./notifications");
const _random = require("./random");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const passthrough = (_req, _res, next)=>next();
function createApiv1({ authLimiter } = {}) {
    const limiter = authLimiter ?? passthrough;
    const apiv1 = _express.default.Router();
    const patientDataRoutes = _express.default.Router();
    const referenceDataRoutes = _express.default.Router();
    const syncRoutes = _express.default.Router();
    // auth endpoints (added pre auth check)
    apiv1.post('/login', limiter, _auth.loginHandler);
    apiv1.use('/resetPassword', limiter, _resetPassword.resetPassword);
    apiv1.use('/changePassword', limiter, _changePassword.changePassword);
    apiv1.get('/public/ping', (0, _expressasynchandler.default)((req, res)=>{
        req.flagPermissionChecked();
        return res.send({
            ok: 'ok'
        });
    }));
    apiv1.get('/public/translation/languageOptions', (0, _expressasynchandler.default)(async (req, res)=>{
        req.flagPermissionChecked();
        const { TranslatedString } = req.models;
        const response = await TranslatedString.getPossibleLanguages();
        res.send(response);
    }));
    apiv1.get('/public/translation/:language', (0, _expressasynchandler.default)(async (req, res)=>{
        // Everyone can access translations
        req.flagPermissionChecked();
        const { models: { TranslatedString }, params: { language } } = req;
        const translatedStringRecords = await TranslatedString.findAll({
            where: {
                language
            },
            attributes: [
                'stringId',
                'text'
            ]
        });
        res.send((0, _lodash.mapValues)((0, _lodash.keyBy)(translatedStringRecords, 'stringId'), 'text'));
    }));
    apiv1.use(_auth.authMiddleware);
    apiv1.use(_middleware.constructPermission);
    apiv1.use(_audit.attachAuditUserToDbSession);
    apiv1.delete('/admin/settings/cache', (0, _expressasynchandler.default)(async (req, res)=>{
        req.checkPermission('manage', 'all');
        _settings.settingsCache.reset();
        res.status(204).send();
    }));
    apiv1.get('/admin/roles', (0, _expressasynchandler.default)(async (req, res)=>{
        if (req.user.role !== 'admin') {
            throw new _errors.ForbiddenError('Only admins can list roles');
        }
        req.flagPermissionChecked();
        const { Role } = req.models;
        const roles = await Role.findAll({
            attributes: [
                'id',
                'name'
            ],
            order: [
                [
                    'name',
                    'ASC'
                ]
            ]
        });
        res.send(roles);
    }));
    apiv1.post('/admin/impersonate', (0, _expressasynchandler.default)(async (req, res)=>{
        const { user, userDevice: device, facilityId, models } = req;
        if (user.role !== 'admin') {
            throw new _errors.ForbiddenError('Only admins can impersonate roles');
        }
        req.flagPermissionChecked();
        const { roleId } = _zod.object({
            roleId: _zod.string().min(1).nullable().default(null)
        }).parse(req.body);
        if (roleId === user.role) {
            throw new _errors.ForbiddenError('Cannot impersonate your own role');
        }
        const role = roleId ? await models.Role.findByPk(roleId) : null;
        if (roleId && !role) {
            throw new _errors.ForbiddenError('Impersonation role does not exist');
        }
        _logging.log.info('Role impersonation', {
            userId: user.id,
            action: roleId ? 'start' : 'stop',
            impersonateRoleId: roleId
        });
        const token = await (0, _auth.buildToken)({
            user,
            deviceId: device?.id,
            facilityId,
            impersonateRoleId: roleId ?? undefined
        });
        const roleString = roleId || user.role;
        const permissions = await (0, _rolesToPermissions.getPermissionsForRoles)(models, roleString);
        res.send({
            token,
            role: role?.forResponse() ?? null,
            permissions
        });
    }));
    apiv1.post('/refresh', _auth.refreshHandler);
    apiv1.post('/setFacility', _auth.setFacilityHandler);
    apiv1.use(patientDataRoutes); // see below for specifics
    apiv1.use(referenceDataRoutes); // see below for specifics
    apiv1.use(syncRoutes); // see below for specifics
    apiv1.use('/telegram', _telegramRoutes.telegramRoutes);
    // patient data endpoints
    patientDataRoutes.use('/allergy', _allergy.allergy);
    patientDataRoutes.use('/appointments', _appointments.appointments);
    patientDataRoutes.use('/diagnosis', _diagnosis.diagnosis);
    patientDataRoutes.use('/encounter', _encounter.encounter);
    patientDataRoutes.use('/familyHistory', _familyHistory.familyHistory);
    patientDataRoutes.use('/imagingRequest', _imaging.imagingRequest);
    patientDataRoutes.use('/invoices', _invoice.invoices);
    patientDataRoutes.use('/labRequest', _labs.labRequest);
    patientDataRoutes.use('/labTest', _labs.labTest);
    patientDataRoutes.use('/labTestType', _labs.labTestType);
    patientDataRoutes.use('/labTestPanel', _labs.labTestPanel);
    patientDataRoutes.use('/medication', _medication.medication);
    patientDataRoutes.use('/notes', _note.notes);
    patientDataRoutes.use('/ongoingCondition', _ongoingCondition.ongoingCondition);
    patientDataRoutes.use('/patient', _patient.patient);
    patientDataRoutes.use('/patientCarePlan', _patient.patientCarePlan);
    patientDataRoutes.use('/patientIssue', _patient.patientIssue);
    patientDataRoutes.use('/procedure', _procedure.procedure);
    patientDataRoutes.use('/referral', _referral.referral);
    patientDataRoutes.use('/surveyResponse', _surveyResponse.surveyResponse);
    patientDataRoutes.use('/surveyResponseAnswer', _surveyResponseAnswer.surveyResponseAnswer);
    patientDataRoutes.use('/triage', _triage.triage);
    patientDataRoutes.use('/vitals', _vitals.vitals);
    patientDataRoutes.use('/tasks', _tasks.tasks);
    patientDataRoutes.use('/notifications', _notifications.notifications);
    // reference data endpoints
    referenceDataRoutes.use('/asset', _asset.asset);
    referenceDataRoutes.use('/attachment', _attachment.attachment);
    referenceDataRoutes.use('/certificateNotification', _certificateNotification.certificateNotification);
    referenceDataRoutes.use('/department', _department.department);
    referenceDataRoutes.use('/facility', _facility.facility);
    referenceDataRoutes.use('/labRequestLog', _labRequestLog.labRequestLog);
    referenceDataRoutes.use('/location', _location.location);
    referenceDataRoutes.use('/locationAssignments', _locationAssignments.locationAssignments);
    referenceDataRoutes.use('/locationGroup', _locationGroup.locationGroup);
    referenceDataRoutes.use('/patientFieldDefinition', _patient.patientFieldDefinition);
    referenceDataRoutes.use('/template', _template.template);
    referenceDataRoutes.use('/program', _program.program);
    referenceDataRoutes.use('/programRegistry', _programRegistry.programRegistry);
    referenceDataRoutes.use('/referenceData', _referenceData.referenceData);
    referenceDataRoutes.use('/reportRequest', _reportRequest.reportRequest);
    referenceDataRoutes.use('/reports', _reports.reports);
    referenceDataRoutes.use('/scheduledVaccine', _scheduledVaccine.scheduledVaccine);
    referenceDataRoutes.use('/suggestions', _suggestions.suggestions);
    referenceDataRoutes.use('/survey', _survey.survey);
    referenceDataRoutes.use('/user', _user.user);
    referenceDataRoutes.use('/upcomingVaccinations', _upcomingVaccinations.upcomingVaccinations);
    referenceDataRoutes.use('/translation', _translation.translation);
    // sync endpoints
    syncRoutes.use('/sync', _sync.sync);
    syncRoutes.use('/syncHealth', _syncHealth.syncHealth);
    syncRoutes.use('/patientFacility', _patientFacility.patientFacility);
    // Random record picker for tests / synthetic load (see packages/synthetic-tests RandomEntityFetcher).
    // Off by default in non-test environments; set TAMANU_ENABLE_SYNTHETIC_RANDOM_API=true to enable.
    const enableRandomRecordApi = process.env.NODE_ENV === 'test' || process.env.TAMANU_ENABLE_SYNTHETIC_RANDOM_API === 'true';
    if (enableRandomRecordApi) {
        apiv1.use('/random', _random.random);
    }
    return apiv1;
}

//# sourceMappingURL=index.js.map