"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.IcureBasicApi = exports.IcureApi = exports.EncryptedFieldsConfig = exports.SecretIdUseOption = exports.getShaVersionForKey = exports.hexPublicKeysWithSha256Of = exports.hexPublicKeysWithSha1Of = exports.NativeCryptoPrimitivesBridge = exports.KeyStorageImpl = exports.LocalStorageImpl = exports.AuthSecretType = void 0;
const icc_api_1 = require("../icc-api");
const icc_user_x_api_1 = require("./icc-user-x-api");
const icc_crypto_x_api_1 = require("./icc-crypto-x-api");
const icc_contact_x_api_1 = require("./icc-contact-x-api");
const icc_invoice_x_api_1 = require("./icc-invoice-x-api");
const icc_document_x_api_1 = require("./icc-document-x-api");
const icc_hcparty_x_api_1 = require("./icc-hcparty-x-api");
const icc_form_x_api_1 = require("./icc-form-x-api");
const icc_helement_x_api_1 = require("./icc-helement-x-api");
const icc_classification_x_api_1 = require("./icc-classification-x-api");
const icc_calendar_item_x_api_1 = require("./icc-calendar-item-x-api");
const icc_patient_x_api_1 = require("./icc-patient-x-api");
const icc_message_x_api_1 = require("./icc-message-x-api");
const icc_receipt_x_api_1 = require("./icc-receipt-x-api");
const icc_accesslog_x_api_1 = require("./icc-accesslog-x-api");
const icc_code_x_api_1 = require("./icc-code-x-api");
const icc_maintenance_task_x_api_1 = require("./icc-maintenance-task-x-api");
const icc_data_owner_x_api_1 = require("./icc-data-owner-x-api");
const LocalStorageImpl_1 = require("./storage/LocalStorageImpl");
const KeyStorageImpl_1 = require("./storage/KeyStorageImpl");
const AuthenticationProvider_1 = require("./auth/AuthenticationProvider");
const CryptoPrimitives_1 = require("./crypto/CryptoPrimitives");
const UserEncryptionKeysManager_1 = require("./crypto/UserEncryptionKeysManager");
const IcureStorageFacade_1 = require("./storage/IcureStorageFacade");
const DefaultStorageEntryKeysFactory_1 = require("./storage/DefaultStorageEntryKeysFactory");
const KeyRecovery_1 = require("./crypto/KeyRecovery");
const BaseExchangeKeysManager_1 = require("./crypto/BaseExchangeKeysManager");
const ExchangeKeysManager_1 = require("./crypto/ExchangeKeysManager");
const ShamirKeysManager_1 = require("./crypto/ShamirKeysManager");
const TransferKeysManager_1 = require("./crypto/TransferKeysManager");
const icc_icure_maintenance_x_api_1 = require("./icc-icure-maintenance-x-api");
const utils_1 = require("./crypto/utils");
const ExchangeDataManager_1 = require("./crypto/ExchangeDataManager");
const BaseExchangeDataManager_1 = require("./crypto/BaseExchangeDataManager");
const IccExchangeDataApi_1 = require("../icc-api/api/internal/IccExchangeDataApi");
const AccessControlSecretUtils_1 = require("./crypto/AccessControlSecretUtils");
const SecureDelegationsEncryption_1 = require("./crypto/SecureDelegationsEncryption");
const ExtendedApisUtilsImpl_1 = require("./crypto/ExtendedApisUtilsImpl");
const SecureDelegationsManager_1 = require("./crypto/SecureDelegationsManager");
const AccessControlKeysHeadersProvider_1 = require("./crypto/AccessControlKeysHeadersProvider");
const IccExchangeDataMapApi_1 = require("../icc-api/api/internal/IccExchangeDataMapApi");
const ExchangeDataMapManager_1 = require("./crypto/ExchangeDataMapManager");
const icc_device_x_api_1 = require("./icc-device-x-api");
const icc_bekmehr_x_api_1 = require("./icc-bekmehr-x-api");
const icc_doctemplate_x_api_1 = require("./icc-doctemplate-x-api");
const icc_topic_x_api_1 = require("./icc-topic-x-api");
const IccRoleApi_1 = require("../icc-api/api/IccRoleApi");
const DataOwnerTypeEnum_1 = require("../icc-api/model/DataOwnerTypeEnum");
const DelegationsDeAnonymization_1 = require("./crypto/DelegationsDeAnonymization");
const JwtBridgedAuthService_1 = require("./auth/JwtBridgedAuthService");
const SmartAuthProvider_1 = require("./auth/SmartAuthProvider");
const KeyPairRecoverer_1 = require("./crypto/KeyPairRecoverer");
const IccRecoveryDataApi_1 = require("../icc-api/api/internal/IccRecoveryDataApi");
const RecoveryDataEncryption_1 = require("./crypto/RecoveryDataEncryption");
const icc_recovery_x_api_1 = require("./icc-recovery-x-api");
const JwtUtils_1 = require("./auth/JwtUtils");
const SecurityMetadataDecryptor_1 = require("./crypto/SecurityMetadataDecryptor");
const icc_application_settings_x_api_1 = require("./icc-application-settings-x-api");
__exportStar(require("./icc-accesslog-x-api"), exports);
__exportStar(require("./icc-application-settings-x-api"), exports);
__exportStar(require("./icc-bekmehr-x-api"), exports);
__exportStar(require("./icc-calendar-item-x-api"), exports);
__exportStar(require("./icc-classification-x-api"), exports);
__exportStar(require("./icc-code-x-api"), exports);
__exportStar(require("./icc-contact-x-api"), exports);
__exportStar(require("./icc-crypto-x-api"), exports);
__exportStar(require("./icc-doctemplate-x-api"), exports);
__exportStar(require("./icc-document-x-api"), exports);
__exportStar(require("./icc-form-x-api"), exports);
__exportStar(require("./icc-hcparty-x-api"), exports);
__exportStar(require("./icc-helement-x-api"), exports);
__exportStar(require("./icc-invoice-x-api"), exports);
__exportStar(require("./icc-message-x-api"), exports);
__exportStar(require("./icc-patient-x-api"), exports);
__exportStar(require("./icc-user-x-api"), exports);
__exportStar(require("./icc-receipt-x-api"), exports);
__exportStar(require("./icc-data-owner-x-api"), exports);
__exportStar(require("./icc-icure-maintenance-x-api"), exports);
__exportStar(require("./icc-maintenance-task-x-api"), exports);
__exportStar(require("./icc-recovery-x-api"), exports);
__exportStar(require("./utils"), exports);
__exportStar(require("./crypto/RSA"), exports);
__exportStar(require("./crypto/CryptoPrimitives"), exports);
__exportStar(require("./crypto/ShareMetadataBehaviour"), exports);
__exportStar(require("./auth/AuthenticationProvider"), exports);
var SmartAuthProvider_2 = require("./auth/SmartAuthProvider");
Object.defineProperty(exports, "AuthSecretType", { enumerable: true, get: function () { return SmartAuthProvider_2.AuthSecretType; } });
var LocalStorageImpl_2 = require("./storage/LocalStorageImpl");
Object.defineProperty(exports, "LocalStorageImpl", { enumerable: true, get: function () { return LocalStorageImpl_2.LocalStorageImpl; } });
var KeyStorageImpl_2 = require("./storage/KeyStorageImpl");
Object.defineProperty(exports, "KeyStorageImpl", { enumerable: true, get: function () { return KeyStorageImpl_2.KeyStorageImpl; } });
var NativeCryptoPrimitivesBridge_1 = require("./crypto/NativeCryptoPrimitivesBridge");
Object.defineProperty(exports, "NativeCryptoPrimitivesBridge", { enumerable: true, get: function () { return NativeCryptoPrimitivesBridge_1.NativeCryptoPrimitivesBridge; } });
var utils_2 = require("./crypto/utils");
Object.defineProperty(exports, "hexPublicKeysWithSha1Of", { enumerable: true, get: function () { return utils_2.hexPublicKeysWithSha1Of; } });
Object.defineProperty(exports, "hexPublicKeysWithSha256Of", { enumerable: true, get: function () { return utils_2.hexPublicKeysWithSha256Of; } });
Object.defineProperty(exports, "getShaVersionForKey", { enumerable: true, get: function () { return utils_2.getShaVersionForKey; } });
var SecretIdUseOption_1 = require("./crypto/SecretIdUseOption");
Object.defineProperty(exports, "SecretIdUseOption", { enumerable: true, get: function () { return SecretIdUseOption_1.SecretIdUseOption; } });
var IcureApiOptions;
(function (IcureApiOptions) {
    let Defaults;
    (function (Defaults) {
        Defaults.entryKeysFactory = new DefaultStorageEntryKeysFactory_1.DefaultStorageEntryKeysFactory();
        Defaults.createMaintenanceTasksOnNewKey = true;
        Defaults.headers = {};
    })(Defaults = IcureApiOptions.Defaults || (IcureApiOptions.Defaults = {}));
    class WithDefaults {
        constructor(custom) {
            var _a, _b, _c, _d, _e, _f, _g, _h;
            this.entryKeysFactory = (_a = custom.entryKeysFactory) !== null && _a !== void 0 ? _a : Defaults.entryKeysFactory;
            this.createMaintenanceTasksOnNewKey = (_b = custom.createMaintenanceTasksOnNewKey) !== null && _b !== void 0 ? _b : Defaults.createMaintenanceTasksOnNewKey;
            this.storage = (_c = custom.storage) !== null && _c !== void 0 ? _c : new LocalStorageImpl_1.LocalStorageImpl();
            this.keyStorage = (_d = custom.keyStorage) !== null && _d !== void 0 ? _d : new KeyStorageImpl_1.KeyStorageImpl(this.storage);
            this.headers = (_e = custom.headers) !== null && _e !== void 0 ? _e : Defaults.headers;
            this.encryptedFieldsConfig = (_f = custom.encryptedFieldsConfig) !== null && _f !== void 0 ? _f : {};
            this.groupSelector = (_g = custom.groupSelector) !== null && _g !== void 0 ? _g : ((groups) => Promise.resolve(groups[0].groupId));
            this.disableParentKeysInitialisation = (_h = custom.disableParentKeysInitialisation) !== null && _h !== void 0 ? _h : false;
            this.injectExchangeData = custom.injectExchangeData;
        }
    }
    IcureApiOptions.WithDefaults = WithDefaults;
})(IcureApiOptions || (IcureApiOptions = {}));
var EncryptedFieldsConfig;
(function (EncryptedFieldsConfig) {
    EncryptedFieldsConfig.Defaults = {
        accessLog: ['detail', 'objectId'],
        calendarItem: ['details', 'title', 'patientId'],
        contact: ['descr', 'notes[].markdown'],
        service: ['notes[].markdown'],
        healthElement: ['descr', 'note', 'notes[].markdown'],
        maintenanceTask: ['properties'],
        patient: ['note', 'notes[].markdown'],
        message: [],
        document: [],
        topic: ['description', 'linkedServices', 'linkedHealthElements'],
    };
})(EncryptedFieldsConfig || (exports.EncryptedFieldsConfig = EncryptedFieldsConfig = {}));
var IcureApi;
(function (IcureApi) {
    /**
     * Initialises a new instance of the iCure API.
     */
    function initialise(host_1, authenticationOptions_1, cryptoStrategies_1) {
        return __awaiter(this, arguments, void 0, function* (host, authenticationOptions, cryptoStrategies, crypto = typeof window !== 'undefined' ? window.crypto : typeof self !== 'undefined' ? self.crypto : {}, fetchImpl = typeof window !== 'undefined'
            ? window.fetch
            : typeof self !== 'undefined'
                ? self.fetch
                : fetch, options = {}) {
            var _a, _b;
            const params = new IcureApiOptions.WithDefaults(options);
            let authenticationProviderInfo = yield initialiseAuthProviderWithGroupSelector(host, authenticationOptions, params.headers, fetchImpl, params.groupSelector);
            const cryptoInitInfo = yield initialiseCryptoWithProvider(host, fetchImpl, authenticationProviderInfo.groupSpecificAuthenticationProvider, params, cryptoStrategies, crypto, (_a = options.useLiteCompatibilityMode) !== null && _a !== void 0 ? _a : false);
            return new IcureApiImpl(cryptoInitInfo, host, authenticationProviderInfo.groupSpecificAuthenticationProvider, fetchImpl, authenticationProviderInfo.grouplessUserApi, authenticationProviderInfo.matches, authenticationProviderInfo.matches.find((match) => match.groupId === authenticationProviderInfo.chosenGroupId), params, cryptoStrategies, (_b = options.useLiteCompatibilityMode) !== null && _b !== void 0 ? _b : false);
        });
    }
    IcureApi.initialise = initialise;
})(IcureApi || (exports.IcureApi = IcureApi = {}));
function getAuthenticationProvider(host, authenticationOptions, headers, fetchImpl) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a, _b;
        let authenticationProvider;
        if ('getIcureTokens' in authenticationOptions && 'switchGroup' in authenticationOptions && 'getAuthService' in authenticationOptions) {
            authenticationProvider = authenticationOptions;
        }
        else if ('icureTokens' in authenticationOptions && !!authenticationOptions.icureTokens) {
            authenticationProvider = new AuthenticationProvider_1.JwtAuthenticationProvider(new icc_api_1.IccAuthApi(host, headers, new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl), (_a = authenticationOptions === null || authenticationOptions === void 0 ? void 0 : authenticationOptions.credentials) === null || _a === void 0 ? void 0 : _a.username, (_b = authenticationOptions === null || authenticationOptions === void 0 ? void 0 : authenticationOptions.credentials) === null || _b === void 0 ? void 0 : _b.password, undefined, authenticationOptions.icureTokens);
        }
        else if ('username' in authenticationOptions &&
            'password' in authenticationOptions &&
            !!authenticationOptions.username &&
            !!authenticationOptions.password) {
            authenticationProvider = new AuthenticationProvider_1.EnsembleAuthenticationProvider(new icc_api_1.IccAuthApi(host, headers, new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl), authenticationOptions.username, authenticationOptions.password, 3600, undefined, undefined, authenticationOptions.thirdPartyTokens);
        }
        else if ('thirdPartyTokens' in authenticationOptions && !!authenticationOptions.thirdPartyTokens) {
            authenticationProvider = new AuthenticationProvider_1.JwtAuthenticationProvider(new icc_api_1.IccAuthApi(host, headers, new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl), undefined, undefined, new JwtBridgedAuthService_1.JwtBridgedAuthService(new icc_api_1.IccAuthApi(host, headers, new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl), undefined, undefined, authenticationOptions.thirdPartyTokens, undefined));
        }
        else if ('secretProvider' in authenticationOptions) {
            authenticationProvider = yield SmartAuthProvider_1.SmartAuthProvider.initialise(new icc_api_1.IccAuthApi(host, headers, new AuthenticationProvider_1.NoAuthenticationProvider(), fetchImpl), authenticationOptions.username, authenticationOptions.secretProvider, {
                initialSecret: authenticationOptions.initialSecret,
                initialAuthToken: authenticationOptions.initialAuthToken,
                initialRefreshToken: authenticationOptions.initialRefreshToken,
            });
        }
        else {
            throw new Error('Invalid authentication options provided');
        }
        return authenticationProvider;
    });
}
function initialiseAuthProviderWithGroupSelector(host, authenticationOptions, headers, fetchImpl, groupSelector) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a;
        let grouplessAuthenticationProvider = yield getAuthenticationProvider(host, authenticationOptions, headers, fetchImpl);
        const grouplessUserApi = new icc_api_1.IccUserApi(host, headers, grouplessAuthenticationProvider, fetchImpl);
        const matches = yield getMatchesOrEmpty(grouplessUserApi);
        const tokens = yield grouplessAuthenticationProvider.getIcureTokens();
        const currentGroupId = tokens ? (0, JwtUtils_1.getGroupOfJwt)(tokens.token) : undefined;
        const chosenGroupId = matches.length > 1 && !!groupSelector ? yield groupSelector(matches, currentGroupId) : (_a = matches[0]) === null || _a === void 0 ? void 0 : _a.groupId;
        /*TODO
         * On new very new users switching the authentication provider to a specific group may fail and block the user for too many requests. This is
         * probably linked to replication of the user in the fallback database.
         */
        /*
         * If the auth provider is initialized with credentials and jwt not switching the group will may cause issues:
         * 1. The default group for the user is group A
         * 2. The user logs in to group B -> the provider is switched
         * 3. The user refreshes the page -> a new instance of the api with initial iCure tokens is created
         * 4. The refresh token is expired / the user needs to do a high security operation -> a new login is done .If we did
         *    not switch the provider here the login would default to group A, potentially causing a lot of issues...
         */
        const groupSpecificAuthenticationProvider = !!chosenGroupId
            ? yield grouplessAuthenticationProvider.switchGroup(chosenGroupId, matches)
            : grouplessAuthenticationProvider;
        return {
            groupSpecificAuthenticationProvider,
            // No need for a groupless user api on a group-specific smart auth provider
            grouplessUserApi: groupSpecificAuthenticationProvider instanceof SmartAuthProvider_1.SmartAuthProvider ? undefined : grouplessUserApi,
            matches,
            chosenGroupId,
        };
    });
}
const REQUEST_AUTOFIX_ANONYMITY_HEADER = 'Icure-Request-Autofix-Anonymity';
function initialiseCryptoWithProvider(host, fetchImpl, groupSpecificAuthenticationProvider, params, cryptoStrategies, crypto, useLiteCompatibilityMode) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a;
        const initialDataOwnerStub = yield new icc_data_owner_x_api_1.IccDataOwnerXApi(host, params.headers, groupSpecificAuthenticationProvider, fetchImpl).getCurrentDataOwnerStub();
        const dataOwnerRequiresAnonymousDelegation = cryptoStrategies.dataOwnerRequiresAnonymousDelegation(initialDataOwnerStub);
        let updatedHeaders = params.headers;
        if (!Object.keys(updatedHeaders).includes(REQUEST_AUTOFIX_ANONYMITY_HEADER)) {
            if (initialDataOwnerStub.type == DataOwnerTypeEnum_1.DataOwnerTypeEnum.Patient || initialDataOwnerStub.type == DataOwnerTypeEnum_1.DataOwnerTypeEnum.Device) {
                if (!dataOwnerRequiresAnonymousDelegation) {
                    updatedHeaders = Object.assign(Object.assign({}, updatedHeaders), { [REQUEST_AUTOFIX_ANONYMITY_HEADER]: 'false' });
                }
            }
            else {
                if (dataOwnerRequiresAnonymousDelegation) {
                    updatedHeaders = Object.assign(Object.assign({}, updatedHeaders), { [REQUEST_AUTOFIX_ANONYMITY_HEADER]: 'true' });
                }
            }
        }
        const authApi = new icc_api_1.IccAuthApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl);
        const userApi = new icc_user_x_api_1.IccUserXApi(host, updatedHeaders, groupSpecificAuthenticationProvider, authApi, fetchImpl);
        const healthcarePartyApi = new icc_hcparty_x_api_1.IccHcpartyXApi(host, updatedHeaders, groupSpecificAuthenticationProvider, authApi, fetchImpl);
        const deviceApi = new icc_device_x_api_1.IccDeviceXApi(host, updatedHeaders, groupSpecificAuthenticationProvider, userApi, authApi, fetchImpl);
        const basePatientApi = new icc_api_1.IccPatientApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl);
        const dataOwnerApi = new icc_data_owner_x_api_1.IccDataOwnerXApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl);
        const exchangeDataApi = new IccExchangeDataApi_1.IccExchangeDataApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl);
        const baseRecoveryDataApi = new IccRecoveryDataApi_1.IccRecoveryDataApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl);
        // Crypto initialisation
        const icureStorage = new IcureStorageFacade_1.IcureStorageFacade(params.keyStorage, params.storage, params.entryKeysFactory);
        const cryptoPrimitives = 'AES' in crypto && 'RSA' in crypto && 'HMAC' in crypto ? crypto : new CryptoPrimitives_1.WebCryptoPrimitives(crypto);
        const baseExchangeKeysManager = new BaseExchangeKeysManager_1.BaseExchangeKeysManager(cryptoPrimitives, dataOwnerApi, healthcarePartyApi, basePatientApi, deviceApi);
        const baseExchangeDataManager = new BaseExchangeDataManager_1.BaseExchangeDataManager(exchangeDataApi, dataOwnerApi, cryptoPrimitives, dataOwnerRequiresAnonymousDelegation, useLiteCompatibilityMode);
        const keyRecovery = new KeyRecovery_1.KeyRecovery(cryptoPrimitives, dataOwnerApi, baseExchangeKeysManager, baseExchangeDataManager);
        const recoveryDataEncryption = new RecoveryDataEncryption_1.RecoveryDataEncryption(cryptoPrimitives, baseRecoveryDataApi);
        const keyPairRecoverer = new KeyPairRecoverer_1.KeyPairRecoverer(recoveryDataEncryption);
        const userEncryptionKeysManager = new UserEncryptionKeysManager_1.UserEncryptionKeysManager(cryptoPrimitives, dataOwnerApi, icureStorage, keyRecovery, cryptoStrategies, !params.disableParentKeysInitialisation, keyPairRecoverer, dataOwnerRequiresAnonymousDelegation);
        const newKey = yield userEncryptionKeysManager.initialiseKeys();
        yield new TransferKeysManager_1.TransferKeysManager(cryptoPrimitives, baseExchangeDataManager, dataOwnerApi, userEncryptionKeysManager, icureStorage).updateTransferKeys(yield dataOwnerApi.getCurrentDataOwnerStub());
        // TODO customise cache size?
        const exchangeKeysManager = new ExchangeKeysManager_1.ExchangeKeysManager(userEncryptionKeysManager, baseExchangeKeysManager, dataOwnerApi);
        const accessControlSecretUtils = new AccessControlSecretUtils_1.AccessControlSecretUtils(cryptoPrimitives);
        const exchangeDataManager = yield (0, ExchangeDataManager_1.initialiseExchangeDataManagerForCurrentDataOwner)(baseExchangeDataManager, userEncryptionKeysManager, accessControlSecretUtils, cryptoStrategies, dataOwnerApi, cryptoPrimitives, !params.disableParentKeysInitialisation);
        if (params.injectExchangeData != null && params.injectExchangeData.details.length > 0) {
            yield exchangeDataManager.injectDecryptedExchangeData(params.injectExchangeData.details, params.injectExchangeData.reEncryptWithOwnKeys);
        }
        const exchangeDataMapManager = new ExchangeDataMapManager_1.ExchangeDataMapManager(new IccExchangeDataMapApi_1.IccExchangeDataMapApi(host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl));
        const secureDelegationsEncryption = new SecureDelegationsEncryption_1.SecureDelegationsEncryption(userEncryptionKeysManager, cryptoPrimitives);
        const secureDelegationsSecurityMetadataEncryption = new SecurityMetadataDecryptor_1.SecurityMetadataDecryptor(exchangeKeysManager, cryptoPrimitives, exchangeDataManager, exchangeDataMapManager, secureDelegationsEncryption, dataOwnerApi);
        const xApiUtils = new ExtendedApisUtilsImpl_1.ExtendedApisUtilsImpl(cryptoPrimitives, dataOwnerApi, secureDelegationsSecurityMetadataEncryption, new SecureDelegationsManager_1.SecureDelegationsManager(exchangeDataManager, exchangeDataMapManager, secureDelegationsEncryption, accessControlSecretUtils, userEncryptionKeysManager, cryptoPrimitives, dataOwnerApi, cryptoStrategies, dataOwnerRequiresAnonymousDelegation), userApi, !params.disableParentKeysInitialisation);
        const shamirManager = new ShamirKeysManager_1.ShamirKeysManager(cryptoPrimitives, dataOwnerApi, userEncryptionKeysManager, exchangeDataManager);
        if (userEncryptionKeysManager.getSelfVerifiedKeys().length > 0) {
            yield (0, utils_1.ensureDelegationForSelf)(dataOwnerApi, xApiUtils, basePatientApi, cryptoPrimitives);
        }
        const accessControlKeysHeadersProvider = new AccessControlKeysHeadersProvider_1.AccessControlKeysHeadersProvider(exchangeDataManager);
        const delegationsDeAnonymisation = new DelegationsDeAnonymization_1.DelegationsDeAnonymization(dataOwnerApi, secureDelegationsSecurityMetadataEncryption, xApiUtils, cryptoPrimitives, accessControlSecretUtils, host, updatedHeaders, groupSpecificAuthenticationProvider, fetchImpl, accessControlKeysHeadersProvider);
        const cryptoApi = new icc_crypto_x_api_1.IccCryptoXApi(exchangeKeysManager, cryptoPrimitives, userEncryptionKeysManager, dataOwnerApi, xApiUtils, shamirManager, params.storage, params.keyStorage, exchangeDataManager, accessControlKeysHeadersProvider, delegationsDeAnonymisation);
        const maintenanceTaskApi = new icc_maintenance_task_x_api_1.IccMaintenanceTaskXApi(host, updatedHeaders, cryptoApi, healthcarePartyApi, dataOwnerApi, userApi, authApi, !dataOwnerRequiresAnonymousDelegation, (_a = params.encryptedFieldsConfig.maintenanceTask) !== null && _a !== void 0 ? _a : EncryptedFieldsConfig.Defaults.maintenanceTask, groupSpecificAuthenticationProvider, fetchImpl);
        const icureMaintenanceTaskApi = new icc_icure_maintenance_x_api_1.IccIcureMaintenanceXApi(cryptoApi, maintenanceTaskApi, dataOwnerApi, exchangeDataApi);
        if (newKey && params.createMaintenanceTasksOnNewKey) {
            yield icureMaintenanceTaskApi.createMaintenanceTasksForNewKeypair(yield userApi.getCurrentUser(), newKey.newKeyPair);
        }
        return {
            cryptoApi,
            userApi,
            healthcarePartyApi,
            deviceApi,
            maintenanceTaskApi,
            dataOwnerApi,
            icureMaintenanceTaskApi,
            headers: updatedHeaders,
            dataOwnerRequiresAnonymousDelegation,
            recoveryApi: new icc_recovery_x_api_1.IccRecoveryXApi(baseRecoveryDataApi, recoveryDataEncryption, userEncryptionKeysManager, dataOwnerApi, cryptoPrimitives, exchangeDataManager),
        };
    });
}
class IcureApiImpl {
    constructor(cryptoInitInfos, host, groupSpecificAuthenticationProvider, fetch, grouplessUserApi, latestMatches, currentGroupInfo, params, cryptoStrategies, useLiteCompatibilityMode) {
        this.cryptoInitInfos = cryptoInitInfos;
        this.host = host;
        this.groupSpecificAuthenticationProvider = groupSpecificAuthenticationProvider;
        this.fetch = fetch;
        this.grouplessUserApi = grouplessUserApi;
        this.currentGroupInfo = currentGroupInfo;
        this.params = params;
        this.cryptoStrategies = cryptoStrategies;
        this.useLiteCompatibilityMode = useLiteCompatibilityMode;
        this.latestGroupsRequest = Promise.resolve(latestMatches);
    }
    get pricingApi() {
        var _a;
        return ((_a = this._pricingApi) !== null && _a !== void 0 ? _a : (this._pricingApi = new icc_api_1.IccTarificationApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get recoveryApi() {
        return this.cryptoInitInfos.recoveryApi;
    }
    get authApi() {
        var _a;
        return ((_a = this._authApi) !== null && _a !== void 0 ? _a : (this._authApi = new icc_api_1.IccAuthApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get codeApi() {
        var _a;
        return ((_a = this._codeApi) !== null && _a !== void 0 ? _a : (this._codeApi = new icc_code_x_api_1.IccCodeXApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get calendarItemTypeApi() {
        var _a;
        return ((_a = this._calendarItemTypeApi) !== null && _a !== void 0 ? _a : (this._calendarItemTypeApi = new icc_api_1.IccCalendarItemTypeApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get medicalLocationApi() {
        var _a;
        return ((_a = this._medicalLocationApi) !== null && _a !== void 0 ? _a : (this._medicalLocationApi = new icc_api_1.IccMedicallocationApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get roleApi() {
        var _a;
        return (_a = this._roleApi) !== null && _a !== void 0 ? _a : (this._roleApi = new IccRoleApi_1.IccRoleApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    get entityReferenceApi() {
        var _a;
        return ((_a = this._entityReferenceApi) !== null && _a !== void 0 ? _a : (this._entityReferenceApi = new icc_api_1.IccEntityrefApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get permissionApi() {
        var _a;
        return ((_a = this._permissionApi) !== null && _a !== void 0 ? _a : (this._permissionApi = new icc_api_1.IccPermissionApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get accessLogApi() {
        var _a, _b;
        return ((_a = this._accessLogApi) !== null && _a !== void 0 ? _a : (this._accessLogApi = new icc_accesslog_x_api_1.IccAccesslogXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, (_b = this.params.encryptedFieldsConfig.accessLog) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.accessLog, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get agendaApi() {
        var _a;
        return ((_a = this._agendaApi) !== null && _a !== void 0 ? _a : (this._agendaApi = new icc_api_1.IccAgendaApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get contactApi() {
        var _a, _b, _c;
        return ((_a = this._contactApi) !== null && _a !== void 0 ? _a : (this._contactApi = new icc_contact_x_api_1.IccContactXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, this.userApi, this.authApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, this.fetch, (_b = this.params.encryptedFieldsConfig.contact) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.contact, (_c = this.params.encryptedFieldsConfig.service) !== null && _c !== void 0 ? _c : EncryptedFieldsConfig.Defaults.service)));
    }
    get formApi() {
        var _a;
        return ((_a = this._formApi) !== null && _a !== void 0 ? _a : (this._formApi = new icc_form_x_api_1.IccFormXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get groupApi() {
        var _a;
        return ((_a = this._groupApi) !== null && _a !== void 0 ? _a : (this._groupApi = new icc_api_1.IccGroupApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get invoiceApi() {
        var _a;
        return ((_a = this._invoiceApi) !== null && _a !== void 0 ? _a : (this._invoiceApi = new icc_invoice_x_api_1.IccInvoiceXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.entityReferenceApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get insuranceApi() {
        var _a;
        return ((_a = this._insuranceApi) !== null && _a !== void 0 ? _a : (this._insuranceApi = new icc_api_1.IccInsuranceApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get documentApi() {
        var _a, _b;
        return ((_a = this._documentApi) !== null && _a !== void 0 ? _a : (this._documentApi = new icc_document_x_api_1.IccDocumentXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.authApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, (_b = this.params.encryptedFieldsConfig.document) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.document, this.fetch)));
    }
    get healthcareElementApi() {
        var _a, _b;
        return ((_a = this._healthcareElementApi) !== null && _a !== void 0 ? _a : (this._healthcareElementApi = new icc_helement_x_api_1.IccHelementXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, this.userApi, this.authApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, (_b = this.params.encryptedFieldsConfig.healthElement) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.healthElement, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get classificationApi() {
        var _a;
        return ((_a = this._classificationApi) !== null && _a !== void 0 ? _a : (this._classificationApi = new icc_classification_x_api_1.IccClassificationXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get calendarItemApi() {
        var _a, _b;
        return ((_a = this._calendarItemApi) !== null && _a !== void 0 ? _a : (this._calendarItemApi = new icc_calendar_item_x_api_1.IccCalendarItemXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, (_b = this.params.encryptedFieldsConfig.calendarItem) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.calendarItem, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get receiptApi() {
        var _a;
        return ((_a = this._receiptApi) !== null && _a !== void 0 ? _a : (this._receiptApi = new icc_receipt_x_api_1.IccReceiptXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get timetableApi() {
        var _a;
        return ((_a = this._timetableApi) !== null && _a !== void 0 ? _a : (this._timetableApi = new icc_api_1.IccTimeTableApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get patientApi() {
        var _a, _b;
        return ((_a = this._patientApi) !== null && _a !== void 0 ? _a : (this._patientApi = new icc_patient_x_api_1.IccPatientXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.contactApi, this.formApi, this.healthcareElementApi, this.invoiceApi, this.documentApi, this.healthcarePartyApi, this.classificationApi, this.dataOwnerApi, this.calendarItemApi, this.userApi, this.authApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, (_b = this.params.encryptedFieldsConfig.patient) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.patient, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get messageApi() {
        var _a, _b;
        return ((_a = this._messageApi) !== null && _a !== void 0 ? _a : (this._messageApi = new icc_message_x_api_1.IccMessageXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, this.authApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, (_b = this.params.encryptedFieldsConfig.message) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.message, this.fetch)));
    }
    get topicApi() {
        var _a, _b;
        return ((_a = this._topicApi) !== null && _a !== void 0 ? _a : (this._topicApi = new icc_topic_x_api_1.IccTopicXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.dataOwnerApi, this.authApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, this.groupSpecificAuthenticationProvider, (_b = this.params.encryptedFieldsConfig.topic) !== null && _b !== void 0 ? _b : EncryptedFieldsConfig.Defaults.topic, this.fetch)));
    }
    get anonymousAccessApi() {
        var _a;
        return ((_a = this._anonymousAccessApi) !== null && _a !== void 0 ? _a : (this._anonymousAccessApi = new icc_api_1.IccAnonymousAccessApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get applicationSettingsApi() {
        var _a;
        return ((_a = this._applicationSettingsApi) !== null && _a !== void 0 ? _a : (this._applicationSettingsApi = new icc_application_settings_x_api_1.IccApplicationSettingsXApi(this.host, this.cryptoInitInfos.headers, this.cryptoInitInfos.cryptoApi, this.cryptoInitInfos.dataOwnerApi, !this.cryptoInitInfos.dataOwnerRequiresAnonymousDelegation, ['encryptedSettings'], this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get bekmehrApi() {
        var _a;
        return ((_a = this._bekmehrApi) !== null && _a !== void 0 ? _a : (this._bekmehrApi = new icc_bekmehr_x_api_1.IccBekmehrXApi(this.host, this.cryptoInitInfos.headers, this.contactApi, this.healthcareElementApi, this.documentApi, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get beefactApi() {
        var _a;
        return ((_a = this._beefactApi) !== null && _a !== void 0 ? _a : (this._beefactApi = new icc_api_1.IccBeefactApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get beresultexportApi() {
        var _a;
        return ((_a = this._beresultexportApi) !== null && _a !== void 0 ? _a : (this._beresultexportApi = new icc_api_1.IccBeresultexportApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get beresultimportApi() {
        var _a;
        return ((_a = this._beresultimportApi) !== null && _a !== void 0 ? _a : (this._beresultimportApi = new icc_api_1.IccBeresultimportApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get besamv2Api() {
        var _a;
        return ((_a = this._besamv2Api) !== null && _a !== void 0 ? _a : (this._besamv2Api = new icc_api_1.IccBesamv2Api(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get classificationTemplateApi() {
        var _a;
        return ((_a = this._classificationTemplateApi) !== null && _a !== void 0 ? _a : (this._classificationTemplateApi = new icc_api_1.IccClassificationTemplateApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get doctemplateApi() {
        var _a;
        return ((_a = this._doctemplateApi) !== null && _a !== void 0 ? _a : (this._doctemplateApi = new icc_doctemplate_x_api_1.IccDoctemplateXApi(this.host, this.cryptoInitInfos.headers, this.cryptoApi, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get entitytemplateApi() {
        var _a;
        return ((_a = this._entitytemplateApi) !== null && _a !== void 0 ? _a : (this._entitytemplateApi = new icc_api_1.IccEntitytemplateApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get frontendmigrationApi() {
        var _a;
        return ((_a = this._frontendmigrationApi) !== null && _a !== void 0 ? _a : (this._frontendmigrationApi = new icc_api_1.IccFrontendmigrationApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get icureApi() {
        var _a;
        return ((_a = this._icureApi) !== null && _a !== void 0 ? _a : (this._icureApi = new icc_api_1.IccIcureApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get keywordApi() {
        var _a;
        return ((_a = this._keywordApi) !== null && _a !== void 0 ? _a : (this._keywordApi = new icc_api_1.IccKeywordApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get medexApi() {
        var _a;
        return ((_a = this._medexApi) !== null && _a !== void 0 ? _a : (this._medexApi = new icc_api_1.IccMedexApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get placeApi() {
        var _a;
        return ((_a = this._placeApi) !== null && _a !== void 0 ? _a : (this._placeApi = new icc_api_1.IccPlaceApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get pubsubApi() {
        var _a;
        return ((_a = this._pubsubApi) !== null && _a !== void 0 ? _a : (this._pubsubApi = new icc_api_1.IccPubsubApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get replicationApi() {
        var _a;
        return ((_a = this._replicationApi) !== null && _a !== void 0 ? _a : (this._replicationApi = new icc_api_1.IccReplicationApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get tarificationApi() {
        var _a;
        return ((_a = this._tarificationApi) !== null && _a !== void 0 ? _a : (this._tarificationApi = new icc_api_1.IccTarificationApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get tmpApi() {
        var _a;
        return ((_a = this._tmpApi) !== null && _a !== void 0 ? _a : (this._tmpApi = new icc_api_1.IccTmpApi(this.host, this.cryptoInitInfos.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get cryptoApi() {
        return this.cryptoInitInfos.cryptoApi;
    }
    get dataOwnerApi() {
        return this.cryptoInitInfos.dataOwnerApi;
    }
    get deviceApi() {
        return this.cryptoInitInfos.deviceApi;
    }
    get healthcarePartyApi() {
        return this.cryptoInitInfos.healthcarePartyApi;
    }
    get icureMaintenanceTaskApi() {
        return this.cryptoInitInfos.icureMaintenanceTaskApi;
    }
    get maintenanceTaskApi() {
        return this.cryptoInitInfos.maintenanceTaskApi;
    }
    get userApi() {
        return this.cryptoInitInfos.userApi;
    }
    getGroupsInfo() {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            this.latestGroupsRequest = ((_a = this.grouplessUserApi) !== null && _a !== void 0 ? _a : this.userApi).getMatchingUsers();
            return { currentGroup: this.currentGroupInfo, availableGroups: yield this.latestGroupsRequest };
        });
    }
    switchGroup(newGroupId) {
        return __awaiter(this, void 0, void 0, function* () {
            const availableGroups = yield this.latestGroupsRequest;
            const switchedProvider = yield this.groupSpecificAuthenticationProvider.switchGroup(newGroupId, availableGroups);
            const cryptoInitInfos = yield initialiseCryptoWithProvider(this.host, this.fetch, switchedProvider, this.params, this.cryptoStrategies, this.cryptoApi.primitives, this.useLiteCompatibilityMode);
            return new IcureApiImpl(cryptoInitInfos, this.host, switchedProvider, this.fetch, this.grouplessUserApi, availableGroups, availableGroups.find((x) => x.groupId === newGroupId), this.params, this.cryptoStrategies, this.useLiteCompatibilityMode);
        });
    }
}
class IcureBasicApiImpl {
    get accessLogApi() {
        var _a;
        return ((_a = this._accessLogApi) !== null && _a !== void 0 ? _a : (this._accessLogApi = new icc_api_1.IccAccesslogApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get pricingApi() {
        var _a;
        return ((_a = this._pricingApi) !== null && _a !== void 0 ? _a : (this._pricingApi = new icc_api_1.IccTarificationApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get icureApi() {
        var _a;
        return ((_a = this._icureApi) !== null && _a !== void 0 ? _a : (this._icureApi = new icc_api_1.IccIcureApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get agendaApi() {
        var _a;
        return ((_a = this._agendaApi) !== null && _a !== void 0 ? _a : (this._agendaApi = new icc_api_1.IccAgendaApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get authApi() {
        var _a;
        return (_a = this._authApi) !== null && _a !== void 0 ? _a : (this._authApi = new icc_api_1.IccAuthApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    get codeApi() {
        var _a;
        return (_a = this._codeApi) !== null && _a !== void 0 ? _a : (this._codeApi = new icc_code_x_api_1.IccCodeXApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    get deviceApi() {
        var _a;
        return ((_a = this._deviceApi) !== null && _a !== void 0 ? _a : (this._deviceApi = new icc_device_x_api_1.IccDeviceXApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.userApi, this.authApi, this.fetch)));
    }
    get entityReferenceApi() {
        var _a;
        return ((_a = this._entityReferenceApi) !== null && _a !== void 0 ? _a : (this._entityReferenceApi = new icc_api_1.IccEntityrefApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get formApi() {
        var _a;
        return (_a = this._formApi) !== null && _a !== void 0 ? _a : (this._formApi = new icc_api_1.IccFormApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    get groupApi() {
        var _a;
        return (_a = this._groupApi) !== null && _a !== void 0 ? _a : (this._groupApi = new icc_api_1.IccGroupApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    get healthcarePartyApi() {
        var _a;
        return ((_a = this._healthcarePartyApi) !== null && _a !== void 0 ? _a : (this._healthcarePartyApi = new icc_hcparty_x_api_1.IccHcpartyXApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.authApi, this.fetch)));
    }
    get insuranceApi() {
        var _a;
        return ((_a = this._insuranceApi) !== null && _a !== void 0 ? _a : (this._insuranceApi = new icc_api_1.IccInsuranceApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get permissionApi() {
        var _a;
        return ((_a = this._permissionApi) !== null && _a !== void 0 ? _a : (this._permissionApi = new icc_api_1.IccPermissionApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get userApi() {
        var _a;
        return ((_a = this._userApi) !== null && _a !== void 0 ? _a : (this._userApi = new icc_user_x_api_1.IccUserXApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.authApi, this.fetch)));
    }
    getGroupsInfo() {
        return __awaiter(this, void 0, void 0, function* () {
            var _a;
            if (!this.currentGroupInfo)
                return { currentGroup: undefined, availableGroups: [] };
            this.latestGroupsRequest = ((_a = this.grouplessUserApi) !== null && _a !== void 0 ? _a : this.userApi).getMatchingUsers();
            return { currentGroup: this.currentGroupInfo, availableGroups: yield this.latestGroupsRequest };
        });
    }
    get patientApi() {
        var _a;
        return ((_a = this._patientApi) !== null && _a !== void 0 ? _a : (this._patientApi = new icc_api_1.IccPatientApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch)));
    }
    get roleApi() {
        var _a;
        return (_a = this._roleApi) !== null && _a !== void 0 ? _a : (this._roleApi = new IccRoleApi_1.IccRoleApi(this.host, this.params.headers, this.groupSpecificAuthenticationProvider, this.fetch));
    }
    switchGroup(newGroupId) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.currentGroupInfo)
                throw new Error('Cannot switch group: the backend environment does not support multiple groups.');
            const availableGroups = yield this.latestGroupsRequest;
            const switchedProvider = yield this.groupSpecificAuthenticationProvider.switchGroup(newGroupId, availableGroups);
            return new IcureBasicApiImpl(this.host, switchedProvider, this.fetch, this.grouplessUserApi, availableGroups, availableGroups.find((x) => x.groupId === newGroupId), this.params);
        });
    }
    constructor(host, groupSpecificAuthenticationProvider, fetch, grouplessUserApi, latestMatches, currentGroupInfo, params) {
        this.host = host;
        this.groupSpecificAuthenticationProvider = groupSpecificAuthenticationProvider;
        this.fetch = fetch;
        this.grouplessUserApi = grouplessUserApi;
        this.currentGroupInfo = currentGroupInfo;
        this.params = params;
        this.latestGroupsRequest = Promise.resolve(latestMatches);
    }
}
var IcureBasicApiOptions;
(function (IcureBasicApiOptions) {
    let Defaults;
    (function (Defaults) {
        Defaults.headers = {};
    })(Defaults = IcureBasicApiOptions.Defaults || (IcureBasicApiOptions.Defaults = {}));
    class WithDefaults {
        constructor(custom) {
            var _a, _b;
            this.headers = (_a = custom.headers) !== null && _a !== void 0 ? _a : Defaults.headers;
            this.groupSelector = (_b = custom.groupSelector) !== null && _b !== void 0 ? _b : ((groups) => Promise.resolve(groups[0].groupId));
        }
    }
    IcureBasicApiOptions.WithDefaults = WithDefaults;
})(IcureBasicApiOptions || (IcureBasicApiOptions = {}));
var IcureBasicApi;
(function (IcureBasicApi) {
    /**
     * Initialises a new instance of the iCure API.
     */
    function initialise(host_1, authenticationOptions_1) {
        return __awaiter(this, arguments, void 0, function* (host, authenticationOptions, fetchImpl = typeof window !== 'undefined'
            ? window.fetch
            : typeof self !== 'undefined'
                ? self.fetch
                : fetch, options = {}) {
            var _a;
            const params = new IcureBasicApiOptions.WithDefaults(options);
            const authProviderInfo = yield initialiseAuthProviderWithGroupSelector(host, authenticationOptions, (_a = params.headers) !== null && _a !== void 0 ? _a : {}, fetchImpl, params.groupSelector);
            return new IcureBasicApiImpl(host, authProviderInfo.groupSpecificAuthenticationProvider, fetch, authProviderInfo.grouplessUserApi, authProviderInfo.matches, authProviderInfo.matches.find((match) => match.groupId === authProviderInfo.chosenGroupId), params);
        });
    }
    IcureBasicApi.initialise = initialise;
})(IcureBasicApi || (exports.IcureBasicApi = IcureBasicApi = {}));
function getMatchesOrEmpty(userApi) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            return yield userApi.getMatchingUsers();
        }
        catch (err) {
            if (err instanceof Error && 'statusCode' in err && err.statusCode === 404)
                return Promise.resolve([]);
            else
                return Promise.reject(err);
        }
    });
}
//# sourceMappingURL=index.js.map