{"version":3,"sources":["src/common.speech/SynthesisRestAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,aAAa,EAIhB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAY,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAG5E;;;;GAIG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,kBAAkB,CAAkB;gBAEzB,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,eAAe;IAgB7E;;;;;;OAMG;IACU,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAQxE;;;;;;;OAOG;YACW,gBAAgB;CA+BjC","file":"SynthesisRestAdapter.d.ts","sourcesContent":["import {\r\n    IRequestOptions,\r\n    IRestResponse,\r\n    RestConfigBase,\r\n    RestMessageAdapter,\r\n    RestRequestType,\r\n} from \"../common.browser/Exports.js\";\r\nimport {\r\n    PropertyId,\r\n} from \"../sdk/Exports.js\";\r\nimport { ConnectionFactoryBase } from \"./ConnectionFactoryBase.js\";\r\nimport { AuthInfo, IAuthentication, SynthesizerConfig } from \"./Exports.js\";\r\nimport { HeaderNames } from \"./HeaderNames.js\";\r\n\r\n/**\r\n * Implements methods for speech synthesis classes, sending requests to endpoint\r\n * and parsing response into expected format\r\n * @class SynthesisRestAdapter\r\n */\r\nexport class SynthesisRestAdapter {\r\n    private privRestAdapter: RestMessageAdapter;\r\n    private privUri: string | undefined;\r\n    private privEndpoint: string;\r\n    private privIsCustomEndpoint: boolean;\r\n    private privAuthentication: IAuthentication;\r\n\r\n    public constructor(config: SynthesizerConfig, authentication: IAuthentication) {\r\n\r\n        let endpoint = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Endpoint, undefined);\r\n        this.privIsCustomEndpoint = !!endpoint;\r\n        if (!endpoint) {\r\n            const region: string = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Region, \"westus\");\r\n            const hostSuffix: string = ConnectionFactoryBase.getHostSuffix(region);\r\n            endpoint = config.parameters.getProperty(PropertyId.SpeechServiceConnection_Host, `https://${region}.tts.speech${hostSuffix}`);\r\n        }\r\n        this.privEndpoint = endpoint;\r\n\r\n        const options: IRequestOptions = RestConfigBase.requestOptions;\r\n        this.privRestAdapter = new RestMessageAdapter(options);\r\n        this.privAuthentication = authentication;\r\n    }\r\n\r\n    /**\r\n     * Sends list voices request to endpoint.\r\n     * @function\r\n     * @public\r\n     * @param connectionId - guid for connectionId\r\n     * @returns {Promise<IRestResponse>} rest response to status request\r\n     */\r\n    public async getVoicesList(connectionId: string): Promise<IRestResponse> {\r\n        const uri: string = await this.getVoicesListUri();\r\n        this.privRestAdapter.setHeaders(HeaderNames.ConnectionId, connectionId);\r\n        const authInfo: AuthInfo = await this.privAuthentication.fetch(connectionId);\r\n        this.privRestAdapter.setHeaders(authInfo.headerName, authInfo.token);\r\n        return this.privRestAdapter.request(RestRequestType.Get, uri);\r\n    }\r\n\r\n    /**\r\n     * Builds (and caches) the voices/list URI. When the caller supplied a custom endpoint with no path\r\n     * (e.g. a custom-domain or private-link host via fromEndpoint), the host may not serve the voices/list\r\n     * route directly and AAD token auth requires the regional host with the ocp-apim-custom-domain-name\r\n     * query parameter. In that case we resolve the service redirect (which is exposed on the synthesis\r\n     * route) to discover the regional host and custom-domain parameter, then retarget it to the\r\n     * voices/list path, keeping the http(s) scheme for this REST call.\r\n     */\r\n    private async getVoicesListUri(): Promise<string> {\r\n        if (this.privUri !== undefined) {\r\n            return this.privUri;\r\n        }\r\n\r\n        const voicesPath = \"/cognitiveservices/voices/list\";\r\n        const endpointUrl: URL = new URL(this.privEndpoint);\r\n        const pathName: string = endpointUrl.pathname;\r\n        const hasNoPath: boolean = pathName === \"\" || pathName === \"/\";\r\n\r\n        if (this.privIsCustomEndpoint && hasNoPath) {\r\n            // The redirect handler is exposed on the synthesis route. Resolving it returns the regional\r\n            // host together with the Ocp-Apim-Custom-Domain-Name parameter (or, when no redirect applies,\r\n            // falls back to the original host). We then point the resolved URL at the voices/list path.\r\n            endpointUrl.pathname = \"/tts/cognitiveservices/websocket/v1\";\r\n            const resolved: string = await ConnectionFactoryBase.getRedirectUrlFromEndpoint(endpointUrl.toString(), false);\r\n            const resolvedUrl: URL = new URL(resolved);\r\n            resolvedUrl.pathname = voicesPath;\r\n            resolvedUrl.searchParams.delete(\"GenerateRedirectResponse\");\r\n            this.privUri = resolvedUrl.toString();\r\n        } else if (hasNoPath) {\r\n            endpointUrl.pathname = voicesPath;\r\n            this.privUri = endpointUrl.toString();\r\n        } else {\r\n            // The endpoint already carries a path; preserve the legacy behavior of appending the voices route.\r\n            this.privUri = `${this.privEndpoint}${voicesPath}`;\r\n        }\r\n\r\n        return this.privUri;\r\n    }\r\n\r\n}\r\n"]}