"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get AdministeredVaccine () {
        return AdministeredVaccine;
    },
    get Base () {
        return Base;
    },
    get CertifiableVaccine () {
        return CertifiableVaccine;
    },
    get Department () {
        return Department;
    },
    get Encounter () {
        return Encounter;
    },
    get Facility () {
        return Facility;
    },
    get InvoicePriceList () {
        return InvoicePriceList;
    },
    get InvoiceProduct () {
        return InvoiceProduct;
    },
    get LabTestPanel () {
        return LabTestPanel;
    },
    get LabTestPanelLabTestTypes () {
        return LabTestPanelLabTestTypes;
    },
    get LabTestType () {
        return LabTestType;
    },
    get Location () {
        return Location;
    },
    get LocationGroup () {
        return LocationGroup;
    },
    get Patient () {
        return Patient;
    },
    get PatientAdditionalData () {
        return PatientAdditionalData;
    },
    get PatientFieldValue () {
        return PatientFieldValue;
    },
    get Permission () {
        return Permission;
    },
    get ProcedureTypeSurvey () {
        return ProcedureTypeSurvey;
    },
    get ProgramDataElement () {
        return ProgramDataElement;
    },
    get ProgramRegistry () {
        return ProgramRegistry;
    },
    get ProgramRegistryClinicalStatus () {
        return ProgramRegistryClinicalStatus;
    },
    get ProgramRegistryCondition () {
        return ProgramRegistryCondition;
    },
    get RDmanufacturer () {
        return RDmanufacturer;
    },
    get ReferenceData () {
        return ReferenceData;
    },
    get ReferenceDataRelation () {
        return ReferenceDataRelation;
    },
    get ReferenceDrugFacility () {
        return ReferenceDrugFacility;
    },
    get ReferenceMedicationTemplate () {
        return ReferenceMedicationTemplate;
    },
    get ScheduledVaccine () {
        return ScheduledVaccine;
    },
    get Survey () {
        return Survey;
    },
    get SurveyScreenComponent () {
        return SurveyScreenComponent;
    },
    get TaskTemplate () {
        return TaskTemplate;
    },
    get TaskTemplateDesignation () {
        return TaskTemplateDesignation;
    },
    get TranslatedString () {
        return TranslatedString;
    },
    get User () {
        return User;
    },
    get UserDesignation () {
        return UserDesignation;
    },
    get UserFacility () {
        return UserFacility;
    },
    get baseConfigShape () {
        return baseConfigShape;
    },
    get baseValidationShape () {
        return baseValidationShape;
    }
});
const _yup = /*#__PURE__*/ _interop_require_wildcard(require("yup"));
const _constants = require("@tamanu/constants");
const _config = /*#__PURE__*/ _interop_require_default(require("config"));
const _jsonString = require("./jsonString");
const _rangeObject = require("./rangeObject");
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 visibilityStatus = _yup.string().default(_constants.VISIBILITY_STATUSES.CURRENT).oneOf(Object.values(_constants.VISIBILITY_STATUSES));
const safeIdRegex = /^[A-Za-z0-9-]+$/;
const safeCodeRegex = /^[A-Za-z0-9-./]+$/;
const fieldTypes = {
    id: _yup.string().matches(safeIdRegex, 'id must not have spaces or punctuation other than -'),
    code: _yup.string().matches(safeCodeRegex, 'code must not have spaces or punctuation other than -./'),
    name: _yup.string().max(255)
};
const Base = _yup.object().shape({
    id: fieldTypes.id.required()
});
const availableFacilities = _yup.mixed().nullable().default(null).transform((value)=>{
    if (!value) return null;
    if (Array.isArray(value)) return value;
    try {
        return JSON.parse(value);
    } catch  {
        return value;
    }
}).test('is-valid-facility-array', 'availableFacilities must be null or a JSON array of facility IDs', (value)=>{
    if (value === null || value === undefined) return true;
    return Array.isArray(value) && value.every((id)=>typeof id === 'string');
});
const ReferenceData = Base.shape({
    type: _yup.string().required(),
    code: fieldTypes.code.required(),
    name: _yup.string().required(),
    visibilityStatus,
    availableFacilities
});
const RDmanufacturer = ReferenceData.shape({
    code: fieldTypes.code.matches(/^((?!ORG-).+|ORG-[0-9]+)$/, 'must either by a textual code or an EU ORG code').required(),
    name: _yup.string().required()
});
const Patient = Base.shape({
    firstName: _yup.string().required(),
    middleName: _yup.string(),
    lastName: _yup.string().required(),
    culturalName: _yup.string(),
    displayId: _yup.string().required(),
    sex: _yup.string().oneOf([
        'male',
        'female',
        'other'
    ]).required(),
    dateOfBirth: _yup.date().required(),
    dateOfDeath: _yup.date(),
    villageId: _yup.string()
});
const PatientAdditionalData = _yup.object().shape({
    patientId: _yup.string().required()
});
const PatientFieldValue = _yup.object().shape({
    patientId: _yup.string().required(),
    definitionId: _yup.string().required()
});
const User = Base.shape({
    email: _yup.string().required(),
    displayId: _yup.string(),
    displayName: _yup.string().required(),
    password: _yup.string(),
    phoneNumber: _yup.string(),
    visibilityStatus: _yup.string().default(_constants.VISIBILITY_STATUSES.CURRENT).oneOf([
        _constants.VISIBILITY_STATUSES.CURRENT,
        _constants.VISIBILITY_STATUSES.HISTORICAL
    ])
});
const Facility = Base.shape({
    code: fieldTypes.code.required(),
    name: fieldTypes.name.required(),
    email: _yup.string(),
    contactNumber: _yup.string(),
    streetAddress: _yup.string(),
    cityTown: _yup.string(),
    division: _yup.string(),
    type: _yup.string(),
    visibilityStatus
});
const Department = Base.shape({
    code: fieldTypes.code.required(),
    name: fieldTypes.name.required(),
    facilityId: _yup.string().required(),
    visibilityStatus
});
const Location = Base.shape({
    code: fieldTypes.code.required(),
    name: fieldTypes.name.required(),
    facilityId: _yup.string().required(),
    visibilityStatus,
    maxOccupancy: _yup.number().integer().min(1, 'maxOccupancy must be 1 or null for unrestricted occupancy').max(1, 'maxOccupancy above 1 is unimplemented')
});
const LocationGroup = Base.shape({
    code: fieldTypes.code.required(),
    name: fieldTypes.name.required(),
    facilityId: _yup.string().required(),
    visibilityStatus,
    isBookable: _yup.string().default(_constants.LOCATION_BOOKABLE_VIEW.NO).oneOf(_constants.LOCATION_BOOKABLE_VIEW_VALUES)
});
const Permission = _yup.object().shape({
    _yCell: _yup.string().oneOf([
        'y',
        'n'
    ], 'permissions matrix must only use the letter y or n'),
    verb: _yup.string().required().trim(),
    noun: _yup.string().required().trim().oneOf(_constants.PERMISSION_NOUNS, 'Noun is invalid or does not exist'),
    objectId: _yup.string().nullable().trim(),
    deletedAt: _yup.date().nullable()
});
const rangeRegex = /^[0-9.]+, [0-9.]+$/;
const LabTestType = Base.shape({
    name: _yup.string().required(),
    labTestCategoryId: _yup.string().required(),
    resultType: _yup.string().required().oneOf(Object.values(_constants.LAB_TEST_RESULT_TYPES)),
    options: _yup.string(),
    unit: _yup.string(),
    maleRange: _yup.string().matches(rangeRegex),
    femaleRange: _yup.string().matches(rangeRegex),
    visibilityStatus: _yup.string().default(_constants.LAB_TEST_TYPE_VISIBILITY_STATUSES.CURRENT).oneOf(Object.values(_constants.LAB_TEST_TYPE_VISIBILITY_STATUSES)),
    availableFacilities
});
const LabTestPanel = Base.shape({
    name: _yup.string().required(),
    code: _yup.string().required(),
    categoryId: _yup.string().required(),
    visibilityStatus,
    availableFacilities
});
const LabTestPanelLabTestTypes = _yup.object().shape({
    // id is auto generated by db, so don't require it on import
    labTestPanelId: _yup.string().required(),
    labTestTypeId: _yup.string().required()
});
const visualisationConfigSchema = _yup.object().shape({
    yAxis: _yup.object().shape({
        graphRange: _yup.lazy((value)=>Array.isArray(value) ? _rangeObject.rangeArraySchema : _rangeObject.rangeObjectSchema),
        interval: _yup.number().required()
    })
});
const ProgramDataElement = Base.shape({
    indicator: _yup.string(),
    type: _yup.string().required().oneOf(_constants.PROGRAM_DATA_ELEMENT_TYPE_VALUES),
    defaultOptions: (0, _jsonString.jsonString)(),
    visualisationConfig: (0, _jsonString.visualisationConfigString)(visualisationConfigSchema)
});
const baseValidationShape = _yup.object().shape({
    mandatory: _yup.lazy((value)=>{
        return typeof value === 'boolean' ? _yup.boolean() : _yup.object().shape({
            encounterType: _yup.mixed()
        });
    })
}).noUnknown();
const baseConfigShape = _yup.object().noUnknown();
const SurveyScreenComponent = Base.shape({
    visibilityCriteria: (0, _jsonString.jsonString)(),
    validationCriteria: _config.default.validateQuestionConfigs.enabled ? (0, _jsonString.validationString)(baseValidationShape) : (0, _jsonString.jsonString)(),
    config: _config.default.validateQuestionConfigs.enabled ? (0, _jsonString.configString)(baseConfigShape) : (0, _jsonString.jsonString)(),
    screenIndex: _yup.number().required(),
    componentIndex: _yup.number().required(),
    options: (0, _jsonString.jsonString)(),
    calculation: _yup.string(),
    surveyId: _yup.string().required(),
    detail: _yup.string().max(255),
    dataElementId: _yup.string().required(),
    visibilityStatus
});
const ScheduledVaccine = Base.shape({
    category: _yup.string().required(),
    label: _yup.string().required(),
    doseLabel: _yup.string().required(),
    weeksFromBirthDue: _yup.number().when([
        'doseLabel',
        'index'
    ], {
        is: (doseLabel, index)=>{
            if (!doseLabel.startsWith('Dose')) return false;
            return index > 1;
        },
        then: _yup.number().test('is-null', 'Weeks from birth due should not be set for non-first doses', (value)=>{
            return value === undefined;
        }),
        otherwise: _yup.number()
    }),
    weeksFromLastVaccinationDue: _yup.number().when([
        'doseLabel',
        'index'
    ], {
        is: (doseLabel, index)=>{
            if (!doseLabel.startsWith('Dose')) return false;
            return index === 1;
        },
        then: _yup.number().test('is-null', 'Weeks from last vaccination due should not be set for first doses', (value)=>value === undefined),
        otherwise: _yup.number()
    }),
    index: _yup.number().required(),
    vaccineId: _yup.string().required(),
    visibilityStatus,
    sortIndex: _yup.number().required()
});
const ICD11_REGEX = /^([0-9A-HJ-NP-V]{1,4}(\.[0-9A-HJ-NP-V]{1,4})?|X[0-9A-HJ-NP-Z.]+)$/;
const SNOMED_OR_ATC = /^([0-9]+|[A-Z][0-9A-Z]*)$/;
const EITHER_EU_CODE_OR_SOMETHING_ELSE = /^((?!EU\/).+|EU\/[0-9]\/[0-9]{2}\/[0-9]+)$/;
const CertifiableVaccine = Base.shape({
    icd11DrugCode: _yup.string().matches(ICD11_REGEX, 'must be ICD-11 code').required(),
    icd11DiseaseCode: _yup.string().matches(ICD11_REGEX, 'must be ICD-11 code').required(),
    vaccineCode: _yup.string().matches(SNOMED_OR_ATC, 'must be SNOMED-CT or ATC code').required(),
    targetCode: _yup.string().matches(SNOMED_OR_ATC, 'must be SNOMED-CT or ATC code').optional(),
    euProductCode: _yup.string().matches(EITHER_EU_CODE_OR_SOMETHING_ELSE, 'must either be a name or an EU product code').optional(),
    maximumDosage: _yup.number().positive().integer().required(),
    vaccineId: _yup.string().required(),
    manufacturerId: _yup.string().optional()
});
const Survey = Base.shape({
    surveyType: _yup.string().required().oneOf(Object.values(_constants.SURVEY_TYPES)),
    isSensitive: _yup.boolean().required(),
    visibilityStatus: _yup.string().default(_constants.VISIBILITY_STATUSES.CURRENT).oneOf([
        _constants.VISIBILITY_STATUSES.CURRENT,
        _constants.VISIBILITY_STATUSES.HISTORICAL
    ]),
    visibilityCriteria: (0, _jsonString.jsonString)()
});
const ProgramRegistry = Base.shape({
    code: fieldTypes.code.required(),
    name: _yup.string().required(),
    visibilityStatus,
    lossToFollowUpEnabled: _yup.boolean().default(false),
    lossToFollowUpThresholdDays: _yup.number().integer().positive().default(90)
});
const ProgramRegistryClinicalStatus = Base.shape({
    code: fieldTypes.code.required(),
    name: _yup.string().required(),
    color: _yup.string().required().oneOf(Object.keys(_constants.STATUS_COLOR)),
    visibilityStatus
});
const ProgramRegistryCondition = Base.shape({
    code: fieldTypes.code.required(),
    name: _yup.string().required(),
    visibilityStatus
});
const AdministeredVaccine = Base.shape({
    batch: _yup.string(),
    consent: _yup.boolean().required(),
    status: _yup.string().oneOf(Object.values(_constants.VACCINE_STATUS)).required(),
    reason: _yup.string(),
    injectionSite: _yup.string().oneOf(Object.values(_constants.INJECTION_SITE_VALUES)),
    date: _yup.date().required(),
    scheduledVaccineId: fieldTypes.id.required(),
    encounterId: fieldTypes.id.required()
});
const Encounter = Base.shape({
    // contains only what's needed for administeredVaccine imports, extend as necessary
    encounterType: _yup.string().oneOf(Object.values(_constants.ENCOUNTER_TYPES)),
    startDate: _yup.date().required(),
    endDate: _yup.date(),
    reasonForEncounter: _yup.string(),
    // relationships
    locationId: _yup.string().required(),
    departmentId: _yup.string().required(),
    examinerId: _yup.string().required(),
    patientId: _yup.string().required()
});
const TranslatedString = _yup.object().shape({
    stringId: _yup.string().required()
});
const ReferenceDataRelation = _yup.object().shape({
    referenceDataParentId: _yup.string().required(),
    referenceDataId: _yup.string().required(),
    type: _yup.string().oneOf(Object.values(_constants.REFERENCE_DATA_RELATION_TYPES))
});
const UserFacility = _yup.object().shape({
    // id is auto generated by db, so don't require it on import
    facilityId: _yup.string().required(),
    userId: _yup.string().required()
});
// yup's .noUnknown() silently strips unknown keys in non-strict validate() mode, so
// we use an explicit .test() to surface typos (e.g. "facility_id" instead of "facilityId").
const KNOWN_RULE_KEYS = [
    'facilityId',
    'patientType',
    'patientAge'
];
const KNOWN_AGE_KEYS = [
    'min',
    'max'
];
const invoicePriceListRulesSchema = _yup.object().nullable().default(null).test('known-keys', 'invalid rules', function(value) {
    if (value == null) return true;
    const unknown = Object.keys(value).filter((k)=>!KNOWN_RULE_KEYS.includes(k));
    if (unknown.length > 0) {
        return this.createError({
            message: `rules has unknown keys: ${unknown.join(', ')} (expected ${KNOWN_RULE_KEYS.join(', ')})`
        });
    }
    const { patientAge } = value;
    if (patientAge != null && typeof patientAge === 'object') {
        const unknownAge = Object.keys(patientAge).filter((k)=>!KNOWN_AGE_KEYS.includes(k));
        if (unknownAge.length > 0) {
            return this.createError({
                message: `rules.patientAge has unknown keys: ${unknownAge.join(', ')} (expected min, max)`
            });
        }
    } else if (patientAge != null && typeof patientAge !== 'number') {
        return this.createError({
            message: 'rules.patientAge must be a number or an object like {min, max}'
        });
    }
    return true;
});
const InvoicePriceList = _yup.object().shape({
    id: fieldTypes.id.required(),
    code: fieldTypes.code.required(),
    name: _yup.string().nullable(),
    rules: invoicePriceListRulesSchema,
    evaluationOrder: _yup.number().integer().nullable(),
    visibilityStatus
});
const InvoiceProduct = _yup.object().shape({
    id: _yup.string().required(),
    name: _yup.string().required(),
    category: _yup.string().oneOf(Object.values(_constants.INVOICE_ITEMS_CATEGORIES)),
    sourceRecordType: _yup.string().oneOf(Array.from(new Set(Object.values(_constants.INVOICE_ITEMS_CATEGORIES_MODELS)))),
    sourceRecordId: _yup.string(),
    insurable: _yup.boolean(),
    visibilityStatus
});
const UserDesignation = _yup.object().shape({
    userId: _yup.string().required(),
    designationId: _yup.string().required()
});
const TaskTemplate = _yup.object().shape({
    id: _yup.string().required(),
    referenceDataId: _yup.string().required(),
    highPriority: _yup.boolean().optional(),
    frequencyValue: _yup.number().moreThan(0).optional(),
    frequencyUnit: _yup.string().optional().transform((value)=>_constants.TASK_FREQUENCY_ACCEPTED_UNITS_TO_VALUE[value] || value).oneOf([
        ...Object.values(_constants.TASK_FREQUENCY_ACCEPTED_UNITS),
        null
    ])
});
const TaskTemplateDesignation = _yup.object().shape({
    taskTemplateId: _yup.string().required(),
    designationId: _yup.string().required()
});
const ProcedureTypeSurvey = _yup.object().shape({
    // id is auto generated by db, so don't require it on import
    procedureTypeId: _yup.string().required(),
    surveyId: _yup.string().required()
});
const ReferenceMedicationTemplate = _yup.object().shape({
    id: _yup.string().required(),
    referenceDataId: _yup.string().required(),
    isPrn: _yup.boolean().default(false),
    isVariableDose: _yup.boolean().default(false),
    doseAmount: _yup.number().nullable().positive().when('isVariableDose', {
        is: false,
        then: (schema)=>schema.required('Dose amount is required when isVariableDose is false.'),
        otherwise: (schema)=>schema.nullable()
    }),
    units: _yup.string().required().oneOf(Object.values(_constants.DRUG_UNITS)),
    frequency: _yup.string().required().oneOf(Object.values(_constants.ADMINISTRATION_FREQUENCIES)),
    route: _yup.string().required().oneOf(Object.values(_constants.DRUG_ROUTE_VALUES)).transform((value)=>Object.keys(_constants.DRUG_ROUTE_LABELS).find((key)=>_constants.DRUG_ROUTE_LABELS[key] === value) || value),
    durationValue: _yup.number().nullable().positive(),
    durationUnit: _yup.string().oneOf([
        ...Object.values(_constants.MEDICATION_DURATION_UNITS),
        null
    ]).nullable(),
    notes: _yup.string().optional().nullable(),
    dischargeQuantity: _yup.number().optional().nullable().positive(),
    isOngoing: _yup.boolean().default(false)
}).test('duration-paired', null, function({ durationValue, durationUnit }) {
    if (durationValue && !durationUnit) {
        return this.createError({
            path: 'durationUnit',
            message: 'Duration unit is required when duration value is provided.'
        });
    }
    if (!durationValue && durationUnit) {
        return this.createError({
            path: 'durationValue',
            message: 'Duration value is required when duration unit is provided.'
        });
    }
    return true;
}).test('forbid-duration-when-frequency-is-immediately', null, function({ frequency, durationValue, durationUnit }) {
    if (frequency === _constants.ADMINISTRATION_FREQUENCIES.IMMEDIATELY && (durationValue || durationUnit)) {
        return this.createError({
            path: 'durationValue',
            message: 'Duration is not allowed when frequency is Immediately.'
        });
    }
    return true;
}).test('forbid-duration-when-medication-is-ongoing', null, function({ isOngoing, durationValue, durationUnit }) {
    if (isOngoing && (durationValue || durationUnit)) {
        return this.createError({
            path: 'durationValue',
            message: 'Duration is not allowed when medication is ongoing.'
        });
    }
    return true;
});
const ReferenceDrugFacility = _yup.object().shape({
    referenceDrugId: _yup.string().required(),
    facilityId: _yup.string().required(),
    quantity: _yup.number().integer().nullable(),
    stockStatus: _yup.string().oneOf(Object.values(_constants.DRUG_STOCK_STATUSES))
});

//# sourceMappingURL=baseSchemas.js.map