diff --git a/sdk/translation/ai-translation-text-rest/CHANGELOG.md b/sdk/translation/ai-translation-text-rest/CHANGELOG.md index d2330ef8be25..e5cf384b071a 100644 --- a/sdk/translation/ai-translation-text-rest/CHANGELOG.md +++ b/sdk/translation/ai-translation-text-rest/CHANGELOG.md @@ -1,12 +1,3 @@ -# Release History +## 1.0.0-beta.1 (2023-06-06) -## 1.0.0-beta.1 (2023-04-18) -Initial release - -### Features Added -- Added support for Text Translation - [Translate API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate) -- Added support for Text Transliteration - [Transliterate API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-transliterate) -- Added support for Finding Sentence Boundaries - [FindSentenceBoundaries API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-break-sentence) -- Added support for Getting the Supported Languages - [GetLanguages API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-languages) -- Added support for Looking up the Dictionary Entries - [LookupDictionaryEntries API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-lookup) -- Added support for Looking up the Dictionary Examples - [LookupDictionaryExamples API](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-examples) + - Initial Release diff --git a/sdk/translation/ai-translation-text-rest/README.md b/sdk/translation/ai-translation-text-rest/README.md index 4ae823571c54..d755f08c0174 100644 --- a/sdk/translation/ai-translation-text-rest/README.md +++ b/sdk/translation/ai-translation-text-rest/README.md @@ -22,8 +22,9 @@ Dictionary example Returns grammatical structure and context examples for the so Key links: +- [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-text-rest) - [Package (NPM)](https://www.npmjs.com/package/@azure-rest/ai-translation-text) -- [API reference documentation](https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference) +- [API reference documentation](https://docs.microsoft.com/javascript/api/@azure-rest/ai-translation-text?view=azure-node-preview) - [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-text-rest/samples) ## Getting started @@ -31,262 +32,36 @@ Key links: ### Currently supported environments - LTS versions of Node.js -- Latest versions of Edge, Chrome, Safar and Firefox ### Prerequisites -- An existing Translator service or Cognitive Services resource. +- You must have an [Azure subscription](https://azure.microsoft.com/free/) to use this package. ### Install the `@azure-rest/ai-translation-text` package -Install the Azure Text Translation REST client library for JavaScript with `npm`: +Install the Azure TextTranslation REST client REST client library for JavaScript with `npm`: ```bash npm install @azure-rest/ai-translation-text ``` -#### Create a Translator service resource +### Create and authenticate a `TextTranslationClient` -You can create Translator resource following [Create a Translator resource][translator_resource_create]. +To use an [Azure Active Directory (AAD) token credential](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-a-pre-fetched-access-token), +provide an instance of the desired credential type obtained from the +[@azure/identity](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) library. -### Browser support +To authenticate with AAD, you must first `npm` install [`@azure/identity`](https://www.npmjs.com/package/@azure/identity) -#### JavaScript Bundle +After setup, you can choose which type of [credential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#credentials) from `@azure/identity` to use. +As an example, [DefaultAzureCredential](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/identity/identity#defaultazurecredential) +can be used to authenticate the client. -To use this client library in the browser, first you need to use a bundler. For details on how to do this, please refer to our [bundling documentation](https://aka.ms/AzureSDKBundling). - -### Authenticate the client - -Interaction with the service using the client library begins with creating an instance of the [TextTranslationClient][translator_client_class] class. You will need an **API key** or `TokenCredential` to instantiate a client object. For more information regarding authenticating with cognitive services, see [Authenticate requests to Translator Service][translator_auth]. - -#### Get an API key - -You can get the `endpoint`, `API key` and `Region` from the Cognitive Services resource or Translator service resource information in the [Azure Portal][azure_portal]. - -Alternatively, use the [Azure CLI][azure_cli] snippet below to get the API key from the Translator service resource. - -```PowerShell -az cognitiveservices account keys list --resource-group --name -``` - -### Create a `TextTranslationClient` using an API key and Region credential - -Once you have the value for the API key and Region, create an `TranslatorCredential`. - -With the value of the `TranslatorCredential` you can create the [TextTranslationClient][translator_client_class]: - -```javascript -const translateCedential = new TranslatorCredential(apiKey, region); -const translationClient = TextTranslationClient(endpoint, translateCedential); -``` - -## Examples - -The following section provides several code snippets using the `client` [created above](#create-a-texttranslationclient-using-an-api-key-and-region-credential), and covers the main features present in this client library. - -### Get Supported Languages - -Gets the set of languages currently supported by other operations of the Translator. - -```javascript -const langResponse = await translationClient.path("/languages").get(); - -if (isUnexpected(langResponse)) { - throw langResponse.body; -} - -const languages = langResponse.body; - -if (languages.translation) { - console.log("Translated languages:"); - for (const key in languages.translation) { - const translationLanguage = languages.translation[key]; - console.log(`${key} -- name: ${translationLanguage.name} (${translationLanguage.nativeName})`); - } -} - -if (languages.transliteration) { - console.log("Transliteration languages:"); - for (const key in languages.transliteration) { - const transliterationLanguage = languages.transliteration[key]; - console.log( - `${key} -- name: ${transliterationLanguage.name} (${transliterationLanguage.nativeName})` - ); - } -} - -if (languages.dictionary) { - console.log("Dictionary languages:"); - for (const key in languages.dictionary) { - const dictionaryLanguage = languages.dictionary[key]; - console.log( - `${key} -- name: ${dictionaryLanguage.name} (${dictionaryLanguage.nativeName}), supported target languages count: ${dictionaryLanguage.translations.length}` - ); - } -} -``` - -Please refer to the service documentation for a conceptual discussion of [languages][languages_doc]. - -### Translate - -Renders single source-language text to multiple target-language texts with a single request. - -```javascript -const inputText = [{ text: "This is a test." }]; -const parameters = { - to: "cs", - from: "en", -}; -const translateResponse = await translationClient.path("/translate").post({ - body: inputText, - queryParameters: parameters, -}); - -if (isUnexpected(translateResponse)) { - throw translateResponse.body; -} - -const translations = translateResponse.body; -for (const translation of translations) { - console.log( - `Text was translated to: '${translation?.translations[0]?.to}' and the result is: '${translation?.translations[0]?.text}'.` - ); -} -``` - -Please refer to the service documentation for a conceptual discussion of [translate][translate_doc]. - -### Transliterate - -Converts characters or letters of a source language to the corresponding characters or letters of a target language. - -```javascript -const inputText = [{ text: "这是个测试。" }]; -const parameters = { - language: "zh-Hans", - fromScript: "Hans", - toScript: "Latn", -}; -const transliterateResponse = await translationClient.path("/transliterate").post({ - body: inputText, - queryParameters: parameters, -}); - -if (isUnexpected(transliterateResponse)) { - throw transliterateResponse.body; -} - -const translations = transliterateResponse.body; -for (const transliteration of translations) { - console.log( - `Input text was transliterated to '${transliteration?.script}' script. Transliterated text: '${transliteration?.text}'.` - ); -} -``` - -Please refer to the service documentation for a conceptual discussion of [transliterate][transliterate_doc]. - -### Break Sentence - -Identifies the positioning of sentence boundaries in a piece of text. - -```javascript -const inputText = [{ text: "zhè shì gè cè shì。" }]; -const parameters = { - language: "zh-Hans", - script: "Latn", -}; -const breakSentenceResponse = await translationClient.path("/breaksentence").post({ - body: inputText, - queryParameters: parameters, -}); - -if (isUnexpected(breakSentenceResponse)) { - throw breakSentenceResponse.body; -} - -const breakSentences = breakSentenceResponse.body; -for (const breakSentence of breakSentences) { - console.log(`The detected sentece boundaries: '${breakSentence?.sentLen.join(", ")}'.`); -} -``` - -Please refer to the service documentation for a conceptual discussion of [break sentence][breaksentence_doc]. - -### Dictionary Lookup - -Returns equivalent words for the source term in the target language. - -```javascript -const inputText = [{ text: "fly" }]; -const parameters = { - to: "es", - from: "en", -}; -const dictionaryResponse = await translationClient.path("/dictionary/lookup").post({ - body: inputText, - queryParameters: parameters, -}); - -if (isUnexpected(dictionaryResponse)) { - throw dictionaryResponse.body; -} - -const dictionaryEntries = dictionaryResponse.body; -for (const dictionaryEntry of dictionaryEntries) { - console.log( - `For the given input ${dictionaryEntry?.translations?.length} entries were found in the dictionary.` - ); - console.log( - `First entry: '${dictionaryEntry?.translations[0]?.displayTarget}', confidence: ${dictionaryEntry?.translations[0]?.confidence}.` - ); -} -``` - -Please refer to the service documentation for a conceptual discussion of [dictionary lookup][dictionarylookup_doc]. - -### Dictionary Examples - -Returns grammatical structure and context examples for the source term and target term pair. - -```javascript -const inputText = [{ text: "fly", translation: "volar" }]; -const parameters = { - to: "es", - from: "en", -}; -const dictionaryResponse = await translationClient.path("/dictionary/examples").post({ - body: inputText, - queryParameters: parameters, -}); - -if (isUnexpected(dictionaryResponse)) { - throw dictionaryResponse.body; -} - -const dictionaryExamples = dictionaryResponse.body; -for (const dictionaryExample of dictionaryExamples) { - console.log( - `For the given input ${dictionaryExample?.examples?.length} examples were found in the dictionary.` - ); - const firstExample = dictionaryExample?.examples[0]; - console.log( - `Example: '${firstExample.targetPrefix + firstExample.targetTerm + firstExample.targetSuffix}'.` - ); -} -``` - -Please refer to the service documentation for a conceptual discussion of [dictionary examples][dictionaryexamples_doc]. +Set the values of the client ID, tenant ID, and client secret of the AAD application as environment variables: +AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET ## Troubleshooting -When you interact with the Translator Service using the TextTranslator client library, errors returned by the Translator service correspond to the same HTTP status codes returned for REST API requests. - -For example, if you submit a translation request without a target translate language, a `400` error is returned, indicating "Bad Request". - -You can find the different error codes returned by the service in the [Service Documentation][service_errors]. - ### Logging Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`: @@ -298,16 +73,3 @@ setLogLevel("info"); ``` For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger). - -[azure_cli]: https://docs.microsoft.com/cli/azure -[azure_portal]: https://portal.azure.com -[translator_resource_create]: https://learn.microsoft.com/azure/cognitive-services/Translator/create-translator-resource -[translator_auth]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference#authentication -[service_errors]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-reference#errors -[translator_client_class]: https://github.com/azure/azure-sdk-for-js/blob/main/sdk/translation/ai-translation-text-rest/src/generated/clientDefinitions.ts -[languages_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-languages -[translate_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-translate -[transliterate_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-transliterate -[breaksentence_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-break-sentence -[dictionarylookup_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-lookup -[dictionaryexamples_doc]: https://learn.microsoft.com/azure/cognitive-services/translator/reference/v3-0-dictionary-examples diff --git a/sdk/translation/ai-translation-text-rest/api-extractor.json b/sdk/translation/ai-translation-text-rest/api-extractor.json index ebfd2ff45058..cd2ce34eeb03 100644 --- a/sdk/translation/ai-translation-text-rest/api-extractor.json +++ b/sdk/translation/ai-translation-text-rest/api-extractor.json @@ -28,4 +28,4 @@ } } } -} +} \ No newline at end of file diff --git a/sdk/translation/ai-translation-text-rest/karma.conf.js b/sdk/translation/ai-translation-text-rest/karma.conf.js index efc32a66afa6..a9d5f1b5fc59 100644 --- a/sdk/translation/ai-translation-text-rest/karma.conf.js +++ b/sdk/translation/ai-translation-text-rest/karma.conf.js @@ -53,13 +53,11 @@ module.exports = function (config) { envPreprocessor: [ "TEST_MODE", - "TEXT_TRANSLATION_TENANT_ID", - "TEXT_TRANSLATION_CLIENT_ID", - "TEXT_TRANSLATION_CLIENT_SECRET", - "TEXT_TRANSLATION_ENDPOINT", - "TEXT_TRANSLATION_CUSTOM_ENDPOINT", - "TEXT_TRANSLATION_API_KEY", - "TEXT_TRANSLATION_REGION", + "ENDPOINT", + "AZURE_CLIENT_SECRET", + "AZURE_CLIENT_ID", + "AZURE_TENANT_ID", + "SUBSCRIPTION_ID", "RECORDINGS_RELATIVE_PATH", ], diff --git a/sdk/translation/ai-translation-text-rest/package.json b/sdk/translation/ai-translation-text-rest/package.json index 0512843164d4..062d1ce5db44 100644 --- a/sdk/translation/ai-translation-text-rest/package.json +++ b/sdk/translation/ai-translation-text-rest/package.json @@ -3,17 +3,14 @@ "sdk-type": "client", "author": "Microsoft Corporation", "version": "1.0.0-beta.1", - "description": "An isomorphic client library for the Azure Cognitive Translator Service", - "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-text-rest/README.md", + "description": "Microsoft Translation Text", "keywords": [ "node", "azure", "cloud", "typescript", "browser", - "isomorphic", - "translate", - "translation" + "isomorphic" ], "license": "MIT", "main": "dist/index.js", @@ -28,35 +25,24 @@ "dist-esm/src/", "types/ai-translation-text.d.ts", "README.md", - "CHANGELOG.md", - "LICENSE" + "LICENSE", + "review/*" ], "engines": { "node": ">=14.0.0" }, - "//sampleConfiguration": { - "productName": "Azure Text Translation Service", - "productSlugs": [ - "azure", - "azure-cognitive-services", - "azure-translator" - ], - "requiredResources": { - "Translator resource instance": "https://learn.microsoft.com/azure/cognitive-services/Translator/create-translator-resource" - } - }, "scripts": { "audit": "node ../../../common/scripts/rush-audit.js && rimraf node_modules package-lock.json && npm i --package-lock-only 2>&1 && npm audit", "build:browser": "tsc -p . && cross-env ONLY_BROWSER=true rollup -c 2>&1", "build:node": "tsc -p . && cross-env ONLY_NODE=true rollup -c 2>&1", - "build:samples": "echo Obsolete.", + "build:samples": "echo skipped.", "build:test": "tsc -p . && dev-tool run bundle", "build:debug": "tsc -p . && dev-tool run bundle && api-extractor run --local", - "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", + "check-format": "prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", "clean": "rimraf dist dist-browser dist-esm test-dist temp types *.tgz *.log", - "execute:samples": "dev-tool samples run samples-dev", + "execute:samples": "echo skipped", "extract-api": "rimraf review && mkdirp ./review && api-extractor run --local", - "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"", + "format": "prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"*.{js,json}\" \"test/**/*.ts\"", "generate:client": "echo skipped", "integration-test:browser": "dev-tool run test:browser", "integration-test:node": "dev-tool run test:node-js-input -- --timeout 5000000 'dist-esm/test/**/*.spec.js'", @@ -76,7 +62,7 @@ "autoPublish": false, "dependencies": { "@azure/core-auth": "^1.3.0", - "@azure-rest/core-client": "^1.1.0", + "@azure-rest/core-client": "^1.1.3", "@azure/core-rest-pipeline": "^1.8.0", "@azure/logger": "^1.0.0", "tslib": "^2.2.0" @@ -115,12 +101,16 @@ "karma": "^6.2.0", "nyc": "^15.0.0" }, + "homepage": "https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-text-rest/README.md", "//metadata": { "constantPaths": [ { - "path": "src/customClient.ts", + "path": "src/textTranslation.ts", "prefix": "userAgentInfo" } ] + }, + "browser": { + "./dist-esm/test/public/utils/env.js": "./dist-esm/test/public/utils/env.browser.js" } -} +} \ No newline at end of file diff --git a/sdk/translation/ai-translation-text-rest/review/ai-translation-text.api.md b/sdk/translation/ai-translation-text-rest/review/ai-translation-text.api.md index 022ea3f935a3..27654e15cc36 100644 --- a/sdk/translation/ai-translation-text-rest/review/ai-translation-text.api.md +++ b/sdk/translation/ai-translation-text-rest/review/ai-translation-text.api.md @@ -7,12 +7,10 @@ import { Client } from '@azure-rest/core-client'; import { ClientOptions } from '@azure-rest/core-client'; import { HttpResponse } from '@azure-rest/core-client'; -import { KeyCredential } from '@azure/core-auth'; import { RawHttpHeaders } from '@azure/core-rest-pipeline'; import { RawHttpHeadersInput } from '@azure/core-rest-pipeline'; import { RequestParameters } from '@azure-rest/core-client'; import { StreamableMethod } from '@azure-rest/core-client'; -import { TokenCredential } from '@azure/core-auth'; // @public export interface BackTranslationOutput { @@ -40,7 +38,7 @@ export interface CommonScriptModelOutput { } // @public -function createClient(endpoint: undefined | string, credential?: undefined | TranslatorCredential | KeyCredential | TokenCredential, options?: ClientOptions): TextTranslationClient; +function createClient(endpoint: string, options?: ClientOptions): TextTranslationClient; export default createClient; // @public @@ -514,10 +512,10 @@ export interface TranslateQueryParamProperties { fromScript?: string; includeAlignment?: boolean; includeSentenceLength?: boolean; - profanityAction?: "NoAction" | "Marked" | "Deleted"; - profanityMarker?: "Asterisk" | "Tag"; + profanityAction?: string; + profanityMarker?: string; suggestedFrom?: string; - textType?: "plain" | "html"; + textType?: string; to: string; toScript?: string; } @@ -535,15 +533,7 @@ export interface TranslationOutput { sentLen?: SentenceLengthOutput; text: string; to: string; - transliteration?: TransliterationOutput; -} - -// @public (undocumented) -export interface TranslatorCredential { - // (undocumented) - key: string; - // (undocumented) - region: string; + transliteration?: TransliteratedTextOutput; } // @public @@ -631,12 +621,6 @@ export interface TransliterationLanguageOutput { scripts: Array; } -// @public -export interface TransliterationOutput { - script: string; - text: string; -} - // (No @packageDocumentation comment for this package) ``` diff --git a/sdk/translation/ai-translation-text-rest/src/authentication.ts b/sdk/translation/ai-translation-text-rest/src/authentication.ts deleted file mode 100644 index 215b69b023fe..000000000000 --- a/sdk/translation/ai-translation-text-rest/src/authentication.ts +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import { AzureKeyCredential } from "@azure/core-auth"; -import { - PipelinePolicy, - PipelineRequest, - PipelineResponse, - SendRequest, -} from "@azure/core-rest-pipeline"; - -const APIM_KEY_HEADER_NAME = "Ocp-Apim-Subscription-Key"; -const APIM_REGION_HEADER_NAME = "Ocp-Apim-Subscription-Region"; - -export interface TranslatorCredential { - key: string; - region: string; -} - -export class TranslatorAuthenticationPolicy implements PipelinePolicy { - name: string = "TranslatorAuthenticationPolicy"; - credential: TranslatorCredential; - - constructor(credential: TranslatorCredential) { - this.credential = credential; - } - - sendRequest(request: PipelineRequest, next: SendRequest): Promise { - request.headers.set(APIM_KEY_HEADER_NAME, this.credential.key); - request.headers.set(APIM_REGION_HEADER_NAME, this.credential.region); - - return next(request); - } -} - -export class TranslatorAzureKeyAuthenticationPolicy implements PipelinePolicy { - name: string = "TranslatorAzureKeyAuthenticationPolicy"; - credential: AzureKeyCredential; - - constructor(credential: AzureKeyCredential) { - this.credential = credential; - } - - sendRequest(request: PipelineRequest, next: SendRequest): Promise { - request.headers.set(APIM_KEY_HEADER_NAME, this.credential.key); - - return next(request); - } -} diff --git a/sdk/translation/ai-translation-text-rest/src/generated/clientDefinitions.ts b/sdk/translation/ai-translation-text-rest/src/clientDefinitions.ts similarity index 100% rename from sdk/translation/ai-translation-text-rest/src/generated/clientDefinitions.ts rename to sdk/translation/ai-translation-text-rest/src/clientDefinitions.ts diff --git a/sdk/translation/ai-translation-text-rest/src/customClient.ts b/sdk/translation/ai-translation-text-rest/src/customClient.ts deleted file mode 100644 index 427d551a393f..000000000000 --- a/sdk/translation/ai-translation-text-rest/src/customClient.ts +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. - -import { getClient, ClientOptions } from "@azure-rest/core-client"; -import * as coreRestPipeline from "@azure/core-rest-pipeline"; -import { PipelineRequest, PipelineResponse, SendRequest } from "@azure/core-rest-pipeline"; -import { TextTranslationClient } from "./generated/clientDefinitions"; -import { - TranslatorCredential, - TranslatorAuthenticationPolicy, - TranslatorAzureKeyAuthenticationPolicy, -} from "./authentication"; -import { AzureKeyCredential, KeyCredential, TokenCredential } from "@azure/core-auth"; - -const DEFAULT_SCOPE = "https://cognitiveservices.azure.com/.default"; -const DEFAULT_ENPOINT = "https://api.cognitive.microsofttranslator.com"; -const PLATFORM_HOST = "cognitiveservices"; -const PLATFORM_PATH = "/translator/text/v3.0"; - -function isKeyCredential(credential: any): credential is KeyCredential { - return (credential as KeyCredential)?.key !== undefined; -} - -function isTranslatorKeyCredential(credential: any): credential is TranslatorCredential { - return (credential as TranslatorCredential)?.key !== undefined; -} - -/** Policy that sets the api-version (or equivalent) to reflect the library version. */ -const apiVersionPolicy = { - name: "MTApiVersionPolicy", - async sendRequest(request: PipelineRequest, next: SendRequest): Promise { - const param = request.url.split("?"); - if (param.length > 1) { - const newParams = param[1].split("&"); - newParams.push("api-version=3.0"); - request.url = param[0] + "?" + newParams.join("&"); - } else { - // no query parameters in request url - request.url = param[0] + "?api-version=3.0"; - } - return next(request); - }, -}; - -/** - * Initialize a new instance of `TextTranslationClient` - * @param endpoint type: string, Supported Text Translation endpoints (protocol and hostname, for example: - * https://api.cognitive.microsofttranslator.com). - * @param options type: ClientOptions, the parameter for all optional parameters - */ -export default function createClient( - endpoint: undefined | string, - credential: undefined | TranslatorCredential | KeyCredential | TokenCredential = undefined, - options: ClientOptions = {} -): TextTranslationClient { - let serviceEndpoint: string; - if (!endpoint) { - serviceEndpoint = DEFAULT_ENPOINT; - } else if (endpoint.toLowerCase().indexOf(PLATFORM_HOST) !== -1) { - serviceEndpoint = `${endpoint}${PLATFORM_PATH}`; - } else { - serviceEndpoint = endpoint; - } - - const baseUrl = options.baseUrl ?? `${serviceEndpoint}`; - - const userAgentInfo = `azsdk-js-ai-translation-text-rest/1.0.0-beta.1`; - const userAgentPrefix = - options.userAgentOptions && options.userAgentOptions.userAgentPrefix - ? `${options.userAgentOptions.userAgentPrefix} ${userAgentInfo}` - : `${userAgentInfo}`; - options = { - ...options, - userAgentOptions: { - userAgentPrefix, - }, - }; - - const client = getClient(baseUrl, options) as TextTranslationClient; - client.pipeline.addPolicy(apiVersionPolicy); - - if (isTranslatorKeyCredential(credential)) { - const mtAuthneticationPolicy = new TranslatorAuthenticationPolicy( - credential as TranslatorCredential - ); - client.pipeline.addPolicy(mtAuthneticationPolicy); - } else if (isKeyCredential(credential)) { - const mtKeyAuthenticationPolicy = new TranslatorAzureKeyAuthenticationPolicy( - credential as AzureKeyCredential - ); - client.pipeline.addPolicy(mtKeyAuthenticationPolicy); - } else if (credential) { - client.pipeline.addPolicy( - coreRestPipeline.bearerTokenAuthenticationPolicy({ - credential: credential as TokenCredential, - scopes: DEFAULT_SCOPE, - }) - ); - } - - return client; -} diff --git a/sdk/translation/ai-translation-text-rest/src/index.ts b/sdk/translation/ai-translation-text-rest/src/index.ts index e6aee809f150..3aab800e51fa 100644 --- a/sdk/translation/ai-translation-text-rest/src/index.ts +++ b/sdk/translation/ai-translation-text-rest/src/index.ts @@ -1,16 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT license. -import TextTranslation from "./customClient"; +import TextTranslation from "./textTranslation"; -export * from "./customClient"; -export * from "./generated/parameters"; -export * from "./generated/responses"; -export * from "./generated/clientDefinitions"; -export * from "./generated/isUnexpected"; -export * from "./generated/models"; -export * from "./generated/outputModels"; -export * from "./generated/serializeHelper"; -export { TranslatorCredential } from "./authentication"; +export * from "./textTranslation"; +export * from "./parameters"; +export * from "./responses"; +export * from "./clientDefinitions"; +export * from "./isUnexpected"; +export * from "./models"; +export * from "./outputModels"; +export * from "./serializeHelper"; export default TextTranslation; diff --git a/sdk/translation/ai-translation-text-rest/src/generated/isUnexpected.ts b/sdk/translation/ai-translation-text-rest/src/isUnexpected.ts similarity index 100% rename from sdk/translation/ai-translation-text-rest/src/generated/isUnexpected.ts rename to sdk/translation/ai-translation-text-rest/src/isUnexpected.ts diff --git a/sdk/translation/ai-translation-text-rest/src/logger.ts b/sdk/translation/ai-translation-text-rest/src/logger.ts new file mode 100644 index 000000000000..d2cdd4fac447 --- /dev/null +++ b/sdk/translation/ai-translation-text-rest/src/logger.ts @@ -0,0 +1,5 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { createClientLogger } from "@azure/logger"; +export const logger = createClientLogger("ai-translation-text"); diff --git a/sdk/translation/ai-translation-text-rest/src/generated/models.ts b/sdk/translation/ai-translation-text-rest/src/models.ts similarity index 100% rename from sdk/translation/ai-translation-text-rest/src/generated/models.ts rename to sdk/translation/ai-translation-text-rest/src/models.ts diff --git a/sdk/translation/ai-translation-text-rest/src/generated/outputModels.ts b/sdk/translation/ai-translation-text-rest/src/outputModels.ts similarity index 96% rename from sdk/translation/ai-translation-text-rest/src/generated/outputModels.ts rename to sdk/translation/ai-translation-text-rest/src/outputModels.ts index fe0a66447bd2..66a1b2fd05e4 100644 --- a/sdk/translation/ai-translation-text-rest/src/generated/outputModels.ts +++ b/sdk/translation/ai-translation-text-rest/src/outputModels.ts @@ -88,7 +88,7 @@ export interface ErrorResponseOutput { /** Error details as returned by Translator Service. */ export interface ErrorDetailsOutput { - /** Number indetifier of the error. */ + /** Number identifier of the error. */ code: number; /** Human readable error description. */ message: string; @@ -130,19 +130,19 @@ export interface TranslationOutput { /** A string giving the translated text. */ text: string; /** An object giving the translated text in the script specified by the toScript parameter. */ - transliteration?: TransliterationOutput; + transliteration?: TransliteratedTextOutput; /** Alignment information. */ alignment?: TranslatedTextAlignmentOutput; /** Sentence boundaries in the input and output texts. */ sentLen?: SentenceLengthOutput; } -/** An object giving the translated text in the script specified by the toScript parameter. */ -export interface TransliterationOutput { - /** A string specifying the target script. */ - script: string; - /** A string giving the translated text in the target script. */ +/** Transliterated text element. */ +export interface TransliteratedTextOutput { + /** A string which is the result of converting the input string to the output script. */ text: string; + /** A string specifying the script used in the output. */ + script: string; } /** Alignment information object. */ @@ -178,15 +178,7 @@ export interface SourceTextOutput { text: string; } -/** Transliterated text element. */ -export interface TransliteratedTextOutput { - /** A string which is the result of converting the input string to the output script. */ - text: string; - /** A string specifying the script used in the output. */ - script: string; -} - -/** Elemented containing break sentence result. */ +/** Item containing break sentence result. */ export interface BreakSentenceItemOutput { /** The detectedLanguage property is only present in the result object when language auto-detection is requested. */ detectedLanguage?: DetectedLanguageOutput; diff --git a/sdk/translation/ai-translation-text-rest/src/generated/parameters.ts b/sdk/translation/ai-translation-text-rest/src/parameters.ts similarity index 96% rename from sdk/translation/ai-translation-text-rest/src/generated/parameters.ts rename to sdk/translation/ai-translation-text-rest/src/parameters.ts index 9e15c9f65453..07c5171388c4 100644 --- a/sdk/translation/ai-translation-text-rest/src/generated/parameters.ts +++ b/sdk/translation/ai-translation-text-rest/src/parameters.ts @@ -53,7 +53,7 @@ export interface TranslateHeaders { } export interface TranslateBodyParam { - /** Array of the text to be translated. */ + /** Defines the content of the request */ body: Array; } @@ -78,7 +78,7 @@ export interface TranslateQueryParamProperties { * Defines whether the text being translated is plain text or HTML text. Any HTML needs to be a well-formed, * complete element. Possible values are: plain (default) or html. */ - textType?: "plain" | "html"; + textType?: string; /** * A string specifying the category (domain) of the translation. This parameter is used to get translations * from a customized system built with Custom Translator. Add the Category ID from your Custom Translator @@ -89,12 +89,12 @@ export interface TranslateQueryParamProperties { * Specifies how profanities should be treated in translations. * Possible values are: NoAction (default), Marked or Deleted. */ - profanityAction?: "NoAction" | "Marked" | "Deleted"; + profanityAction?: string; /** * Specifies how profanities should be marked in translations. * Possible values are: Asterisk (default) or Tag. */ - profanityMarker?: "Asterisk" | "Tag"; + profanityMarker?: string; /** * Specifies whether to include alignment projection from source text to translated text. * Possible values are: true or false (default). @@ -147,7 +147,7 @@ export interface TransliterateHeaders { } export interface TransliterateBodyParam { - /** Array of the text to be transliterated. */ + /** Defines the content of the request */ body: Array; } @@ -189,7 +189,7 @@ export interface FindSentenceBoundariesHeaders { } export interface FindSentenceBoundariesBodyParam { - /** Array of the text for which values the sentence boundaries will be calculated. */ + /** Defines the content of the request */ body: Array; } @@ -226,7 +226,7 @@ export interface LookupDictionaryEntriesHeaders { } export interface LookupDictionaryEntriesBodyParam { - /** Array of the text to be sent to dictionary. */ + /** Defines the content of the request */ body: Array; } @@ -263,7 +263,7 @@ export interface LookupDictionaryExamplesHeaders { } export interface LookupDictionaryExamplesBodyParam { - /** Array of the text to be sent to dictionary. */ + /** Defines the content of the request */ body: Array; } diff --git a/sdk/translation/ai-translation-text-rest/src/generated/responses.ts b/sdk/translation/ai-translation-text-rest/src/responses.ts similarity index 100% rename from sdk/translation/ai-translation-text-rest/src/generated/responses.ts rename to sdk/translation/ai-translation-text-rest/src/responses.ts diff --git a/sdk/translation/ai-translation-text-rest/src/generated/serializeHelper.ts b/sdk/translation/ai-translation-text-rest/src/serializeHelper.ts similarity index 100% rename from sdk/translation/ai-translation-text-rest/src/generated/serializeHelper.ts rename to sdk/translation/ai-translation-text-rest/src/serializeHelper.ts diff --git a/sdk/translation/ai-translation-text-rest/src/textTranslation.ts b/sdk/translation/ai-translation-text-rest/src/textTranslation.ts new file mode 100644 index 000000000000..8c5226e506c8 --- /dev/null +++ b/sdk/translation/ai-translation-text-rest/src/textTranslation.ts @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { getClient, ClientOptions } from "@azure-rest/core-client"; +import { logger } from "./logger"; +import { TextTranslationClient } from "./clientDefinitions"; + +/** + * Initialize a new instance of `TextTranslationClient` + * @param endpoint - Supported Text Translation endpoints (protocol and hostname, for example: + * https://api.cognitive.microsofttranslator.com). + * @param options - the parameter for all optional parameters + */ +export default function createClient( + endpoint: string, + options: ClientOptions = {} +): TextTranslationClient { + const baseUrl = options.baseUrl ?? `${endpoint}`; + options.apiVersion = options.apiVersion ?? "3.0"; + + const userAgentInfo = `azsdk-js-ai-translation-text-rest/1.0.0-beta.1`; + const userAgentPrefix = + options.userAgentOptions && options.userAgentOptions.userAgentPrefix + ? `${options.userAgentOptions.userAgentPrefix} ${userAgentInfo}` + : `${userAgentInfo}`; + options = { + ...options, + userAgentOptions: { + userAgentPrefix, + }, + loggingOptions: { + logger: options.loggingOptions?.logger ?? logger.info, + }, + }; + + const client = getClient(baseUrl, options) as TextTranslationClient; + + return client; +} diff --git a/sdk/translation/ai-translation-text-rest/test/public/sampleTest.spec.ts b/sdk/translation/ai-translation-text-rest/test/public/sampleTest.spec.ts new file mode 100644 index 000000000000..bce68e428645 --- /dev/null +++ b/sdk/translation/ai-translation-text-rest/test/public/sampleTest.spec.ts @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import { Recorder } from "@azure-tools/test-recorder"; +import { assert } from "chai"; +import { createRecorder } from "./utils/recordedClient"; +import { Context } from "mocha"; + +describe("My test", () => { + let recorder: Recorder; + + beforeEach(async function (this: Context) { + recorder = await createRecorder(this); + }); + + afterEach(async function () { + await recorder.stop(); + }); + + it("sample test", async function () { + assert.equal(1, 1); + }); +}); diff --git a/sdk/translation/ai-translation-text-rest/test/public/utils/env.browser.ts b/sdk/translation/ai-translation-text-rest/test/public/utils/env.browser.ts new file mode 100644 index 000000000000..fd2aca680c7b --- /dev/null +++ b/sdk/translation/ai-translation-text-rest/test/public/utils/env.browser.ts @@ -0,0 +1,2 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. diff --git a/sdk/translation/ai-translation-text-rest/test/public/utils/env.ts b/sdk/translation/ai-translation-text-rest/test/public/utils/env.ts new file mode 100644 index 000000000000..0e06855b73ae --- /dev/null +++ b/sdk/translation/ai-translation-text-rest/test/public/utils/env.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +import * as dotenv from "dotenv"; + +dotenv.config(); diff --git a/sdk/translation/ai-translation-text-rest/test/public/utils/recordedClient.ts b/sdk/translation/ai-translation-text-rest/test/public/utils/recordedClient.ts index 0ed463f59cdf..6cc58bc15e11 100644 --- a/sdk/translation/ai-translation-text-rest/test/public/utils/recordedClient.ts +++ b/sdk/translation/ai-translation-text-rest/test/public/utils/recordedClient.ts @@ -2,123 +2,28 @@ // Licensed under the MIT license. import { Context } from "mocha"; -import { - Recorder, - RecorderStartOptions, - isPlaybackMode, - assertEnvironmentVariable, -} from "@azure-tools/test-recorder"; -import { StaticAccessTokenCredential } from "./StaticAccessTokenCredential"; -import createTextTranslationClient, { - TranslatorCredential, - TextTranslationClient, -} from "../../../src"; -import { ClientOptions } from "@azure-rest/core-client"; -import { createDefaultHttpClient, createPipelineRequest } from "@azure/core-rest-pipeline"; -import { TokenCredential } from "@azure/core-auth"; +import { Recorder, RecorderStartOptions } from "@azure-tools/test-recorder"; +import "./env"; const envSetupForPlayback: Record = { - TEXT_TRANSLATION_API_KEY: "fakeapikey", - TEXT_TRANSLATION_ENDPOINT: "https://fakeEndpoint.cognitive.microsofttranslator.com", - TEXT_TRANSLATION_CUSTOM_ENDPOINT: "https://fakeCustomEndpoint.cognitiveservices.azure.com", - TEXT_TRANSLATION_REGION: "fakeregion", + ENDPOINT: "https://endpoint", + AZURE_CLIENT_ID: "azure_client_id", + AZURE_CLIENT_SECRET: "azure_client_secret", + AZURE_TENANT_ID: "88888888-8888-8888-8888-888888888888", + SUBSCRIPTION_ID: "azure_subscription_id", }; const recorderEnvSetup: RecorderStartOptions = { envSetupForPlayback, }; -export async function startRecorder(context: Context): Promise { +/** + * creates the recorder and reads the environment variables from the `.env` file. + * Should be called first in the test suite to make sure environment variables are + * read before they are being used. + */ +export async function createRecorder(context: Context): Promise { const recorder = new Recorder(context.currentTest); await recorder.start(recorderEnvSetup); return recorder; } - -export async function createTranslationClient(options: { - recorder?: Recorder; - clientOptions?: ClientOptions; -}): Promise { - const { recorder, clientOptions = {} } = options; - const updatedOptions = recorder ? recorder.configureClientOptions(clientOptions) : clientOptions; - const endpoint = assertEnvironmentVariable("TEXT_TRANSLATION_ENDPOINT"); - const apikey = assertEnvironmentVariable("TEXT_TRANSLATION_API_KEY"); - const region = assertEnvironmentVariable("TEXT_TRANSLATION_REGION"); - - const translatorCredential: TranslatorCredential = { - key: apikey, - region, - }; - const client = createTextTranslationClient(endpoint, translatorCredential, updatedOptions); - return client; -} - -export async function createCustomTranslationClient(options: { - recorder?: Recorder; - clientOptions?: ClientOptions; -}): Promise { - const { recorder, clientOptions = {} } = options; - const updatedOptions = recorder ? recorder.configureClientOptions(clientOptions) : clientOptions; - const customEndpoint = assertEnvironmentVariable("TEXT_TRANSLATION_CUSTOM_ENDPOINT"); - const apikey = assertEnvironmentVariable("TEXT_TRANSLATION_API_KEY"); - const region = assertEnvironmentVariable("TEXT_TRANSLATION_REGION"); - - const translatorCredential: TranslatorCredential = { - key: apikey, - region, - }; - const client = createTextTranslationClient(customEndpoint, translatorCredential, updatedOptions); - return client; -} - -export async function createLanguageClient(options: { - recorder?: Recorder; - clientOptions?: ClientOptions; -}): Promise { - const { recorder, clientOptions = {} } = options; - const updatedOptions = recorder ? recorder.configureClientOptions(clientOptions) : clientOptions; - const endpoint = assertEnvironmentVariable("TEXT_TRANSLATION_ENDPOINT"); - return createTextTranslationClient(endpoint, undefined, updatedOptions); -} - -export async function createTokenTranslationClient(options: { - recorder?: Recorder; - clientOptions?: ClientOptions; -}): Promise { - const { recorder, clientOptions = {} } = options; - const updatedOptions = recorder ? recorder.configureClientOptions(clientOptions) : clientOptions; - const endpoint = assertEnvironmentVariable("TEXT_TRANSLATION_ENDPOINT"); - const apikey = assertEnvironmentVariable("TEXT_TRANSLATION_API_KEY"); - const region = assertEnvironmentVariable("TEXT_TRANSLATION_REGION"); - - const issueTokenURL: string = - "https://" + - region + - ".api.cognitive.microsoft.com/sts/v1.0/issueToken?Subscription-Key=" + - apikey; - let credential: TokenCredential; - if (isPlaybackMode()) { - credential = createMockToken(); - } else { - const tokenClient = createDefaultHttpClient(); - const request = createPipelineRequest({ - url: issueTokenURL, - method: "POST", - }); - request.allowInsecureConnection = true; - const response = await tokenClient.sendRequest(request); - const token: string = response.bodyAsText!; - credential = new StaticAccessTokenCredential(token); - } - const client = createTextTranslationClient(endpoint, credential, updatedOptions); - return client; -} - -export function createMockToken(): { - getToken: (_scopes: string) => Promise<{ token: string; expiresOnTimestamp: number }>; -} { - return { - getToken: async (_scopes: string) => { - return { token: "testToken", expiresOnTimestamp: 11111 }; - }, - }; -} diff --git a/sdk/translation/ai-translation-text-rest/tsconfig.json b/sdk/translation/ai-translation-text-rest/tsconfig.json index 0a7a9f618e4f..d5bf593423c9 100644 --- a/sdk/translation/ai-translation-text-rest/tsconfig.json +++ b/sdk/translation/ai-translation-text-rest/tsconfig.json @@ -2,10 +2,10 @@ "extends": "../../../tsconfig.package", "compilerOptions": { "outDir": "./dist-esm", - "declarationDir": "./types", - "paths": { - "@azure-rest/ai-translation-text": ["./src/index"] - } + "declarationDir": "./types" }, - "include": ["src/**/*.ts", "test/**/*.ts", "samples-dev/**/*.ts"] -} + "include": [ + "src/**/*.ts", + "./test/**/*.ts" + ] +} \ No newline at end of file diff --git a/sdk/translation/ci.yml b/sdk/translation/ci.yml index d5491a3469ce..8b042756d32b 100644 --- a/sdk/translation/ci.yml +++ b/sdk/translation/ci.yml @@ -1,30 +1,30 @@ # NOTE: Please refer to https://aka.ms/azsdk/engsys/ci-yaml before editing this file. - + trigger: branches: include: - - main - - hotfix/* - - release/* - - restapi* + - main + - hotfix/* + - release/* + - restapi* paths: include: - - sdk/translation/ci.yml - - sdk/translation/ai-translation-text-rest/ - + - sdk/translation/ci.yml + - sdk/translation/ai-translation-text-rest/ pr: branches: include: - - main - - feature/* - - hotfix/* - - release/* - - restapi* + - main + - feature/* + - hotfix/* + - release/* + - restapi* + exclude: + - feature/v4 paths: include: - - sdk/translation/ci.yml - - sdk/translation/ai-translation-text-rest/ - + - sdk/translation/ci.yml + - sdk/translation/ai-translation-text-rest/ extends: template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml parameters: