{"version":3,"sources":["../src/utils/local-storage.ts","../src/utils/utils.ts","../src/utils/logger-helper.service.ts","../src/utils/logger.service.ts","../src/token-storage/token-storage.service.ts","../src/token-storage/aws-storage.service.ts","../src/token-storage/azure-storage.service.ts","../src/core/aws-web.core.ts","../src/http/http-request.builder.ts","../src/http/aws-http-request.builder.ts","../src/vendor/sig-v4.service.ts","../src/http/azure-http-request.builder.ts","../src/core/azure-web.core.ts","../src/core/web-core.factory.ts"],"names":["dataMemory","MemoryStorage","key","value","LocalStorageService","exception","hmacSHA256","encBase64","createAsyncDelay","duration","resolve","isEmptyObject","obj","withRetries","attempt","nthTry","delay","args","__async","retryCount","error","hmac","message","hash","calcSignature","payload","current","userAgent","authId","accountId","identityId","identityToken","data","signature","convertCamelCaseFromSnake","part","i","calcTestSignature","format","NODE_COLORS","BROWSER_COLORS","LoggerHelperService","params","extraParams","type","name","param","LogType","LoggerService","namespace","options","__spreadValues","formattedMessage","formattedText","text","shouldFormat","typeBlank","showTimestamp","showLogType","timestampFormat","typeFormat","textFormat","namespaceFormat","timestampLog","typeLog","namespaceLog","textLog","whiteColor","typeColor","blackColor","date","zeroOrNull","dt","year","month","day","hours","minutes","seconds","dateText","hoursText","jwtDecode","USE_X_LEMON_IDENTITY_KEY","USE_X_LEMON_LANGUAGE_KEY","REGION_KEY","TokenStorageService","config","prefix","serverExpiration","jwtToken","_a","jwtExpiration","jwtIssuedAt","jwt","e","AWSStorageService","promise","item","result","expiredTime","accessKeyId","secretKey","now","bufferTime","AccessKeyId","SecretKey","SessionToken","tmp","token","credential","identityPoolId","Expiration","issuedTime","kms","kmsArn","AzureStorageService","accessToken","hostKey","clientId","axios","HttpRequestBuilder","axiosInstance","headers","method","AWS","sha256","Hex","SHA256","encHex","HmacSHA256","sigV4Client","AWS_SHA_256","AWS4_REQUEST","AWS4","X_AMZ_DATE","X_AMZ_SECURITY_TOKEN","HOST","AUTHORIZATION","hexEncode","secret","buildCanonicalRequest","path","queryParams","buildCanonicalUri","buildCanonicalQueryString","buildCanonicalHeaders","buildCanonicalSignedHeaders","hashCanonicalRequest","request","uri","UriEncode","input","encodeSlash","ch","sortedQueryParams","property","canonicalQueryString","urlencode","canonicalHeaders","sortedKeys","buildStringToSign","datetime","credentialScope","hashedCanonicalRequest","buildCredentialScope","region","service","calculateSigningKey","calculateSignature","stringToSign","buildAuthorizationHeader","accessKey","awsSigV4Client","invokeUrl","endpoint","pathComponent","verb","body","canonicalRequest","signingKey","url","queryString","AWSHttpRequestBuilder","tokenStorage","signedClient","sigendHeader","signedRequest","header","headerWithIdentity","useXLemonIdentity","__spreadProps","languageKey","language","hostname","AzureHttpRequestBuilder","code","originParams","AWSWebCore","_0","_1","builder","credentials","domain","cached","response","tokenData","refreshToken","changeSiteBody","target","tokenSignature","originToken","use","reject","AzureWebCore","webCoreMap","WebCoreFactory","cloud","ServiceConstructor"],"mappings":"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","sourcesContent":["let dataMemory: any = {};\n\nclass MemoryStorage {\n    constructor() {}\n\n    public setItem(key: string, value: string) {\n        dataMemory[key] = value;\n        return dataMemory[key];\n    }\n\n    public getItem(key: string) {\n        return Object.prototype.hasOwnProperty.call(dataMemory, key) ? dataMemory[key] : undefined;\n    }\n\n    public removeItem(key: string) {\n        return delete dataMemory[key];\n    }\n\n    public clear() {\n        dataMemory = {};\n        return dataMemory;\n    }\n}\n\nexport class LocalStorageService {\n    private storage: any;\n\n    constructor() {\n        try {\n            this.storage = window.localStorage;\n            this.storage.setItem(`.test-value`, 1);\n            this.storage.removeItem(`.test-value`);\n        } catch (exception) {\n            this.storage = new MemoryStorage();\n        }\n    }\n\n    public setItem(key: string, value: string) {\n        this.storage.setItem(key, value);\n    }\n\n    public getItem(key: string) {\n        return this.storage.getItem(key);\n    }\n\n    public removeItem(key: string) {\n        this.storage.removeItem(key);\n    }\n}\n","import { SignaturePayload } from '../types';\nimport hmacSHA256 from 'crypto-js/hmac-sha256.js';\nimport encBase64 from 'crypto-js/enc-base64.js';\n\n/**\n * @description create delay using async/await\n * @param {number} duration (millisecond)\n * @returns {Promise}\n * @example\n * await createAsyncDelay(2000) // wait 2 seconds\n * */\nexport const createAsyncDelay = (duration: number) => {\n    return new Promise<void>(resolve => setTimeout(() => resolve(), duration));\n};\n\nexport const isEmptyObject = (obj: any) => {\n    if (typeof obj !== 'object') {\n        return !obj;\n    }\n    return Object.keys(obj).length === 0;\n};\n\nexport const withRetries =\n    (attempt: any, nthTry: number, delay: number) =>\n    async (...args: any[]) => {\n        let retryCount = 0;\n        do {\n            try {\n                return await attempt(...args);\n            } catch (error) {\n                const isLastAttempt = retryCount === nthTry;\n                if (isLastAttempt) {\n                    return Promise.reject(error);\n                }\n            }\n            await createAsyncDelay(delay);\n        } while (retryCount++ < nthTry);\n    };\n\nexport const hmac = (message: string, key: string) => {\n    //! INFO: lemon-account-api\n    //! algorithm: sha256, encoding: base64\n    const hash = hmacSHA256(message, key);\n    return encBase64.stringify(hash);\n};\n\nexport const calcSignature = (\n    payload: SignaturePayload,\n    current: string = new Date().toISOString(),\n    userAgent: string = navigator.userAgent\n) => {\n    const authId = payload.authId || '';\n    const accountId = payload.accountId || '';\n    const identityId = payload.identityId || '';\n    const identityToken = '';\n\n    //! build payload to sign......\n    const data = [current, accountId, identityId, identityToken, userAgent].join('&');\n    //! make signature with auth-id\n    const signature = hmac(hmac(hmac(data, authId), accountId), identityId);\n    //! returns signature..........\n    // return new Buffer(signature).toString('base64');\n    return signature;\n};\n\nexport const convertCamelCaseFromSnake = (key: string) => {\n    return key\n        .toLowerCase()\n        .split('_')\n        .map((part, i) => (i > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part))\n        .join('');\n};\n\n// NOTE: for native login test\nexport const calcTestSignature = (\n    payload: SignaturePayload,\n    current: string = new Date().toISOString(),\n    userAgent: string = navigator.userAgent\n) => {\n    const authId = payload.authId || '';\n    const accountId = payload.accountId || '';\n    const identityId = payload.identityId || '';\n    const identityToken = payload.identityToken || '';\n\n    //! build payload to sign......\n    const data = [current, accountId, identityId, identityToken, userAgent].join('&');\n    //! make signature with auth-id\n    const signature = hmac(hmac(hmac(data, authId), accountId), identityId);\n    //! returns signature..........\n    // return new Buffer(signature).toString('base64');\n    return signature;\n};\n","import { format } from 'util';\nimport { LogType } from './logger.service';\n\nexport const NODE_COLORS = {\n    Black: 0,\n    Red: 1,\n    Green: 2,\n    Yellow: 3,\n    Blue: 4,\n    Magenta: 5,\n    Cyan: 6,\n    Grey: 7,\n    White: 9,\n};\n\nexport const BROWSER_COLORS = {\n    Black: 'Black',\n    Red: 'IndianRed',\n    Green: 'LimeGreen',\n    Yellow: 'Orange',\n    Blue: 'RoyalBlue',\n    Magenta: 'Orchid',\n    Cyan: 'SkyBlue',\n    Grey: 'DimGrey',\n    White: 'White',\n};\n\nexport class LoggerHelperService {\n    private colorSet: any;\n    private logColors: any;\n\n    constructor() {\n        this.colorSet = this.getColorSet();\n        this.logColors = {\n            DEBUG: this.colorSet.Blue,\n            INFO: this.colorSet.Green,\n            WARN: this.colorSet.Yellow,\n            ERROR: this.colorSet.Red,\n            DEFAULT: this.colorSet.Black,\n        };\n    }\n\n    public formatMessage(message: string, params: any[]) {\n        const extraParams = this.checkErrorInstance(params);\n        return format(message, ...extraParams);\n    }\n\n    public getColorAsType(type: LogType): string {\n        return this.logColors[type];\n    }\n\n    public getColorByName(name: string = 'Grey') {\n        return this.colorSet[name];\n    }\n\n    public isBrowser() {\n        return typeof window !== 'undefined' && typeof window.document !== 'undefined';\n    }\n\n    public isNode() {\n        return typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\n    }\n\n    private checkErrorInstance(params: any[]) {\n        if (this.isNode()) {\n            return params;\n        }\n        // isBrowser\n        // browser에서 error message만 출력하는 이슈 해결 위해\n        return params.map(param => {\n            if (param instanceof Error) {\n                return { error: param.message, stack: param.stack };\n            } else {\n                return param;\n            }\n        });\n    }\n\n    private getColorSet() {\n        return this.isBrowser() ? BROWSER_COLORS : NODE_COLORS;\n    }\n}\n","// refer: https://github.com/lemoncloud-io/lemon-logger-lib\n// TODO: use @lemoncloud/lemon-logger-lib\nimport { LoggerHelperService } from './logger-helper.service';\nimport { LoggerOption } from '../types';\n\nexport enum LogType {\n    DEBUG = 'DEBUG',\n    WARN = 'WARN',\n    INFO = 'INFO',\n    ERROR = 'ERROR',\n}\n\nexport interface LogInterface {\n    debug(message: string, ...extraParams: any[]): void;\n    warn(message: string, ...extraParams: any[]): void;\n    info(message: string, ...extraParams: any[]): void;\n    error(message: string, ...extraParams: any[]): void;\n}\n\nexport interface FormatInterface {\n    timestampFormat: string;\n    typeFormat: string;\n    textFormat: string;\n    namespaceFormat: string;\n}\n\nexport class LoggerService implements LogInterface {\n    private utils: LoggerHelperService;\n\n    private isNode: boolean;\n    private isBrowser: boolean;\n\n    private namespace: string;\n    private options: LoggerOption = {\n        showTimestamp: true,\n        showLogType: true,\n    };\n\n    constructor(namespace: string = 'LEMON', options: LoggerOption = {}) {\n        this.utils = new LoggerHelperService();\n        this.namespace = namespace;\n        this.options = { ...this.options, ...options };\n\n        this.isNode = this.utils.isNode();\n        this.isBrowser = this.utils.isBrowser();\n    }\n\n    log(message: string, ...extraParams: any[]) {\n        const formattedMessage = this.utils.formatMessage(message, extraParams);\n        this.writeLog(LogType.DEBUG, formattedMessage);\n        return;\n    }\n\n    debug(message: string, ...extraParams: any[]) {\n        const formattedMessage = this.utils.formatMessage(message, extraParams);\n        this.writeLog(LogType.DEBUG, formattedMessage);\n    }\n\n    warn(message: string, ...extraParams: any[]) {\n        const formattedMessage = this.utils.formatMessage(message, extraParams);\n        this.writeLog(LogType.WARN, formattedMessage);\n    }\n\n    info(message: string, ...extraParams: any[]) {\n        const formattedMessage = this.utils.formatMessage(message, extraParams);\n        this.writeLog(LogType.INFO, formattedMessage);\n    }\n\n    error(message: string, ...extraParams: any[]) {\n        const formattedMessage = this.utils.formatMessage(message, extraParams);\n        this.writeLog(LogType.ERROR, formattedMessage);\n    }\n\n    private writeLog(type: LogType, message: string) {\n        const format: FormatInterface = this.getFormat(type);\n        const formattedText = this.createLogMessage(type, message, format);\n        if (this.isNode) {\n            console.log(formattedText);\n            return;\n        }\n\n        // isBrowser\n        this.logOnBrowser(type, formattedText, format);\n        return;\n    }\n\n    private createLogMessage(type: LogType, text: string, format: FormatInterface, shouldFormat: boolean = true) {\n        const typeBlank = type === LogType.INFO || type === LogType.WARN ? ' ' : '';\n        const { showTimestamp, showLogType } = this.options;\n        let { timestampFormat, typeFormat, textFormat, namespaceFormat } = format;\n\n        if (this.isBrowser && shouldFormat) {\n            timestampFormat = '%c';\n            typeFormat = '%c';\n            namespaceFormat = '%c';\n            textFormat = ': %c';\n        }\n\n        const timestampLog = showTimestamp ? `${timestampFormat}${this.createTimestamp(new Date())} ` : `${timestampFormat}`; // format 정해줘야 browser에서 포맷 안깨짐\n        const typeLog = showLogType ? `${typeFormat}[${type}]${typeBlank} ` : `${typeFormat}`;\n        const namespaceLog = `${namespaceFormat}${this.namespace}`;\n        const textLog = `${textFormat}${text}`;\n        return `${timestampLog}${typeLog}${namespaceLog}${textLog}`;\n    }\n\n    private logOnBrowser(type: LogType, message: string, format: FormatInterface) {\n        const { timestampFormat, typeFormat, namespaceFormat, textFormat } = format;\n        if (type === LogType.ERROR) {\n            console.error(message, timestampFormat, typeFormat, namespaceFormat, textFormat);\n        } else {\n            console.log(message, timestampFormat, typeFormat, namespaceFormat, textFormat);\n        }\n    }\n\n    private getFormat(type: LogType): FormatInterface {\n        if (this.isNode) {\n            return this.getNodeFormat(type);\n        }\n        // isBrowser\n        return this.getBrowserFormat(type);\n    }\n\n    private getNodeFormat(type: LogType): FormatInterface {\n        const whiteColor = this.utils.getColorByName('White');\n        const typeColor = this.utils.getColorAsType(type);\n        const greyColor = this.utils.getColorByName('Grey');\n\n        const timestampFormat = '\\u001b[3' + greyColor + 'm';\n        const typeFormat = '\\u001b[3' + typeColor + ';22m';\n        const namespaceFormat = '\\u001b[3' + whiteColor + ';1m';\n        const textFormat = '\\u001b[0m: ';\n\n        return { timestampFormat, typeFormat, textFormat, namespaceFormat };\n    }\n\n    private getBrowserFormat(type: LogType): FormatInterface {\n        const blackColor = this.utils.getColorByName('Black');\n        const typeColor = this.utils.getColorAsType(type);\n        const greyColor = this.utils.getColorByName('Grey');\n\n        const timestampFormat = 'color:' + greyColor;\n        const typeFormat = 'color:' + typeColor;\n        const namespaceFormat = 'color:' + blackColor + '; font-weight: bold';\n        const textFormat = ': ';\n\n        return { timestampFormat, typeFormat, textFormat, namespaceFormat };\n    }\n\n    //! timestamp like 2016-12-08 13:30:44 @lemon-engine\n    private createTimestamp(date: Date) {\n        const zeroOrNull = (text: number) => (text < 10 ? '0' : '');\n        const dt = date || new Date();\n        const [year, month, day, hours, minutes, seconds] = [\n            dt.getFullYear(),\n            dt.getMonth() + 1,\n            dt.getDate(),\n            dt.getHours(),\n            dt.getMinutes(),\n            dt.getSeconds(),\n        ];\n\n        const dateText = `${zeroOrNull(year)}${year}-${zeroOrNull(month)}${month}-${zeroOrNull(day)}${day}`; // yyyy-mm-dd\n        const hoursText = `${zeroOrNull(hours)}${hours}:${zeroOrNull(minutes)}${minutes}:${zeroOrNull(seconds)}${seconds}`; //hh:mm:ss\n        return `${dateText} ${hoursText}`;\n    }\n}\n","import { CloudProvider, Storage, WebCoreConfig } from '../types';\nimport { LocalStorageService } from '../utils';\nimport { jwtDecode, JwtPayload } from 'jwt-decode';\n\nexport const USE_X_LEMON_IDENTITY_KEY = 'use_x_lemon_identity_key';\nexport const USE_X_LEMON_LANGUAGE_KEY = 'use_x_lemon_language_key';\nexport const REGION_KEY = 'region';\n\n/**\n * Abstract class representing a token storage service.\n * Provides methods to set and get items in storage, and abstract methods\n * to check and manage cached tokens.\n */\nexport abstract class TokenStorageService {\n    protected prefix: string = 'lemon';\n    protected storage: Storage = new LocalStorageService();\n\n    /**\n     * Constructs a TokenStorageService instance.\n     * @param {WebCoreConfig<CloudProvider>} config - The configuration for the web core.\n     */\n    constructor(protected readonly config: WebCoreConfig<CloudProvider>) {\n        this.prefix = `@${config.project}`;\n        this.storage = this.config.storage || new LocalStorageService();\n    }\n\n    /**\n     * Updates the prefix used in storage keys.\n     * @param {string} prefix - The new prefix to use.\n     */\n    updatePrefix(prefix: string) {\n        this.prefix = `@${prefix}`;\n    }\n\n    /**\n     * Sets an item in the storage.\n     * @param {string} key - The key to set.\n     * @param {string} value - The value to set.\n     * @returns {Promise<void>} - A promise that resolves when the item is set.\n     */\n    async setItem(key: string, value: string): Promise<void> {\n        return await this.storage.setItem(`${this.prefix}.${key}`, value);\n    }\n\n    /**\n     * Gets an item from the storage.\n     * @param {string} key - The key to get.\n     * @returns {Promise<string>} - A promise that resolves to the value of the item.\n     */\n    async getItem(key: string): Promise<string> {\n        return await this.storage.getItem(`${this.prefix}.${key}`);\n    }\n\n    /**\n     * Gets all items from the storage.\n     * @returns {Promise<{ [key: string]: string }>} - A promise that resolves to an object containing all items.\n     */\n    abstract getAllItems(): Promise<{ [key: string]: string }>;\n\n    /**\n     * Checks if there is a cached token in the storage.\n     * @returns {Promise<boolean>} - A promise that resolves to true if a cached token exists, false otherwise.\n     */\n    abstract hasCachedToken(): Promise<boolean>;\n\n    /**\n     * Checks if the cached token should be refreshed.\n     * Abstract method that must be implemented by subclasses to define refresh logic.\n     * @returns {Promise<boolean>} Promise that resolves to true if the token should be refreshed, false otherwise\n     */\n    abstract shouldRefreshToken(): Promise<boolean>;\n\n    /**\n     * Calculates the token expiration timestamp with built-in safety buffer.\n     * Uses a priority-based approach: server expiration first, then JWT expiration, finally fallback duration.\n     * Automatically applies a 5-minute safety buffer to prevent token expiry during requests.\n     * @param {string} [serverExpiration] - ISO string or date string from server response\n     * @param {string} [jwtToken] - JWT token string to extract expiration from\n     * @returns {number} Unix timestamp (milliseconds) when the token should be considered expired\n     */\n    calculateTokenExpiration(serverExpiration?: string, jwtToken?: string): number {\n        const SAFETY_BUFFER = 5 * 60 * 1000; // 5 minutes\n        const FALLBACK_DURATION = 15 * 60 * 1000; // 15 minutes\n\n        if (serverExpiration) {\n            return new Date(serverExpiration).getTime() - SAFETY_BUFFER;\n        }\n\n        if (jwtToken) {\n            try {\n                const jwtExpiration = this.extractJWT(jwtToken)?.exp || null;\n                if (jwtExpiration) {\n                    return jwtExpiration * 1000 - SAFETY_BUFFER; // JWT exp is in seconds\n                }\n            } catch (error) {\n                console.warn('Failed to parse JWT expiration:', error);\n            }\n        }\n\n        console.warn('No server expiration found, using fallback duration');\n        return new Date().getTime() + FALLBACK_DURATION;\n    }\n\n    /**\n     * Extracts the issued time from a JWT token for token lifecycle tracking.\n     * Used to calculate token age and determine refresh timing based on token lifetime.\n     * @param {string} [jwtToken] - JWT token string to extract issued time from\n     * @returns {number | string} Unix timestamp in milliseconds if found, empty string if not available or on error\n     */\n    calculateTokenIssuedTime(jwtToken?: string): number | string {\n        if (jwtToken) {\n            try {\n                const jwtIssuedAt = this.extractJWT(jwtToken)?.iat || null;\n                if (jwtIssuedAt) {\n                    return jwtIssuedAt * 1000;\n                }\n            } catch (error) {\n                console.warn('Failed to parse JWT expiration:', error);\n                return '';\n            }\n        }\n\n        return '';\n    }\n\n    /**\n     * Safely decodes a JWT token and extracts its payload.\n     * Provides error-safe JWT parsing without throwing exceptions on malformed tokens.\n     * @param {string} jwt - JWT token string to decode\n     * @returns {JwtPayload | null} Decoded JWT payload object, or null if decoding fails\n     */\n    extractJWT(jwt: string): JwtPayload | null {\n        try {\n            return jwtDecode(jwt);\n        } catch {\n            return null;\n        }\n    }\n}\n","import { LemonCredentials, LemonKMS, LemonOAuthToken, WebCoreConfig } from '../types';\nimport { REGION_KEY, TokenStorageService, USE_X_LEMON_IDENTITY_KEY } from './token-storage.service';\nimport { convertCamelCaseFromSnake } from '../utils';\n\n/**\n * AWS-specific token storage service that manages OAuth tokens, credentials, and KMS configuration.\n * Extends TokenStorageService to provide AWS Cognito and STS token management capabilities.\n */\nexport class AWSStorageService extends TokenStorageService {\n    /**\n     * List of credential keys stored in the token storage.\n     * These keys represent the complete set of AWS authentication data.\n     */\n    private credentialKeys = [\n        'account_id',\n        'auth_id',\n        'identity_id',\n        'identity_pool_id',\n        'identity_token',\n        'access_key_id',\n        'secret_key',\n        'session_token',\n        'expired_time',\n        'issued_time',\n        'kms_arn',\n    ];\n\n    /**\n     * Creates an instance of AWSStorageService.\n     * @param {WebCoreConfig<'aws'>} config - AWS-specific web core configuration\n     */\n    constructor(readonly config: WebCoreConfig<'aws'>) {\n        super(config);\n    }\n\n    /**\n     * Initializes Lemon configuration by setting default values for identity usage and region.\n     * Sets up the storage with required configuration flags and regional settings.\n     * @returns {Promise<void>} Promise that resolves when initialization is complete\n     */\n    async initLemonConfig() {\n        await this.setItem(USE_X_LEMON_IDENTITY_KEY, 'true');\n        await this.setItem(REGION_KEY, this.config.region || 'ap-northeast-2');\n    }\n\n    /**\n     * Retrieves all stored credential items as a key-value map.\n     * Useful for debugging or bulk operations on stored credentials.\n     * @returns {Promise<{[key: string]: string}>} Promise resolving to object with all credential key-value pairs\n     */\n    async getAllItems() {\n        return await this.credentialKeys.reduce(async (promise, item) => {\n            const result: { [key: string]: string } = await promise.then();\n            result[`${this.prefix}.${item}`] = await this.storage.getItem(`${this.prefix}.${item}`);\n            return Promise.resolve(result);\n        }, Promise.resolve({}));\n    }\n\n    /**\n     * Checks if valid cached tokens exist in storage.\n     * Validates the presence of essential token components required for AWS authentication.\n     * @returns {Promise<boolean>} Promise resolving to true if all required tokens are cached\n     */\n    async hasCachedToken(): Promise<boolean> {\n        const expiredTime = await this.storage.getItem(`${this.prefix}.expired_time`);\n        const accessKeyId = await this.storage.getItem(`${this.prefix}.access_key_id`);\n        const secretKey = await this.storage.getItem(`${this.prefix}.secret_key`);\n        const identityToken = await this.storage.getItem(`${this.prefix}.identity_token`);\n\n        return !!accessKeyId && !!secretKey && !!expiredTime && !!identityToken;\n    }\n\n    /**\n     * Determines whether the stored token should be refreshed based on expiration time.\n     * Uses a 5-minute buffer before actual expiration to ensure token validity.\n     * @returns {Promise<boolean>} Promise resolving to true if token should be refreshed\n     */\n    async shouldRefreshToken(): Promise<boolean> {\n        const expiredTime = +(await this.storage.getItem(`${this.prefix}.expired_time`));\n        const now = new Date().getTime();\n\n        if (!expiredTime || expiredTime <= 0) {\n            return false;\n        }\n\n        if (now >= expiredTime) {\n            return true;\n        }\n\n        const bufferTime = 5 * 60 * 1000;\n        return now >= expiredTime - bufferTime;\n    }\n\n    /**\n     * Retrieves cached AWS credentials (access key, secret key, session token).\n     * Returns the credentials in the format expected by AWS SDK.\n     * @returns {Promise<LemonCredentials>} Promise resolving to AWS credentials object\n     */\n    async getCachedCredentials(): Promise<LemonCredentials> {\n        const AccessKeyId = await this.storage.getItem(`${this.prefix}.access_key_id`);\n        const SecretKey = await this.storage.getItem(`${this.prefix}.secret_key`);\n        const SessionToken = await this.storage.getItem(`${this.prefix}.session_token`);\n        return { AccessKeyId, SecretKey, SessionToken } as LemonCredentials;\n    }\n\n    /**\n     * Retrieves and transforms cached OAuth token data.\n     * Converts snake_case storage keys to camelCase and structures the data for OAuth usage.\n     * Excludes sensitive credential details from the returned object.\n     * @returns {Promise<LemonOAuthToken>} Promise resolving to formatted OAuth token object\n     */\n    async getCachedOAuthToken(): Promise<LemonOAuthToken> {\n        const result: any = await this.credentialKeys.reduce(async (promise, item) => {\n            const tmp: { [key: string]: string } = await promise.then();\n            tmp[convertCamelCaseFromSnake(item)] = await this.storage.getItem(`${this.prefix}.${item}`);\n            return Promise.resolve(tmp);\n        }, Promise.resolve({}));\n\n        const AccessKeyId = await this.storage.getItem(`${this.prefix}.access_key_id`);\n        const SecretKey = await this.storage.getItem(`${this.prefix}.secret_key`);\n        const SessionToken = await this.storage.getItem(`${this.prefix}.session_token`);\n        result.credential = { AccessKeyId, SecretKey, SessionToken };\n\n        delete result.accessKeyId;\n        delete result.secretKey;\n        delete result.sessionToken;\n        delete result.expiredTime;\n        delete result.kmsArn;\n\n        return result as LemonOAuthToken;\n    }\n\n    /**\n     * Saves OAuth token and associated AWS credentials to storage.\n     * Calculates and stores expiration and issued times for token lifecycle management.\n     * @param {LemonOAuthToken} token - OAuth token object containing credentials and metadata\n     * @returns {Promise<void>} Promise that resolves when save operation is complete\n     */\n    async saveOAuthToken(token: LemonOAuthToken): Promise<void> {\n        const { accountId, authId, credential, identityId, identityPoolId, identityToken } = token;\n        const { AccessKeyId, SecretKey, SessionToken, Expiration } = credential;\n\n        this.storage.setItem(`${this.prefix}.account_id`, accountId || '');\n        this.storage.setItem(`${this.prefix}.auth_id`, authId || '');\n        this.storage.setItem(`${this.prefix}.identity_id`, identityId || '');\n        this.storage.setItem(`${this.prefix}.identity_token`, identityToken || '');\n\n        this.storage.setItem(`${this.prefix}.identity_pool_id`, identityPoolId || '');\n        this.storage.setItem(`${this.prefix}.access_key_id`, AccessKeyId || '');\n        this.storage.setItem(`${this.prefix}.secret_key`, SecretKey || '');\n        this.storage.setItem(`${this.prefix}.session_token`, SessionToken || '');\n\n        const expiredTime = this.calculateTokenExpiration(Expiration, identityToken);\n        this.storage.setItem(`${this.prefix}.expired_time`, expiredTime.toString());\n\n        const issuedTime = this.calculateTokenIssuedTime(identityToken);\n        if (issuedTime) {\n            this.storage.setItem(`${this.prefix}.issued_time`, issuedTime.toString());\n        }\n\n        return;\n    }\n\n    /**\n     * Removes all stored OAuth tokens and credentials from storage.\n     * Performs complete cleanup of all credential-related storage keys.\n     * @returns {Promise<void>} Promise that resolves when all tokens are cleared\n     */\n    async clearOAuthToken(): Promise<void> {\n        await Promise.all(this.credentialKeys.map(item => this.storage.removeItem(`${this.prefix}.${item}`)));\n        return;\n    }\n\n    /**\n     * Saves KMS (Key Management Service) configuration to storage.\n     * Stores the KMS ARN for encryption/decryption operations.\n     * @param {LemonKMS} kms - KMS configuration object containing ARN\n     * @returns {Promise<void>} Promise that resolves when KMS data is saved\n     */\n    async saveKMS(kms: LemonKMS): Promise<void> {\n        const kmsArn = kms.arn;\n        this.storage.setItem(`${this.prefix}.kms_arn`, kmsArn || '');\n        return;\n    }\n}\n","import { TokenStorageService } from './token-storage.service';\nimport { LemonOAuthToken, WebCoreConfig } from '../types';\nimport { convertCamelCaseFromSnake } from '../utils';\n\n/**\n * A service to manage Azure-specific storage operations.\n */\nexport class AzureStorageService extends TokenStorageService {\n    /**\n     * The list of keys used to store credentials in the storage.\n     */\n    private credentialKeys = [\n        'account_id',\n        'auth_id',\n        'identity_id',\n        'identity_token',\n        'access_token',\n        'host_key',\n        'expired_time',\n        'issued_time',\n        'client_id',\n    ];\n\n    constructor(readonly config: WebCoreConfig<'azure'>) {\n        super(config);\n    }\n\n    /**\n     * Retrieves all items from the storage.\n     *\n     * @returns An object containing all the stored items.\n     */\n    async getAllItems(): Promise<{ [key: string]: string }> {\n        return await this.credentialKeys.reduce(async (promise, item) => {\n            const result: { [key: string]: string } = await promise;\n            result[`${this.prefix}.${item}`] = await this.storage.getItem(`${this.prefix}.${item}`);\n            return Promise.resolve(result);\n        }, Promise.resolve({}));\n    }\n\n    /**\n     * Checks if there is a cached OAuth token in the storage.\n     *\n     * @returns A boolean indicating whether a cached token exists.\n     */\n    async hasCachedToken(): Promise<boolean> {\n        const expiredTime = await this.storage.getItem(`${this.prefix}.expired_time`);\n        const identityToken = await this.storage.getItem(`${this.prefix}.identity_token`);\n        const accessToken = await this.storage.getItem(`${this.prefix}.access_token`);\n        const hostKey = await this.storage.getItem(`${this.prefix}.host_key`);\n\n        return !!identityToken && !!accessToken && !!hostKey && !!expiredTime;\n    }\n\n    /**\n     * Checks if the cached OAuth token needs to be refreshed.\n     *\n     * @returns A boolean indicating whether the token should be refreshed.\n     */\n    async shouldRefreshToken(): Promise<boolean> {\n        const expiredTime = +(await this.storage.getItem(`${this.prefix}.expired_time`));\n        const now = new Date().getTime();\n\n        if (!expiredTime || expiredTime <= 0) {\n            return false;\n        }\n\n        if (now >= expiredTime) {\n            return true;\n        }\n\n        const bufferTime = 5 * 60 * 1000;\n        return now >= expiredTime - bufferTime;\n    }\n\n    /**\n     * Retrieves the cached OAuth token from the storage.\n     *\n     * @returns The cached OAuth token or `null` if not found.\n     */\n    async getCachedOAuthToken(): Promise<LemonOAuthToken | null> {\n        const result: any = await this.credentialKeys.reduce(async (promise, item) => {\n            const tmp: { [key: string]: string } = await promise;\n            tmp[convertCamelCaseFromSnake(item)] = await this.storage.getItem(`${this.prefix}.${item}`);\n            return Promise.resolve(tmp);\n        }, Promise.resolve({}));\n\n        const hostKey = await this.storage.getItem(`${this.prefix}.host_key`);\n        result.credential = { HostKey: hostKey };\n\n        delete result.hostKey;\n        delete result.expiredTime;\n\n        return result as LemonOAuthToken | null;\n    }\n\n    /**\n     * Saves the provided OAuth token to the storage.\n     *\n     * @param token The OAuth token to be saved.\n     */\n    async saveOAuthToken(token: LemonOAuthToken): Promise<void> {\n        const { accountId, authId, credential, identityId, identityToken, accessToken } = token;\n        const { hostKey, clientId, Expiration } = credential;\n\n        this.storage.setItem(`${this.prefix}.account_id`, accountId || '');\n        this.storage.setItem(`${this.prefix}.auth_id`, authId || '');\n        this.storage.setItem(`${this.prefix}.identity_id`, identityId || '');\n        this.storage.setItem(`${this.prefix}.identity_token`, identityToken || '');\n\n        this.storage.setItem(`${this.prefix}.host_key`, hostKey || '');\n        this.storage.setItem(`${this.prefix}.access_token`, accessToken || '');\n        this.storage.setItem(`${this.prefix}.client_id`, clientId || 'default');\n\n        const expiredTime = this.calculateTokenExpiration(Expiration, identityToken);\n        this.storage.setItem(`${this.prefix}.expired_time`, expiredTime.toString());\n\n        const issuedTime = this.calculateTokenIssuedTime(identityToken);\n        if (issuedTime) {\n            this.storage.setItem(`${this.prefix}.issued_time`, issuedTime.toString());\n        }\n\n        return;\n    }\n\n    /**\n     * Clears all the cached OAuth tokens from the storage.\n     */\n    async clearOAuthToken(): Promise<void> {\n        await Promise.all(this.credentialKeys.map(item => this.storage.removeItem(`${this.prefix}.${item}`)));\n        return;\n    }\n}\n","import {\n    AWSWebCoreState,\n    Body,\n    ChangeSiteBody,\n    HttpResponse,\n    LemonCredentials,\n    LemonKMS,\n    LemonOAuthToken,\n    Params,\n    RefreshTokenBody,\n    TokenSignature,\n    WebCoreConfig,\n    WebCoreService,\n} from '../types';\nimport { AWSStorageService, USE_X_LEMON_IDENTITY_KEY, USE_X_LEMON_LANGUAGE_KEY } from '../token-storage';\nimport { calcSignature, LoggerService } from '../utils';\nimport axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { AWSHttpRequestBuilder, HttpRequestBuilder } from '../http';\nimport AWS from 'aws-sdk/global.js';\n\n/**\n * AWSWebCore class implements AWS-based operations for Lemoncloud authentication logic.\n * Provides comprehensive token management, credential building, and authenticated request capabilities.\n */\nexport class AWSWebCore implements WebCoreService {\n    private readonly tokenStorage: AWSStorageService;\n    private readonly logger: LoggerService;\n    private sharedAxiosInstance: AxiosInstance;\n\n    /**\n     * Creates an instance of AWSWebCore with the specified configuration.\n     * Initializes internal services including token storage, logging, and HTTP client.\n     *\n     * @param {WebCoreConfig<'aws'>} config - The AWS-specific configuration object containing\n     *                                        OAuth endpoints, region settings, and other AWS parameters\n     */\n    constructor(private readonly config: WebCoreConfig<'aws'>) {\n        this.logger = new LoggerService('AWSCore');\n        this.tokenStorage = new AWSStorageService(this.config);\n        this.sharedAxiosInstance = axios.create();\n    }\n\n    /**\n     * Retrieves the shared Axios instance used for HTTP requests.\n     * This instance is pre-configured and shared across all requests to maintain consistency.\n     *\n     * @returns {AxiosInstance} The configured Axios instance for making HTTP requests\n     */\n    getSharedAxiosInstance(): AxiosInstance {\n        return this.sharedAxiosInstance;\n    }\n\n    /**\n     * Initializes the AWS WebCore service by validating cached tokens and setting up credentials.\n     * Performs token refresh if necessary or builds credentials from cached data.\n     * This method should be called before using any authenticated operations.\n     *\n     * @returns {Promise<AWSWebCoreState>} A promise that resolves to the initialization state:\n     *                                     - 'no-token': No valid token found\n     *                                     - 'refreshed': Token was refreshed successfully\n     *                                     - 'build': Credentials built from existing valid token\n     * @throws {Error} Throws an error if token refresh fails or credentials cannot be built\n     *\n     * @example\n     * ```typescript\n     * const webCore = new AWSWebCore(config);\n     * const state = await webCore.init();\n     * if (state === 'no-token') {\n     *   // Handle authentication required\n     * }\n     * ```\n     */\n    async init(): Promise<AWSWebCoreState> {\n        await this.tokenStorage.initLemonConfig();\n        const hasCachedToken = await this.tokenStorage.hasCachedToken();\n        if (!hasCachedToken) {\n            this.logger.warn('initialized without token!');\n            return 'no-token';\n        }\n\n        const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();\n        if (shouldRefreshToken) {\n            const refreshed = await this.refreshCachedToken();\n            if (refreshed) {\n                await this.getCurrentCredentials();\n                this.logger.info('initialized and refreshed token!');\n                return 'refreshed';\n            }\n        }\n\n        const cachedToken = await this.tokenStorage.hasCachedToken();\n        if (!cachedToken) {\n            this.logger.warn('initialized without token!');\n            return 'no-token';\n        }\n\n        // build AWS credential without refresh\n        const credential = await this.tokenStorage.getCachedCredentials();\n        this.createAWSCredentials(credential);\n        this.logger.info('initialized with token!');\n        return 'build';\n    }\n\n    /**\n     * Retrieves the token storage service instance.\n     * Provides access to the underlying storage service for advanced token management operations.\n     *\n     * @returns {AWSStorageService} The storage service that manages OAuth tokens and credentials\n     */\n    getTokenStorage(): AWSStorageService {\n        return this.tokenStorage;\n    }\n\n    /**\n     * Creates an HTTP request builder for unsigned requests.\n     * Use this for requests that don't require AWS signature authentication.\n     *\n     * @param {AxiosRequestConfig} config - The Axios request configuration object containing\n     *                                      method, URL, headers, and other request parameters\n     * @returns {HttpRequestBuilder} A configured HTTP request builder instance\n     *\n     * @example\n     * ```typescript\n     * const builder = webCore.buildRequest({\n     *   method: 'GET',\n     *   url: '/api/public-endpoint'\n     * });\n     * const response = await builder.execute();\n     * ```\n     */\n    buildRequest(config: AxiosRequestConfig): HttpRequestBuilder {\n        return new HttpRequestBuilder(config, this.sharedAxiosInstance);\n    }\n\n    /**\n     * Executes an HTTP request without AWS signature authentication.\n     * Suitable for public endpoints or non-AWS services.\n     *\n     * @template T - The expected response data type\n     * @param {string} method - The HTTP method (GET, POST, PUT, DELETE, etc.)\n     * @param {string} url - The complete request URL or base URL\n     * @param {Params} [params={}] - Query parameters to append to the URL\n     * @param {Body} [body] - The request body for POST/PUT requests\n     * @param {AxiosRequestConfig} [config] - Additional Axios configuration options\n     * @returns {Promise<HttpResponse<T>>} Promise resolving to the HTTP response with typed data\n     * @throws {Error} Throws on network errors, HTTP errors, or request configuration issues\n     *\n     * @example\n     * ```typescript\n     * const response = await webCore.request<UserData>(\n     *   'GET',\n     *   '/api/users/123',\n     *   { include: 'profile' }\n     * );\n     * ```\n     */\n    async request<T>(method: string, url: string, params: Params = {}, body?: Body, config?: AxiosRequestConfig): Promise<HttpResponse<T>> {\n        const builder = new HttpRequestBuilder({\n            method,\n            baseURL: url,\n            params,\n        });\n        if (body) {\n            builder.setBody(body);\n        }\n        if (config) {\n            builder.addAxiosRequestConfig(config);\n        }\n        return await builder.execute();\n    }\n\n    /**\n     * Creates an HTTP request builder with AWS signature authentication.\n     * Use this for requests to AWS services or signed API endpoints.\n     *\n     * @param {AxiosRequestConfig} config - The Axios request configuration object\n     * @returns {AWSHttpRequestBuilder} A configured AWS HTTP request builder with signature capabilities\n     *\n     * @example\n     * ```typescript\n     * const builder = webCore.buildSignedRequest({\n     *   method: 'POST',\n     *   url: '/api/aws-protected-endpoint'\n     * });\n     * ```\n     */\n    buildSignedRequest(config: AxiosRequestConfig): AWSHttpRequestBuilder {\n        return new AWSHttpRequestBuilder(this.tokenStorage, config, this.sharedAxiosInstance);\n    }\n\n    /**\n     * Executes an HTTP request with AWS signature authentication.\n     * Automatically signs the request using stored AWS credentials.\n     *\n     * @template T - The expected response data type\n     * @param {string} method - The HTTP method (GET, POST, PUT, DELETE, etc.)\n     * @param {string} url - The complete request URL or base URL\n     * @param {Params} [params={}] - Query parameters to append to the URL\n     * @param {Body} [body] - The request body for POST/PUT requests\n     * @param {AxiosRequestConfig} [config] - Additional Axios configuration options\n     * @returns {Promise<HttpResponse<T>>} Promise resolving to the signed HTTP response\n     * @throws {Error} Throws on authentication errors, network errors, or signature failures\n     *\n     * @example\n     * ```typescript\n     * const response = await webCore.signedRequest<ApiResponse>(\n     *   'POST',\n     *   '/api/protected-resource',\n     *   {},\n     *   { data: 'sensitive information' }\n     * );\n     * ```\n     */\n    async signedRequest<T>(\n        method: string,\n        url: string,\n        params: Params = {},\n        body?: Body,\n        config?: AxiosRequestConfig\n    ): Promise<HttpResponse<T>> {\n        const builder = new AWSHttpRequestBuilder(this.tokenStorage, {\n            method,\n            baseURL: url,\n            params,\n        });\n        if (body) {\n            builder.setBody(body);\n        }\n        if (config) {\n            builder.addAxiosRequestConfig(config);\n        }\n        return await builder.execute();\n    }\n\n    /**\n     * Retrieves all saved tokens from storage as a key-value map.\n     * Useful for debugging, backup, or migration purposes.\n     *\n     * @returns {Promise<{ [key: string]: string }>} Promise resolving to an object containing\n     *                                               all stored token data with keys and values\n     */\n    getSavedToken(): Promise<{ [key: string]: string }> {\n        return this.tokenStorage.getAllItems();\n    }\n\n    /**\n     * Checks if the user is currently authenticated with valid credentials.\n     * Performs token validation and refresh if necessary before determining authentication status.\n     *\n     * @returns {Promise<boolean>} Promise resolving to true if authenticated with valid credentials,\n     *                            false if no token exists or authentication fails\n     * @throws {Error} Logs errors but doesn't throw, returning false on any authentication failure\n     *\n     * @example\n     * ```typescript\n     * if (await webCore.isAuthenticated()) {\n     *   // User is authenticated, proceed with protected operations\n     * } else {\n     *   // Redirect to login or handle unauthenticated state\n     * }\n     * ```\n     */\n    async isAuthenticated(): Promise<boolean> {\n        try {\n            const hasCachedToken = await this.tokenStorage.hasCachedToken();\n            if (!hasCachedToken) {\n                return false;\n            }\n\n            const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();\n            if (shouldRefreshToken) {\n                this.logger.info('return isAuthenticated after refresh token');\n                const refreshed = await this.refreshCachedToken();\n                return refreshed !== null;\n            }\n\n            return new Promise(resolve => {\n                try {\n                    const credentials = AWS.config.credentials as AWS.Credentials;\n                    if (!credentials) {\n                        resolve(false);\n                        return;\n                    }\n\n                    credentials.get(error => {\n                        if (error) {\n                            this.logger.error('get AWSConfig.credentials error: ', error);\n                        }\n                        resolve(!error);\n                    });\n                } catch (e) {\n                    this.logger.error('isAuthenticated error: ', e);\n                    resolve(false);\n                }\n            });\n        } catch (error) {\n            this.logger.error('isAuthenticated error:', error);\n            return false;\n        }\n    }\n\n    /**\n     * Builds AWS credentials from an OAuth token and sets them in AWS.config.\n     * Saves the token to storage and creates AWS credentials for subsequent API calls.\n     *\n     * @param {LemonOAuthToken} token - The OAuth token containing AWS credential information\n     * @returns {Promise<AWS.Credentials>} Promise resolving to the built AWS credentials\n     * @throws {Error} Throws if token is invalid or AWS credentials cannot be created\n     *\n     * @example\n     * ```typescript\n     * const credentials = await webCore.buildCredentialsByToken(oauthToken);\n     * // AWS.config.credentials is now set and ready for use\n     * ```\n     */\n    async buildCredentialsByToken(token: LemonOAuthToken): Promise<AWS.Credentials> {\n        this.logger.log('buildCredentialsByToken()...');\n        await this.buildAWSCredentialsByToken(token);\n\n        const credentials = AWS.config.credentials as AWS.Credentials;\n        if (!credentials) {\n            throw new Error('Failed to build AWS credentials');\n        }\n        return credentials;\n    }\n\n    /**\n     * Builds AWS credentials from cached storage data and sets them in AWS.config.\n     * Uses previously stored credential information to recreate AWS credentials.\n     *\n     * @returns {Promise<AWS.Credentials>} Promise resolving to the built AWS credentials\n     * @throws {Error} Throws if cached credentials are invalid or AWS credentials cannot be created\n     *\n     * @example\n     * ```typescript\n     * const credentials = await webCore.buildCredentialsByStorage();\n     * // AWS.config.credentials is now set from cached data\n     * ```\n     */\n    async buildCredentialsByStorage(): Promise<AWS.Credentials> {\n        this.logger.log('buildCredentialsByStorage()...');\n        await this.buildAWSCredentialsByStorage();\n\n        const credentials = AWS.config.credentials as AWS.Credentials;\n        if (!credentials) {\n            throw new Error('Failed to build AWS credentials from storage');\n        }\n        return credentials;\n    }\n\n    /**\n     * Saves KMS (Key Management Service) configuration to storage.\n     * Stores KMS ARN and other encryption-related configuration for later use.\n     *\n     * @param {LemonKMS} kms - The KMS configuration object containing ARN and encryption settings\n     * @returns {Promise<void>} Promise that resolves when KMS configuration is successfully saved\n     * @throws {Error} Throws if KMS configuration cannot be saved to storage\n     */\n    async saveKMS(kms: LemonKMS): Promise<void> {\n        this.logger.log('saveKMS()...');\n        return await this.tokenStorage.saveKMS(kms);\n    }\n\n    /**\n     * Refreshes the cached OAuth token by calling the refresh endpoint.\n     * Obtains new credentials and updates AWS.config with fresh authentication data.\n     *\n     * @param {string} [domain=''] - Optional domain parameter for multi-tenant refresh requests\n     * @param {string} [url=''] - Optional custom URL for the refresh endpoint, defaults to config.oAuthEndpoint\n     * @returns {Promise<AWS.Credentials | null>} Promise resolving to new AWS credentials on success,\n     *                                           null if refresh fails or token is invalid\n     * @throws {Error} Logs errors but returns null instead of throwing\n     *\n     * @example\n     * ```typescript\n     * const newCredentials = await webCore.refreshCachedToken();\n     * if (newCredentials) {\n     *   // Token successfully refreshed\n     * } else {\n     *   // Refresh failed, user may need to re-authenticate\n     * }\n     * ```\n     */\n    async refreshCachedToken(domain: string = '', url: string = '') {\n        try {\n            const cached = await this.tokenStorage.getCachedOAuthToken();\n            if (!cached.authId) {\n                throw new Error('authId is required for token refresh');\n            }\n\n            const payload = {\n                authId: cached.authId,\n                accountId: cached.accountId,\n                identityId: cached.identityId,\n                identityToken: cached.identityToken,\n            };\n            const current = new Date().toISOString();\n            const signature = calcSignature(payload, current);\n\n            let body: RefreshTokenBody = { current, signature };\n            if (domain && domain.length > 0) {\n                body = { ...body, domain };\n            }\n\n            const response: HttpResponse<LemonOAuthToken> = await this.signedRequest(\n                'POST',\n                url ? url : `${this.config.oAuthEndpoint}/oauth/${cached.authId}/refresh`,\n                {},\n                { ...body }\n            );\n\n            const tokenData = response.data.Token || response.data;\n            const refreshToken = {\n                identityToken: tokenData.identityToken || cached.identityToken,\n                identityPoolId: cached.identityPoolId,\n                ...tokenData,\n            };\n\n            this.logger.info('success to refresh token');\n\n            return await this.buildCredentialsByToken(refreshToken);\n        } catch (error) {\n            this.logger.error('token refresh failed:', error);\n            return null;\n        }\n    }\n\n    /**\n     * Changes the user's active site and obtains new credentials for the target site.\n     * Useful for multi-tenant applications where users can switch between different sites/organizations.\n     *\n     * @param {ChangeSiteBody} changeSiteBody - Object containing siteId and userId for the target site\n     * @param {string} changeSiteBody.siteId - The identifier of the target site to switch to\n     * @param {string} changeSiteBody.userId - The user identifier for the site change operation\n     * @param {string} [url] - Optional custom URL for the site change endpoint\n     * @returns {Promise<AWS.Credentials>} Promise resolving to new AWS credentials for the target site\n     * @throws {Error} Throws if changeSiteBody is invalid, authId is missing, or site change fails\n     *\n     * @example\n     * ```typescript\n     * const credentials = await webCore.changeUserSite({\n     *   siteId: 'new-site-123',\n     *   userId: 'user-456'\n     * });\n     * // User is now authenticated for the new site\n     * ```\n     */\n    async changeUserSite(changeSiteBody: ChangeSiteBody, url?: string): Promise<AWS.Credentials> {\n        if (!changeSiteBody || !changeSiteBody.siteId || !changeSiteBody.userId) {\n            throw new Error('@changeSiteBody required');\n        }\n\n        const cached = await this.tokenStorage.getCachedOAuthToken();\n        const target = `${changeSiteBody.userId}@${changeSiteBody.siteId}`;\n        const tokenSignature = await this.getTokenSignature();\n        const { authId, current, signature, originToken } = tokenSignature;\n        if (!authId) {\n            throw new Error('authId is required for token refresh');\n        }\n\n        const response: HttpResponse<LemonOAuthToken> = await this.signedRequest(\n            'POST',\n            url ? url : `${this.config.oAuthEndpoint}/oauth/${authId}/refresh`,\n            {},\n            { current, signature, target }\n        );\n        const refreshToken = {\n            ...response.data,\n            identityToken: response.data?.identityToken || originToken.identityToken,\n            identityPoolId: cached.identityPoolId,\n        };\n        this.logger.info('success to change user site');\n        return await this.buildCredentialsByToken(refreshToken);\n    }\n\n    /**\n     * Logs out the user by clearing AWS credentials and removing stored tokens.\n     * Performs complete cleanup of authentication state.\n     *\n     * @returns {Promise<void>} Promise that resolves when logout is complete\n     * @throws {Error} Throws if token cleanup fails\n     *\n     * @example\n     * ```typescript\n     * await webCore.logout();\n     * // User is now logged out, all credentials cleared\n     * ```\n     */\n    async logout(): Promise<void> {\n        AWS.config.credentials = null;\n        await this.tokenStorage.clearOAuthToken();\n        return;\n    }\n\n    /**\n     * Configures whether to use the X-Lemon-Identity header in requests.\n     * Controls identity header inclusion for request identification and tracking.\n     *\n     * @param {boolean} use - True to include X-Lemon-Identity header, false to exclude it\n     * @returns {Promise<void>} Promise that resolves when setting is saved\n     */\n    async setUseXLemonIdentity(use: boolean): Promise<void> {\n        await this.tokenStorage.setItem(USE_X_LEMON_IDENTITY_KEY, `${use}`);\n    }\n\n    /**\n     * Configures whether to use the X-Lemon-Language header with a specific key.\n     * Controls language header inclusion for localization and language preference tracking.\n     *\n     * @param {boolean} use - True to include X-Lemon-Language header, false to exclude it\n     * @param {string} [key] - The language key to use when use is true; required if use is true\n     * @returns {Promise<void>} Promise that resolves when setting is saved\n     *\n     * @example\n     * ```typescript\n     * await webCore.setUseXLemonLanguage(true, 'en-US');\n     * // X-Lemon-Language header will be included with 'en-US' value\n     * ```\n     */\n    async setUseXLemonLanguage(use: boolean, key?: string): Promise<void> {\n        if (!use) {\n            await this.tokenStorage.setItem(USE_X_LEMON_LANGUAGE_KEY, '');\n            return;\n        }\n        if (!key) {\n            return;\n        }\n        await this.tokenStorage.setItem(USE_X_LEMON_LANGUAGE_KEY, key);\n    }\n\n    /**\n     * Generates a cryptographic signature for token-based operations.\n     * Creates a time-based signature using stored token information for secure API calls.\n     *\n     * @returns {Promise<TokenSignature>} Promise resolving to signature object containing:\n     *                                   - authId: Authentication identifier\n     *                                   - current: Current timestamp in ISO format\n     *                                   - signature: Calculated cryptographic signature\n     *                                   - originToken: Original token data used for signature\n     * @throws {Error} Throws if cached token is invalid or signature calculation fails\n     */\n    async getTokenSignature(): Promise<TokenSignature> {\n        const originToken = await this.tokenStorage.getCachedOAuthToken();\n        const payload = {\n            authId: originToken.authId,\n            accountId: originToken.accountId,\n            identityId: originToken.identityId,\n            identityToken: originToken.identityToken,\n        };\n        const current = new Date().toISOString();\n        const signature = calcSignature(payload, current);\n        return { authId: payload.authId, current, signature, originToken };\n    }\n\n    /**\n     * Retrieves current AWS credentials, refreshing them if necessary.\n     * Checks token validity and performs refresh if the token is expired or near expiration.\n     *\n     * @returns {Promise<AWS.Credentials | null>} Promise resolving to current AWS credentials,\n     *                                           or null if no valid token exists or refresh fails\n     * @throws {Error} Logs errors but returns null instead of throwing\n     *\n     * @example\n     * ```typescript\n     * const credentials = await webCore.getCredentials();\n     * if (credentials) {\n     *   // Use credentials for AWS API calls\n     * } else {\n     *   // No valid credentials, authentication required\n     * }\n     * ```\n     */\n    async getCredentials(): Promise<AWS.Credentials | null> {\n        const hasCachedToken = await this.tokenStorage.hasCachedToken();\n        if (!hasCachedToken) {\n            this.logger.info('has no cached token!');\n            return null;\n        }\n\n        const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();\n        if (shouldRefreshToken) {\n            this.logger.info('should refresh token!');\n            const refreshed = await this.refreshCachedToken();\n            if (!refreshed) {\n                return null;\n            }\n        }\n\n        return await this.getCurrentCredentials();\n    }\n\n    /**\n     * Builds AWS credentials from cached storage data.\n     * Private method that creates AWS.Credentials object from stored credential data.\n     *\n     * @private\n     * @returns {Promise<void>} Promise that resolves when credentials are built and set\n     * @throws {Error} Throws if cached credentials are missing or invalid\n     */\n    private async buildAWSCredentialsByStorage(): Promise<void> {\n        this.logger.log('buildAWSCredentialsByStorage()...');\n        const credentials = await this.tokenStorage.getCachedCredentials();\n\n        const { AccessKeyId, SecretKey } = credentials;\n        if (!AccessKeyId) {\n            throw new Error('.AccessKeyId (string) is required!');\n        }\n        if (!SecretKey) {\n            throw new Error('.SecretKey (string) is required!');\n        }\n        this.createAWSCredentials(credentials);\n    }\n\n    /**\n     * Retrieves the current AWS credentials from AWS.config.\n     * Private method that validates and returns the currently configured AWS credentials.\n     *\n     * @private\n     * @returns {Promise<AWS.Credentials>} Promise resolving to current AWS credentials\n     * @throws {Error} Throws if no credentials are configured or credential validation fails\n     */\n    private getCurrentCredentials(): Promise<AWS.Credentials> {\n        return new Promise((resolve, reject) => {\n            const credentials = AWS.config.credentials as AWS.Credentials;\n            if (!credentials) {\n                reject(new Error('No AWS credentials configured'));\n                return;\n            }\n\n            credentials.get(error => {\n                if (error) {\n                    this.logger.error('Error on getCurrentCredentials: ', error);\n                    reject(error);\n                } else {\n                    this.logger.info('success to get AWS credentials');\n                    resolve(credentials);\n                }\n            });\n        });\n    }\n\n    /**\n     * Builds AWS credentials from an OAuth token and saves to storage.\n     * Private method that processes token data, saves it to storage, and creates AWS credentials.\n     *\n     * @private\n     * @param {LemonOAuthToken} token - The OAuth token containing credential information\n     * @returns {Promise<void>} Promise that resolves when token is saved and credentials are created\n     * @throws {Error} Throws if token is missing required fields or credential creation fails\n     */\n    private async buildAWSCredentialsByToken(token: LemonOAuthToken): Promise<void> {\n        const { credential } = token;\n        const { AccessKeyId, SecretKey } = credential;\n        if (!AccessKeyId) {\n            throw new Error('.AccessKeyId (string) is required!');\n        }\n        if (!SecretKey) {\n            throw new Error('.SecretKey (string) is required!');\n        }\n        await this.tokenStorage.saveOAuthToken(token);\n        return this.createAWSCredentials(credential);\n    }\n\n    /**\n     * Creates and sets AWS credentials in the global AWS configuration.\n     * Private method that instantiates AWS.Credentials and assigns it to AWS.config.credentials.\n     *\n     * @private\n     * @param {LemonCredentials} credentials - The credential object containing AWS access keys\n     * @param {string} credentials.AccessKeyId - AWS access key identifier\n     * @param {string} credentials.SecretKey - AWS secret access key\n     * @param {string} [credentials.SessionToken] - Optional AWS session token for temporary credentials\n     * @returns {void} No return value, sets AWS.config.credentials directly\n     */\n    private createAWSCredentials(credentials: LemonCredentials) {\n        const { AccessKeyId, SecretKey, SessionToken } = credentials;\n        AWS.config.credentials = new AWS.Credentials(AccessKeyId, SecretKey, SessionToken);\n    }\n}\n","import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { Body, Headers, HttpResponse, Params } from '../types';\n\n/**\n * Class to build and execute HTTP requests\n * @example\n * ```ts\n * const response: HttpResponse<OAuthResponse> = await new HttpRequestBuilder({\n *     method: 'GET',\n *     baseURL: `https://api.lemoncloud.io/v1/oauth`,\n *  })\n *    .setHeaders({ Cookie: this.cookie })\n *    .setParams({ page: 0 })\n *    .execute();\n * ```\n */\nexport class HttpRequestBuilder {\n    private axiosInstance: AxiosInstance;\n    private config: AxiosRequestConfig = {\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        method: 'get',\n    };\n\n    /**\n     * @constructor\n     * @param {AxiosRequestConfig} [config={}] - Initial configuration\n     * @param {AxiosInstance} - Axios Instance\n     * @throws {Error} If the method is not defined\n     * @throws {Error} If the baseURL is not defined\n     */\n    constructor(config: AxiosRequestConfig, axiosInstance?: AxiosInstance) {\n        if (!config.method) {\n            throw new Error('method should be defined!');\n        }\n        if (!config.baseURL) {\n            throw new Error('baseURL should be defined!');\n        }\n        this.config = { ...this.config, ...config };\n        this.axiosInstance = axiosInstance || axios.create(config);\n    }\n\n    /**\n     * Sets the request headers\n     * @param {Headers} headers - Headers to set\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining\n     */\n    setHeaders(headers: Headers): HttpRequestBuilder {\n        this.config.headers = headers;\n        return this;\n    }\n\n    /**\n     * Sets the request parameters\n     * @param {Params} params - Parameters to set\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining\n     */\n    setParams(params: Params): HttpRequestBuilder {\n        this.config.params = params;\n        return this;\n    }\n\n    /**\n     * Sets the request body\n     * @param {Body} data - Body data to set\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining\n     */\n    setBody(data: Body): HttpRequestBuilder {\n        this.config.data = data;\n        return this;\n    }\n\n    /**\n     * Sets the request method\n     * @param {string} method - HTTP method to set\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining\n     */\n    setMethod(method: string): HttpRequestBuilder {\n        this.config.method = method;\n        return this;\n    }\n\n    /**\n     * Adds additional headers to the request.\n     * @param {Headers} headers - Headers to add.\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addHeaders(headers: Headers = {}): HttpRequestBuilder {\n        this.config.headers = { ...this.config.headers, ...headers };\n        return this;\n    }\n\n    /**\n     * Adds additional Axios request configuration.\n     * @param {AxiosRequestConfig} config - The configuration to add.\n     * @returns {HttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addAxiosRequestConfig(config: AxiosRequestConfig): HttpRequestBuilder {\n        this.config = { ...this.config, ...config };\n        return this;\n    }\n\n    /**\n     * Executes the HTTP request\n     * @template T\n     * @returns {Promise<HttpResponse<T>>} - Promise containing the response\n     * @throws {Error} If an error occurs during the request\n     */\n    async execute<T>(): Promise<HttpResponse<T>> {\n        try {\n            return await this.axiosInstance.request<T>(this.config);\n        } catch (error) {\n            throw error;\n        }\n    }\n}\n","import axios, { AxiosHeaders, AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { Body, Headers, HttpRequestData, HttpResponse, Params } from '../types';\nimport { AWSStorageService, REGION_KEY, USE_X_LEMON_IDENTITY_KEY, USE_X_LEMON_LANGUAGE_KEY } from '../token-storage';\nimport AWS from 'aws-sdk/global.js';\nimport { sigV4Client } from '../vendor';\nimport { isEmptyObject, LoggerService } from '../utils';\n\n/**\n * Class to build and execute HTTP requests with AWS signing\n * @example\n * ```ts\n * const response: HttpResponse<OAuthResponse> = await new AWSHttpRequestBuilder({\n *     method: 'GET',\n *     baseURL: `https://api.lemoncloud.io/v1/oauth`,\n *  })\n *    .addHeaders({ Cookie: this.cookie })\n *    .setParams({ page: 0 })\n *    .execute();\n * ```\n */\nexport class AWSHttpRequestBuilder {\n    private axiosInstance: AxiosInstance;\n    private logger: LoggerService;\n    private config: AxiosRequestConfig = {\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        method: 'get',\n    };\n\n    /**\n     * Creates an instance of AWSHttpRequestBuilder.\n     * @param {AWSStorageService} tokenStorage - The AWS storage service for token management.\n     * @param {AxiosRequestConfig} config - The Axios request configuration.\n     * @param {AxiosInstance} axiosInstance - The Axios instance.\n     * @throws {Error} If tokenStorage, method, or baseURL are not defined.\n     */\n    constructor(\n        private readonly tokenStorage: AWSStorageService,\n        config: AxiosRequestConfig,\n        axiosInstance?: AxiosInstance\n    ) {\n        if (!tokenStorage) {\n            throw new Error('tokenStorage should be defined!');\n        }\n        if (!config.method) {\n            throw new Error('method should be defined!');\n        }\n        if (!config.baseURL) {\n            throw new Error('baseURL should be defined!');\n        }\n        this.config = { ...this.config, ...config };\n        this.axiosInstance = axiosInstance || axios.create(this.config);\n        this.logger = new LoggerService('AWSHttpBuilder');\n    }\n\n    /**\n     * Sets the request headers.\n     * @param {Headers} headers - Headers to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setHeaders(headers: Headers): AWSHttpRequestBuilder {\n        this.config.headers = headers;\n        return this;\n    }\n\n    /**\n     * Sets the request parameters.\n     * @param {Params} params - Parameters to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setParams(params: Params): AWSHttpRequestBuilder {\n        this.config.params = params;\n        return this;\n    }\n\n    /**\n     * Sets the request body.\n     * @param {Body} data - Body data to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setBody(data: Body): AWSHttpRequestBuilder {\n        this.config.data = data;\n        return this;\n    }\n\n    /**\n     * Sets the request method.\n     * @param {string} method - HTTP method to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setMethod(method: string): AWSHttpRequestBuilder {\n        this.config.method = method;\n        return this;\n    }\n\n    /**\n     * Adds additional headers to the request.\n     * @param {Headers} headers - Headers to add.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addHeaders(headers: Headers = {}): AWSHttpRequestBuilder {\n        this.config.headers = { ...this.config.headers, ...headers };\n        return this;\n    }\n\n    /**\n     * Adds additional Axios request configuration.\n     * @param {AxiosRequestConfig} config - The configuration to add.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addAxiosRequestConfig(config: AxiosRequestConfig): AWSHttpRequestBuilder {\n        this.config = { ...this.config, ...config };\n        return this;\n    }\n\n    /**\n     * Executes the HTTP request.\n     * @template T\n     * @returns {Promise<HttpResponse<T>>} - Promise containing the response.\n     * @throws {Error} If an error occurs during the request.\n     */\n    async execute<T>(): Promise<HttpResponse<T>> {\n        try {\n            const signedClient = await this.getSignedClient(this.config.baseURL);\n            const data: HttpRequestData = {\n                method: this.config.method?.toLowerCase() || 'get',\n                params: this.config.params,\n                body: this.config.data,\n            };\n            const sigendHeader = await this.getSignedHeader(signedClient, data);\n            this.addHeaders(sigendHeader);\n            return await this.axiosInstance.request<T>(this.config);\n        } catch (error) {\n            throw error;\n        }\n    }\n\n    /**\n     * Gets the signed AWS client.\n     * @private\n     * @param {string} endpoint - The endpoint for the client.\n     * @returns {Promise<any>} - The signed AWS client.\n     * @throws {Error} If endpoint is not provided or signed client is not available.\n     */\n    private async getSignedClient(endpoint: string): Promise<any> {\n        if (!endpoint) {\n            throw new Error('@endpoint (string) is required!');\n        }\n\n        const region = await this.tokenStorage.getItem(REGION_KEY);\n        const ok = AWS.config && AWS.config.credentials;\n        const signedClient =\n            ok &&\n            sigV4Client.newClient({\n                accessKey: AWS.config.credentials.accessKeyId,\n                secretKey: AWS.config.credentials.secretAccessKey,\n                sessionToken: AWS.config.credentials.sessionToken,\n                region: region || 'ap-northeast-2',\n                endpoint: endpoint,\n                host: this.extractHostname(endpoint),\n            });\n\n        if (!signedClient) {\n            this.logger.warn('signedClient is missing. Request without signing..');\n        }\n        return await signedClient;\n    }\n\n    /**\n     * Gets the signed headers for the request.\n     * @private\n     * @param {any} signedClient - The signed AWS client.\n     * @param {HttpRequestData} data - The request data.\n     * @returns {Promise<any>} - The signed headers.\n     */\n    private async getSignedHeader(signedClient: any, data: HttpRequestData): Promise<any> {\n        if (!signedClient) {\n            return {};\n        }\n\n        const { method, path, params, body } = data;\n        // check signRequest instance.\n        const signedRequest = signedClient.signRequest({\n            method: method,\n            path: path || '',\n            headers: {},\n            queryParams: params || {},\n            body: body || {},\n        });\n        const header = signedRequest && signedRequest.headers;\n\n        const hasNoHeader = isEmptyObject(header);\n        if (hasNoHeader) {\n            this.logger.warn('signedClient is missing => Request without signing');\n            return this.config.headers;\n        }\n\n        const headerWithIdentity = await this.addXLemonIdentityToHeader(header);\n        return await this.addXLemonLanguageToHeader(headerWithIdentity);\n    }\n\n    /**\n     * Adds x-lemon-identity to the header.\n     * @param header The header to be added\n     * @returns The header with x-lemon-identity added\n     */\n    private async addXLemonIdentityToHeader(header: any): Promise<AxiosHeaders> {\n        const useXLemonIdentity = await this.tokenStorage.getItem(USE_X_LEMON_IDENTITY_KEY);\n        if (!useXLemonIdentity || useXLemonIdentity === 'false') {\n            return { ...header, ...this.config.headers };\n        }\n        const identityToken = await this.tokenStorage.getItem('identity_token');\n        return {\n            ...header,\n            ...this.config.headers,\n            'x-lemon-identity': identityToken,\n        };\n    }\n\n    /**\n     * Adds x-lemon-language to the header.\n     * @param header The header to be added\n     * @returns The header with x-lemon-language added\n     */\n    private async addXLemonLanguageToHeader(header: any): Promise<AxiosHeaders> {\n        const [languageKey, language] = await Promise.all([\n            this.tokenStorage.getItem(USE_X_LEMON_LANGUAGE_KEY),\n            this.tokenStorage.getItem((await this.tokenStorage.getItem(USE_X_LEMON_LANGUAGE_KEY)) || ''),\n        ]);\n\n        return {\n            ...header,\n            ...this.config.headers,\n            ...(languageKey && language && { 'x-lemon-language': language }),\n        };\n    }\n\n    /**\n     * Extracts the hostname from a URL.\n     * @private\n     * @param {string} url - The URL to extract the hostname from.\n     * @returns {string} - The extracted hostname.\n     */\n    private extractHostname(url: string) {\n        // refer: https://stackoverflow.com/a/23945027/5268806\n        let hostname;\n        // find & remove protocol (http, ftp, etc.) and get hostname\n        if (url.indexOf('//') > -1) {\n            hostname = url.split('/')[2];\n        } else {\n            hostname = url.split('/')[0];\n        }\n        // find & remove port number\n        hostname = hostname.split(':')[0];\n        // find & remove \"?\"\n        hostname = hostname.split('?')[0];\n        return hostname;\n    }\n}\n","/* tslint:disable */\n/*\n * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\").\n * You may not use this file except in compliance with the License.\n * A copy of the License is located at\n *\n *  http://aws.amazon.com/apache2.0\n *\n * or in the \"license\" file accompanying this file. This file is distributed\n * on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\n * express or implied. See the License for the specific language governing\n * permissions and limitations under the License.\n */\n\n// import * as CryptoJS from 'crypto-js';\nimport sha256 from 'crypto-js/sha256.js';\nimport hmacSHA256 from 'crypto-js/hmac-sha256.js';\nimport Hex from 'crypto-js/enc-hex.js';\n\nconst SHA256 = sha256;\nconst encHex = Hex;\nconst HmacSHA256 = hmacSHA256;\n\nconst sigV4Client: { [key: string]: any } = {};\n\nsigV4Client.newClient = function (config: any) {\n    const AWS_SHA_256 = 'AWS4-HMAC-SHA256';\n    const AWS4_REQUEST = 'aws4_request';\n    const AWS4 = 'AWS4';\n    const X_AMZ_DATE = 'x-amz-date';\n    const X_AMZ_SECURITY_TOKEN = 'x-amz-security-token';\n    const HOST = 'host';\n    const AUTHORIZATION = 'Authorization';\n\n    function hash(value: any) {\n        return SHA256(value);\n    }\n\n    function hexEncode(value: any) {\n        return value.toString(encHex);\n    }\n\n    function hmac(secret: any, value: any) {\n        return HmacSHA256(value, secret); // eslint-disable-line\n    }\n\n    function buildCanonicalRequest(method: any, path: any, queryParams: any, headers: any, payload: any) {\n        return (\n            method +\n            '\\n' +\n            buildCanonicalUri(path) +\n            '\\n' +\n            buildCanonicalQueryString(queryParams) +\n            '\\n' +\n            buildCanonicalHeaders(headers) +\n            '\\n' +\n            buildCanonicalSignedHeaders(headers) +\n            '\\n' +\n            hexEncode(hash(payload))\n        );\n    }\n\n    function hashCanonicalRequest(request: any) {\n        return hexEncode(hash(request));\n    }\n\n    function buildCanonicalUri(uri: any) {\n        // eslint-disable-next-line no-constant-condition\n        return 1 ? UriEncode(uri) : encodeURI(uri);\n    }\n\n    //! code from: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html\n    //! '*' '+' '!' 같은 특수 문자가 들어갈 경우 인증 에러 발생할 수 있음.\n    function UriEncode(input: any, encodeSlash = false) {\n        const result = [];\n        // const toHexUTF8 = (str: any) => {\n        //     //TOOD - '한글' 인코딩시 utf8 으로 안하는듯.\n        //     str = str || '';\n        //     let hex = '';\n        //     for (let i = 0; i < str.length; i++) {\n        //         hex += '%' + str.charCodeAt(i).toString(16).toUpperCase();\n        //     }\n        //     return hex;\n        // };\n        for (let i = 0; i < input.length; i++) {\n            const ch = input.charAt(i);\n            if (\n                (ch >= 'A' && ch <= 'Z') ||\n                (ch >= 'a' && ch <= 'z') ||\n                (ch >= '0' && ch <= '9') ||\n                ch == '_' ||\n                ch == '-' ||\n                ch == '~' ||\n                ch == '.'\n            ) {\n                result.push(ch);\n            } else if (ch == '*') {\n                //TODO - encodeURIComponent()에서 인코딩이 안되서, 강제로 인코딩됨.\n                result.push('%2A');\n            } else if (ch == '!') {\n                //TODO - encodeURIComponent()에서 인코딩이 안되서, 강제로 인코딩됨.\n                result.push('%21');\n            } else if (ch == '(') {\n                //TODO - encodeURIComponent()에서 인코딩이 안되서, 강제로 인코딩됨.\n                result.push('%28');\n            } else if (ch == ')') {\n                //TODO - encodeURIComponent()에서 인코딩이 안되서, 강제로 인코딩됨.\n                result.push('%29');\n            } else if (ch == '/') {\n                result.push(encodeSlash ? '%2F' : ch);\n            } else {\n                // result.push(1 ? hexEncode(ch) : toHexUTF8(ch));\n                result.push(encodeURIComponent(ch));\n            }\n        }\n        // console.log('! encode=',result.join('').toString(), '<-', input);\n        return result.join('').toString();\n    }\n\n    function buildCanonicalQueryString(queryParams: any) {\n        if (Object.keys(queryParams).length < 1) {\n            return '';\n        }\n\n        const sortedQueryParams = [];\n        for (const property in queryParams) {\n            if (Object.prototype.hasOwnProperty.call(queryParams, property)) {\n                sortedQueryParams.push(property);\n            }\n        }\n        sortedQueryParams.sort();\n\n        let canonicalQueryString = '';\n        for (let i = 0; i < sortedQueryParams.length; i++) {\n            canonicalQueryString +=\n                sortedQueryParams[i] +\n                '=' +\n                //FIX - encoding problem: A-Z, a-z, 0-9, hyphen ( - ), underscore ( _ ), period ( . ), and tilde ( ~ ).\n                // https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html.\n                // encodeURIComponent(queryParams[sortedQueryParams[i]]) +\n                urlencode(queryParams[sortedQueryParams[i]]) +\n                '&';\n        }\n        return canonicalQueryString.substr(0, canonicalQueryString.length - 1);\n    }\n\n    //code from https://www.codeproject.com/Articles/1016044/JavaScript-URL-encode-decode-and-escape\n    function urlencode(text: any) {\n        return encodeURIComponent(text)\n            .replace(/!/g, '%21')\n            .replace(/'/g, '%27')\n            .replace(/\\(/g, '%28')\n            .replace(/\\)/g, '%29')\n            .replace(/\\*/g, '%2A')\n            .replace(/%20/g, '%20');\n    }\n\n    // function urldecode(text: any) {\n    //     return decodeURIComponent((text + '').replace(/\\+/g, '%20'));\n    // }\n\n    function buildCanonicalHeaders(headers: any) {\n        let canonicalHeaders = '';\n        const sortedKeys = [];\n        for (const property in headers) {\n            if (Object.prototype.hasOwnProperty.call(headers, property)) {\n                sortedKeys.push(property);\n            }\n        }\n        sortedKeys.sort();\n\n        for (let i = 0; i < sortedKeys.length; i++) {\n            canonicalHeaders += sortedKeys[i].toLowerCase() + ':' + headers[sortedKeys[i]] + '\\n';\n        }\n        return canonicalHeaders;\n    }\n\n    function buildCanonicalSignedHeaders(headers: any) {\n        const sortedKeys = [];\n        for (const property in headers) {\n            if (Object.prototype.hasOwnProperty.call(headers, property)) {\n                sortedKeys.push(property.toLowerCase());\n            }\n        }\n        sortedKeys.sort();\n\n        return sortedKeys.join(';');\n    }\n\n    function buildStringToSign(datetime: any, credentialScope: any, hashedCanonicalRequest: any) {\n        return AWS_SHA_256 + '\\n' + datetime + '\\n' + credentialScope + '\\n' + hashedCanonicalRequest;\n    }\n\n    function buildCredentialScope(datetime: any, region: any, service: any) {\n        return datetime.substr(0, 8) + '/' + region + '/' + service + '/' + AWS4_REQUEST;\n    }\n\n    function calculateSigningKey(secretKey: any, datetime: any, region: any, service: any) {\n        return hmac(hmac(hmac(hmac(AWS4 + secretKey, datetime.substr(0, 8)), region), service), AWS4_REQUEST);\n    }\n\n    function calculateSignature(key: any, stringToSign: any) {\n        return hexEncode(hmac(key, stringToSign));\n    }\n\n    function buildAuthorizationHeader(accessKey: any, credentialScope: any, headers: any, signature: any) {\n        return (\n            AWS_SHA_256 +\n            ' Credential=' +\n            accessKey +\n            '/' +\n            credentialScope +\n            ', SignedHeaders=' +\n            buildCanonicalSignedHeaders(headers) +\n            ', Signature=' +\n            signature\n        );\n    }\n\n    const awsSigV4Client: { [key: string]: any } = {};\n\n    if (config.accessKey === undefined || config.secretKey === undefined) {\n        return awsSigV4Client;\n    }\n\n    awsSigV4Client.host = config.host;\n    awsSigV4Client.accessKey = config.accessKey;\n    awsSigV4Client.secretKey = config.secretKey;\n    awsSigV4Client.sessionToken = config.sessionToken;\n    awsSigV4Client.serviceName = config.serviceName || 'execute-api';\n    awsSigV4Client.region = config.region || 'ap-northeast-2';\n    awsSigV4Client.defaultAcceptType = config.defaultAcceptType || 'application/json';\n    awsSigV4Client.defaultContentType = config.defaultContentType || 'application/json';\n\n    const invokeUrl = config.endpoint;\n    const endpoint = /(^https?:\\/\\/[^/]+)/g.exec(invokeUrl)[1];\n    const pathComponent = invokeUrl.substring(endpoint.length);\n\n    awsSigV4Client.endpoint = endpoint;\n    awsSigV4Client.pathComponent = pathComponent;\n\n    awsSigV4Client.signRequest = function (request: any) {\n        const verb = request.method.toUpperCase();\n        const path = awsSigV4Client.pathComponent + request.path;\n        const queryParams = request.queryParams || {}; //{ ...request.queryParams };\n        const headers = request.headers || {}; //{ ...request.headers };\n\n        // If the user has not specified an override for Content type the use default\n        if (headers['Content-Type'] === undefined) {\n            headers['Content-Type'] = awsSigV4Client.defaultContentType;\n        }\n\n        // If the user has not specified an override for Accept type the use default\n        if (headers['Accept'] === undefined) {\n            headers['Accept'] = awsSigV4Client.defaultAcceptType;\n        }\n\n        let body = request.body || {}; //{ ...request.body };\n        // override request body and set to empty when signing GET requests\n        if (request.body === undefined || verb === 'GET') {\n            body = '';\n        } else {\n            body = body && typeof body === 'object' ? JSON.stringify(body) : body;\n        }\n\n        // If there is no body remove the content-type header so it is not\n        // included in SigV4 calculation\n        if (body === '' || body === undefined || body === null) {\n            delete headers['Content-Type'];\n        }\n\n        const datetime = new Date()\n            .toISOString()\n            .replace(/\\.\\d{3}Z$/, 'Z')\n            .replace(/[:-]|\\.\\d{3}/g, '');\n        headers[X_AMZ_DATE] = datetime;\n        // let parser = new URL(awsSigV4Client.endpoint);\n        // headers[HOST] = parser.hostname;\n        headers[HOST] = awsSigV4Client.host;\n\n        const canonicalRequest = buildCanonicalRequest(verb, path, queryParams, headers, body);\n        const hashedCanonicalRequest = hashCanonicalRequest(canonicalRequest);\n        const credentialScope = buildCredentialScope(datetime, awsSigV4Client.region, awsSigV4Client.serviceName);\n        const stringToSign = buildStringToSign(datetime, credentialScope, hashedCanonicalRequest);\n        const signingKey = calculateSigningKey(awsSigV4Client.secretKey, datetime, awsSigV4Client.region, awsSigV4Client.serviceName);\n        const signature = calculateSignature(signingKey, stringToSign);\n\n        headers[AUTHORIZATION] = buildAuthorizationHeader(awsSigV4Client.accessKey, credentialScope, headers, signature);\n        if (awsSigV4Client.sessionToken !== undefined && awsSigV4Client.sessionToken !== '') {\n            headers[X_AMZ_SECURITY_TOKEN] = awsSigV4Client.sessionToken;\n        }\n        delete headers[HOST];\n\n        let url = awsSigV4Client.endpoint + path;\n        const queryString = buildCanonicalQueryString(queryParams);\n        if (queryString !== '') {\n            url += '?' + queryString;\n        }\n\n        // Need to re-attach Content-Type if it is not specified at this point\n        if (headers['Content-Type'] === undefined) {\n            headers['Content-Type'] = awsSigV4Client.defaultContentType;\n        }\n\n        return {\n            headers: headers,\n            url: url,\n        };\n    };\n\n    return awsSigV4Client;\n};\n\nexport { sigV4Client };\n","import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { Body, Headers, HttpResponse, Params } from '../types';\nimport { AzureStorageService, USE_X_LEMON_IDENTITY_KEY, USE_X_LEMON_LANGUAGE_KEY } from '../token-storage';\n\n/**\n * Class to build and execute HTTP requests with AWS signing\n * @example\n * ```ts\n * const response: HttpResponse<OAuthResponse> = await new AzureHttpRequestBuilder({\n *     method: 'GET',\n *     baseURL: `https://api.lemoncloud.io/v1/oauth`,\n *  })\n *    .addHeaders({ Cookie: this.cookie })\n *    .setParams({ page: 0 })\n *    .execute();\n * ```\n */\nexport class AzureHttpRequestBuilder {\n    private axiosInstance: AxiosInstance;\n    private config: AxiosRequestConfig = {\n        headers: {\n            'Content-Type': 'application/json',\n        },\n        method: 'get',\n    };\n\n    /**\n     * Creates an instance of AWSHttpRequestBuilder.\n     * @param {AzureStorageService} tokenStorage - The AWS storage service for token management.\n     * @param {AxiosRequestConfig} config - The Axios request configuration.\n     * @throws {Error} If tokenStorage, method, or baseURL are not defined.\n     */\n    constructor(\n        private readonly tokenStorage: AzureStorageService,\n        config: AxiosRequestConfig\n    ) {\n        if (!tokenStorage) {\n            throw new Error('tokenStorage should be defined!');\n        }\n        if (!config.method) {\n            throw new Error('method should be defined!');\n        }\n        if (!config.baseURL) {\n            throw new Error('baseURL should be defined!');\n        }\n        this.config = { ...this.config, ...config };\n        this.axiosInstance = axios.create(this.config);\n    }\n\n    /**\n     * Sets the request headers.\n     * @param {Headers} headers - Headers to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setHeaders(headers: Headers): AzureHttpRequestBuilder {\n        this.config.headers = headers;\n        return this;\n    }\n\n    /**\n     * Sets the request parameters.\n     * @param {Params} params - Parameters to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setParams(params: Params): AzureHttpRequestBuilder {\n        this.config.params = params;\n        return this;\n    }\n\n    /**\n     * Sets the request body.\n     * @param {Body} data - Body data to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setBody(data: Body): AzureHttpRequestBuilder {\n        this.config.data = data;\n        return this;\n    }\n\n    /**\n     * Sets the request method.\n     * @param {string} method - HTTP method to set.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    setMethod(method: string): AzureHttpRequestBuilder {\n        this.config.method = method;\n        return this;\n    }\n\n    /**\n     * Adds additional headers to the request.\n     * @param {Headers} headers - Headers to add.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addHeaders(headers: Headers = {}): AzureHttpRequestBuilder {\n        this.config.headers = { ...this.config.headers, ...headers };\n        return this;\n    }\n\n    /**\n     * Adds additional Axios request configuration.\n     * @param {AxiosRequestConfig} config - The configuration to add.\n     * @returns {AWSHttpRequestBuilder} - Returns the current instance to allow method chaining.\n     */\n    addAxiosRequestConfig(config: AxiosRequestConfig): AzureHttpRequestBuilder {\n        this.config = { ...this.config, ...config };\n        return this;\n    }\n\n    /**\n     * Executes the HTTP request.\n     * @template T\n     * @returns {Promise<HttpResponse<T>>} - Promise containing the response.\n     * @throws {Error} If an error occurs during the request.\n     */\n    async execute<T>(): Promise<HttpResponse<T>> {\n        try {\n            await this.addCodeParams();\n            await this.addBearerTokenToHeader();\n            await this.addXLemonIdentityToHeader();\n            await this.addXLemonLanguageToHeader();\n            return await this.axiosInstance.request<T>(this.config);\n        } catch (error) {\n            throw error;\n        }\n    }\n    /**\n     * Adds code parameters to the request configuration.\n     * Retrieves the `hostKey` and `clientId` from the token storage and sets them as request parameters.\n     * @private\n     * @async\n     * @returns {Promise<void>} - A promise that resolves when the parameters are added.\n     */\n    private async addCodeParams(): Promise<void> {\n        const code = (await this.tokenStorage.getItem('host_key')) || '';\n        if (!code) {\n            return;\n        }\n        const clientId = (await this.tokenStorage.getItem('client_id')) || 'default';\n        const originParams = this.config.params || {};\n        this.setParams({ ...originParams, code, clientId });\n    }\n\n    /**\n     * Adds a Bearer token to the request headers.\n     * Retrieves the `identityToken` from the token storage and sets it as the `Authorization` header.\n     * @private\n     * @async\n     * @returns {Promise<void>} - A promise that resolves when the token is added.\n     */\n    private async addBearerTokenToHeader(): Promise<void> {\n        const identityToken = (await this.tokenStorage.getItem('identity_token')) || '';\n        if (!identityToken) {\n            return;\n        }\n        this.addHeaders({ Authorization: `Bearer ${identityToken}` });\n    }\n\n    /**\n     * Adds the x-lemon-identity token to the request headers if required.\n     * Checks if the `USE_X_LEMON_IDENTITY_KEY` is set in the token storage and, if true,\n     * retrieves the `identityToken` and sets it as the `x-lemon-identity` header.\n     * @private\n     * @async\n     * @returns {Promise<void>} - A promise that resolves when the token is added.\n     */\n    private async addXLemonIdentityToHeader(): Promise<void> {\n        const useXLemonIdentity = await this.tokenStorage.getItem(USE_X_LEMON_IDENTITY_KEY);\n        if (!useXLemonIdentity || useXLemonIdentity === 'false') {\n            return;\n        }\n        const identityToken = await this.tokenStorage.getItem('identity_token');\n        this.addHeaders({ 'x-lemon-identity': identityToken });\n    }\n\n    /**\n     * Adds the x-lemon-language header to the request if required.\n     * First checks if a language key is set in storage, then retrieves the corresponding language value.\n     * If both exist, adds the language as 'x-lemon-language' header.\n     * @private\n     * @async\n     * @returns {Promise<void>} - A promise that resolves when the language header is added.\n     */\n    private async addXLemonLanguageToHeader(): Promise<void> {\n        const languageKey = await this.tokenStorage.getItem(USE_X_LEMON_LANGUAGE_KEY);\n        if (!languageKey) {\n            return;\n        }\n\n        const language = await this.tokenStorage.getItem(languageKey);\n        if (!language) {\n            return;\n        }\n\n        this.addHeaders({ 'x-lemon-language': language });\n    }\n}\n","import { AzureWebCoreState, Body, HttpResponse, LemonOAuthToken, Params, WebCoreConfig, WebCoreService } from '../types';\nimport { AzureStorageService, USE_X_LEMON_IDENTITY_KEY, USE_X_LEMON_LANGUAGE_KEY } from '../token-storage';\nimport { LoggerService } from '../utils';\nimport axios, { AxiosInstance, AxiosRequestConfig } from 'axios';\nimport { AzureHttpRequestBuilder, HttpRequestBuilder } from '../http';\n\n/**\n * Class to handle Azure-specific web core operations.\n * Implements the WebCoreService interface.\n */\nexport class AzureWebCore implements WebCoreService {\n    private readonly tokenStorage: AzureStorageService;\n    private readonly logger: LoggerService;\n    private sharedAxiosInstance: AxiosInstance;\n\n    /**\n     * Creates an instance of AzureWebCore.\n     * @param {WebCoreConfig<'azure'>} config - The configuration for the Azure web core.\n     */\n    constructor(private readonly config: WebCoreConfig<'azure'>) {\n        this.logger = new LoggerService('AzureCore');\n        this.tokenStorage = new AzureStorageService(this.config);\n        this.sharedAxiosInstance = axios.create();\n    }\n\n    /**\n     * Initializes the Azure web core by checking for cached tokens.\n     * @returns {Promise<AzureWebCoreState>} - The state of the Azure web core after initialization.\n     */\n    async init(): Promise<AzureWebCoreState> {\n        const hasCachedToken = await this.tokenStorage.hasCachedToken();\n        if (!hasCachedToken) {\n            this.logger.warn('initialized without token!');\n            return 'no-token';\n        }\n\n        const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();\n        if (shouldRefreshToken) {\n            this.logger.info('initialized and refreshed token!');\n            // TODO: refresh azure token\n        }\n        this.logger.info('initialized with token!');\n        return 'has-token';\n    }\n\n    /**\n     * Retrieves the token storage service.\n     *\n     * @returns {AzureStorageService} - The storage service that manages OAuth tokens.\n     */\n    getTokenStorage(): AzureStorageService {\n        return this.tokenStorage;\n    }\n\n    /**\n     * Gets the shared axios instance\n     * @returns The shared axios instance\n     */\n    getSharedAxiosInstance(): AxiosInstance {\n        return this.sharedAxiosInstance;\n    }\n\n    /**\n     * Builds a request using HttpRequestBuilder without Credentials.\n     * @param {AxiosRequestConfig} config - The Axios request configuration.\n     * @returns {HttpRequestBuilder} - The HttpRequestBuilder instance.\n     */\n    buildRequest(config: AxiosRequestConfig): HttpRequestBuilder {\n        return new HttpRequestBuilder(config, this.sharedAxiosInstance);\n    }\n\n    /**\n     * Executes a HTTP request without Credentials.\n     * @template T\n     * @param {string} method - The HTTP method.\n     * @param {string} url - The request URL.\n     * @param {Params} [params={}] - The request parameters.\n     * @param {Body} body - The request body.\n     * @param {AxiosRequestConfig} [config] - Additional Axios request configuration.\n     * @returns {Promise<HttpResponse<T>>} - The Axios response.\n     */\n    async request<T>(method: string, url: string, params: Params = {}, body?: Body, config?: AxiosRequestConfig): Promise<HttpResponse<T>> {\n        const builder = new HttpRequestBuilder({\n            method,\n            baseURL: url,\n            params,\n        });\n        if (body) {\n            builder.setBody(body);\n        }\n        if (config) {\n            builder.addAxiosRequestConfig(config);\n        }\n        return await builder.execute();\n    }\n\n    /**\n     * Builds a signed request using the provided Axios configuration.\n     * @param {AxiosRequestConfig} config - The Axios request configuration.\n     * @returns {AzureHttpRequestBuilder} - The request builder for the signed request.\n     */\n    buildSignedRequest(config: AxiosRequestConfig): AzureHttpRequestBuilder {\n        return new AzureHttpRequestBuilder(this.tokenStorage, config);\n    }\n\n    /**\n     * Executes a signed HTTP request.\n     * @template T\n     * @param {string} method - The HTTP method to use for the request.\n     * @param {string} url - The URL for the request.\n     * @param {Params} [params={}] - The URL parameters for the request.\n     * @param {Body} [body] - The request body.\n     * @param {AxiosRequestConfig} [config] - Additional Axios request configuration.\n     * @returns {Promise<HttpResponse<T>>} - The Axios response.\n     */\n    async signedRequest<T>(\n        method: string,\n        url: string,\n        params: Params = {},\n        body?: Body,\n        config?: AxiosRequestConfig\n    ): Promise<HttpResponse<T>> {\n        const builder = new AzureHttpRequestBuilder(this.tokenStorage, {\n            method,\n            baseURL: url,\n            params,\n        });\n        if (body) {\n            builder.setBody(body);\n        }\n        if (config) {\n            builder.addAxiosRequestConfig(config);\n        }\n        return await builder.execute();\n    }\n\n    /**\n     * Retrieves all saved tokens from the storage.\n     * @returns {Promise<{ [key: string]: string }>} - An object containing all saved tokens.\n     */\n    getSavedToken(): Promise<{ [key: string]: string }> {\n        return this.tokenStorage.getAllItems();\n    }\n\n    /**\n     * Checks if the user is authenticated.\n     * @returns {Promise<boolean>} - True if authenticated, otherwise false.\n     */\n    async isAuthenticated(): Promise<boolean> {\n        const hasCachedToken = await this.tokenStorage.hasCachedToken();\n        if (!hasCachedToken) {\n            return false;\n        }\n\n        const shouldRefreshToken = await this.tokenStorage.shouldRefreshToken();\n        if (shouldRefreshToken) {\n            this.logger.info('should refresh token!');\n            // TODO: refresh azure token\n            return true;\n        }\n        return true;\n    }\n\n    /**\n     * Saves an OAuth token to the storage.\n     * @param {LemonOAuthToken} token - The OAuth token to save.\n     * @returns {Promise<void>} - A promise that resolves when the token is saved.\n     */\n    async saveOAuthToken(token: LemonOAuthToken): Promise<void> {\n        return await this.tokenStorage.saveOAuthToken(token);\n    }\n\n    /**\n     * Logs the user out by clearing the OAuth token from the storage.\n     * @returns {Promise<void>} - A promise that resolves when the user is logged out.\n     */\n    async logout(): Promise<void> {\n        await this.tokenStorage.clearOAuthToken();\n        return;\n    }\n\n    /**\n     * Sets whether to use the x-lemon-identity header.\n     * @param {boolean} use - True to use the x-lemon-identity header, otherwise false.\n     * @returns {Promise<void>} - A promise that resolves when the setting is updated.\n     */\n    async setUseXLemonIdentity(use: boolean): Promise<void> {\n        await this.tokenStorage.setItem(USE_X_LEMON_IDENTITY_KEY, `${use}`);\n    }\n\n    /**\n     * Sets whether to use the X-Lemon-Language header with a specific key.\n     * @param {boolean} use - Whether to use the X-Lemon-Language header.\n     * @param {string} key? - The storage key to set.\n     */\n    async setUseXLemonLanguage(use: boolean, key?: string): Promise<void> {\n        if (!use) {\n            await this.tokenStorage.setItem(USE_X_LEMON_LANGUAGE_KEY, '');\n            return;\n        }\n        if (!key) {\n            return;\n        }\n        await this.tokenStorage.setItem(USE_X_LEMON_LANGUAGE_KEY, key);\n    }\n}\n","import { AWSWebCore } from './aws-web.core';\nimport { AzureWebCore } from './azure-web.core';\nimport { CloudProvider, WebCoreConfig, WebCoreConstructor, WebCoreService, WebCoreServiceMap } from '../types';\n\n/**\n * A map of cloud provider to their corresponding WebCore constructor.\n */\nconst webCoreMap: Record<CloudProvider, WebCoreConstructor<WebCoreService>> = {\n    aws: AWSWebCore,\n    azure: AzureWebCore,\n};\n\n/**\n * A factory class to create instances of {@link WebCoreService} based on the cloud provider.\n */\nexport class WebCoreFactory {\n    /**\n     * Creates an instance of {@link WebCoreService} based on the provided configuration.\n     *\n     * @param config The configuration for the WebCore service.\n     * @returns An instance of {@link WebCoreService} specific to the cloud provider.\n     * @throws Error if the cloud provider is not supported.\n     */\n    static create<T extends CloudProvider>(config: WebCoreConfig<T>): WebCoreServiceMap[T] {\n        const { cloud } = config;\n        const ServiceConstructor = webCoreMap[cloud] as WebCoreConstructor<WebCoreServiceMap[T]>;\n        if (!ServiceConstructor) {\n            throw new Error('Unsupported cloud provider');\n        }\n        return new ServiceConstructor(config);\n    }\n}\n"]}