"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 DIAGNOSTIC_REPORT_INCLUDES () {
        return DIAGNOSTIC_REPORT_INCLUDES;
    },
    get diagnosticReport () {
        return diagnosticReport;
    },
    get immunization () {
        return immunization;
    },
    get patient () {
        return patient;
    }
});
const _yup = /*#__PURE__*/ _interop_require_wildcard(require("yup"));
const _lodash = require("lodash");
const _utils = require("./utils");
const _hl7PatientFields = require("./hl7PatientFields");
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 MAX_RECORDS = 20;
// Explicitly set with the direction sign
const sortableHL7BaseFields = [
    '-issued',
    'issued'
];
// List of all the fixed name parameters that we support
const baseParameters = {
    // TODO: remove subject:identifier after the fiji VPS is good without it.
    // Patients don't have a subject parameter,
    // this is just for backwards compatibility.
    'subject:identifier': _yup.string().test('is-correct-format-and-namespace', 'subject:identifier must be in the format "<namespace>|<id>"', _utils.isValidIdentifier),
    _count: _yup.number().integer().min(1).max(MAX_RECORDS).default(MAX_RECORDS).required(),
    _page: _yup.number().integer().min(0).default(0).required(),
    _sort: _yup.string().oneOf(sortableHL7BaseFields).default('-issued').required(),
    after: _yup.object({
        id: _yup.string().required(),
        createdAt: _yup.date().required()
    }).nullable().default(null),
    // TODO: remove status after the fiji VPS is good without it.
    // Patients don't have a status parameter,
    // this is just for backwards compatibility.
    status: _yup.string()
};
// Returns an object with patient parameters as keys
// and yup validation schema for each field as values.
const getPatientParameters = ()=>{
    const parameters = {};
    Object.entries(_hl7PatientFields.hl7PatientFields).forEach(([paramName, paramConfig])=>{
        const { supportedModifiers = [], validationSchema } = paramConfig;
        if (!validationSchema) {
            throw new Error(`The key ${paramName} from hl7PatientFields needs a validationSchema key.`);
        }
        // Add the parameter without suffix
        parameters[paramName] = validationSchema;
        // Add the parameter with all the supported modifiers
        supportedModifiers.forEach((modifier)=>{
            const suffixedName = `${paramName}:${modifier}`;
            parameters[suffixedName] = validationSchema;
        });
    });
    return parameters;
};
// Custom function for yup's noUnknown error message
function noUnknownValidationMessage(obj) {
    // Get all params from the object being validated
    const params = Object.keys(obj.originalValue);
    // Return list of unknown params
    const unknownParams = params.filter((param)=>param in patient.query.fields === false);
    return `Unknown or unsupported parameters: ${unknownParams.join(', ')}`;
}
const patient = {
    query: _yup.object({
        ...getPatientParameters(),
        ...baseParameters,
        // Overwrite sort for patient resource
        _sort: _yup.string().test('is-supported-sort', 'Unsupported or unknown parameters in _sort', (value)=>{
            // Sorts are separated by commas, no whitespace
            const sorts = value.split(',');
            // Faster to check if one is invalid
            const isInvalid = sorts.some((sort)=>{
                // Ignore base fields
                if (sortableHL7BaseFields.includes(sort)) return false;
                // Sort might have a "-" at the beginning, we should ignore it here
                const parameter = (0, _utils.getSortParameterName)(sort);
                return _hl7PatientFields.sortableHL7PatientFields.includes(parameter) === false;
            });
            return !isInvalid;
        }).default('-issued').required()
    }).noUnknown(true, noUnknownValidationMessage)
};
const DIAGNOSTIC_REPORT_INCLUDES = {
    RESULT: 'DiagnosticReport:result',
    DEVICE: 'DiagnosticReport:result.device:Device'
};
const diagnosticReport = {
    query: _yup.object({
        ...baseParameters,
        // This will overwrite the validation in baseParameters for this field,
        // making it required for DiagnosticReport route.
        // Only kept for backwards compatibility.
        'subject:identifier': _yup.string().test('is-correct-format-and-namespace', 'subject:identifier must be in the format "<namespace>|<id>"', _utils.isValidIdentifier).required(),
        _include: _yup.array().of(_yup.string().oneOf(Object.values(DIAGNOSTIC_REPORT_INCLUDES))).transform((_, originalValue)=>{
            if ((0, _lodash.isArray)(originalValue)) {
                return originalValue;
            }
            return [
                originalValue
            ];
        }),
        status: _yup.string().oneOf([
            'final'
        ])
    }).noUnknown(true, noUnknownValidationMessage)
};
const immunization = {
    query: _yup.object({
        ...baseParameters,
        patient: _yup.string(),
        'vaccine-code': _yup.string()
    }).noUnknown(true, noUnknownValidationMessage)
};

//# sourceMappingURL=schema.js.map