Skip to content

Commit 0fe0332

Browse files
hive-botclaude
andcommitted
feat: accept an options object in rephraseText()
Add RephraseTextOptions with writingStyle, tone and extraBodyParameters, accepted as the third argument of rephraseText(). Passing the writing style and tone positionally is deprecated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent c0d1811 commit 0fe0332

5 files changed

Lines changed: 133 additions & 4 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6161
- Added `translateDocumentWaitUntilDone()`, which polls a document translation
6262
until it is done and resolves with the final `DocumentStatus`, or rejects with
6363
a `DeepLError` if the translation fails.
64+
- Added the `RephraseTextOptions` type with `writingStyle`, `tone` and
65+
`extraBodyParameters`. `rephraseText()` accepts it as its third argument.
66+
`extraBodyParameters` are added to the request body and override parameters
67+
of the same name.
6468

6569
### Changed
6670
- `getSourceLanguages()`, `getTargetLanguages()`, and `getGlossaryLanguagePairs()` now call the
@@ -83,6 +87,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8387
- `isDocumentTranslationComplete()` is deprecated; use
8488
`translateDocumentWaitUntilDone()` instead. It will be removed in the next
8589
major version.
90+
- Passing the writing style and tone of `rephraseText()` as positional
91+
arguments is deprecated; pass a `RephraseTextOptions` object as the third
92+
argument instead. The positional form will be removed in the next major
93+
version.
8694

8795
### Fixed
8896
- `downloadTranslationMemoryExport()` no longer hangs on Node 16 and 17 when the output file

‎README.md‎

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,12 @@ To rephrase text, call `rephraseText()`. The first argument is a string containi
11291129

11301130
The second argument is the target language code. Language codes are **case-insensitive** strings, for example, `'de'`, `'fr'`, `'en'`. The target language code can also be `null` to enable auto-detection of the target language.
11311131

1132-
The last two arguments, `writingStyle` and `tone`, are optional and specify the writing style and tone of the rephrased text. Possible values are defined in the `WritingStyle` and `WritingTone` enums.
1132+
The third argument is optional and is a `RephraseTextOptions` object with the following properties:
1133+
- `writingStyle`: the writing style of the rephrased text. Possible values are defined in the `WritingStyle` enum.
1134+
- `tone`: the tone of the rephrased text. Possible values are defined in the `WritingTone` enum. The API accepts either `writingStyle` or `tone` in a request, not both.
1135+
- `extraBodyParameters`: extra parameters to add to the request body. They can override parameters set by the library.
1136+
1137+
Passing the writing style and tone as the third and fourth arguments, for example `rephraseText(text, 'en', WritingStyle.ACADEMIC)`, is deprecated and will be removed in the next major version.
11331138

11341139
`rephraseText()` returns a Promise that fulfills with an `Improvement` object or an array of `Improvement` objects corresponding to your input text(s). The `Improvement` object has the following properties:
11351140
- `text`: the rephrased text,
@@ -1138,15 +1143,16 @@ The last two arguments, `writingStyle` and `tone`, are optional and specify the
11381143

11391144
```javascript
11401145
// Rephrasing a text in academic style:
1141-
const rephrasedResult = await deepLClient.rephraseText('This is an example text.', 'en', WritingStyle.ACADEMIC);
1146+
const rephrasedResult = await deepLClient.rephraseText('This is an example text.', 'en', {
1147+
writingStyle: WritingStyle.ACADEMIC,
1148+
});
11421149
console.log(rephrasedResult.text); // The rephrased text in academic style
11431150

11441151
// Rephrasing multiple texts in a friendly tone:
11451152
const rephrasedTexts = await deepLClient.rephraseText(
11461153
['How are you?', 'What are you doing today?'],
11471154
'de',
1148-
null,
1149-
WritingTone.FRIENDLY,
1155+
{ tone: WritingTone.FRIENDLY },
11501156
);
11511157
console.log(rephrasedTexts[0].text); // The rephrased text for "How are you?" in a friendly tone
11521158
console.log(rephrasedTexts[1].text); // The rephrased text for "What are you doing today?" in a friendly tone

‎src/deeplClient.ts‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ import {
3535
LanguageResourceName,
3636
GetLanguagesForResourceOptions,
3737
LanguageSupport,
38+
RephraseTextOptions,
39+
RequestParameters,
3840
} from './types';
3941
import {
4042
parseMultilingualGlossaryDictionaryInfo,
@@ -145,12 +147,64 @@ export class DeepLClient extends Translator {
145147
super(authKey, options);
146148
}
147149

150+
/**
151+
* @deprecated Pass the writing style in a {@link RephraseTextOptions} object as the third
152+
* argument instead. The positional parameters will be removed in the next major version.
153+
*/
154+
async rephraseText<T extends string | string[]>(
155+
texts: T,
156+
targetLang: string | null | undefined,
157+
writingStyle: string,
158+
tone?: string | null,
159+
): Promise<T extends string ? WriteResult : WriteResult[]>;
160+
/**
161+
* Rephrases the given text(s), optionally in a writing style or tone.
162+
* @param texts Text to rephrase, or an array of texts.
163+
* @param targetLang Target language code, or `null` to keep the language of the input text.
164+
* @param options Rephrasing options, see {@link RephraseTextOptions}. Passing the writing
165+
* style as a string here is deprecated.
166+
* @param tone Deprecated, use {@link RephraseTextOptions.tone}.
167+
* @return Promise of a {@link WriteResult}, or an array of them if `texts` is an array.
168+
* @throws {ArgumentError} If an options object is combined with a `tone` argument.
169+
* @throws {DeepLError} If any error occurs while communicating with the DeepL API.
170+
*/
171+
async rephraseText<T extends string | string[]>(
172+
texts: T,
173+
targetLang?: string | null,
174+
// string and the undefined tone keep subclass overrides with the old positional
175+
// signature compiling; a null tone would make string styles skip the deprecated overload
176+
options?: RephraseTextOptions | string | null,
177+
tone?: undefined,
178+
): Promise<T extends string ? WriteResult : WriteResult[]>;
179+
/**
180+
* @deprecated Pass the writing style and tone in a {@link RephraseTextOptions} object as the
181+
* third argument instead. The positional parameters will be removed in the next major version.
182+
*/
148183
async rephraseText<T extends string | string[]>(
149184
texts: T,
150185
targetLang?: string | null,
151186
writingStyle?: string | null,
152187
tone?: string | null,
188+
): Promise<T extends string ? WriteResult : WriteResult[]>;
189+
async rephraseText<T extends string | string[]>(
190+
texts: T,
191+
targetLang?: string | null,
192+
writingStyleOrOptions?: string | RephraseTextOptions | null,
193+
tone?: string | null,
153194
): Promise<T extends string ? WriteResult : WriteResult[]> {
195+
let writingStyle: string | null | undefined;
196+
let extraBodyParameters: RequestParameters | undefined;
197+
if (typeof writingStyleOrOptions === 'object' && writingStyleOrOptions !== null) {
198+
if (tone !== undefined && tone !== null) {
199+
throw new ArgumentError(
200+
'tone cannot be passed as a separate argument together with an options object',
201+
);
202+
}
203+
({ writingStyle, tone, extraBodyParameters } = writingStyleOrOptions);
204+
} else {
205+
writingStyle = writingStyleOrOptions;
206+
}
207+
154208
const data = new URLSearchParams();
155209
if (targetLang) {
156210
data.append('target_lang', targetLang);
@@ -165,6 +219,11 @@ export class DeepLClient extends Translator {
165219
}
166220

167221
const singular = appendTextsAndReturnIsSingular(data, texts);
222+
if (extraBodyParameters !== undefined) {
223+
for (const paramName in extraBodyParameters) {
224+
data.set(paramName, extraBodyParameters[paramName]);
225+
}
226+
}
168227
const { statusCode, content } = await this.httpClient.sendRequestWithBackoff<string>(
169228
'POST',
170229
'/v2/write/rephrase',

‎src/types.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,22 @@ export interface TextResult {
787787
readonly modelTypeUsed?: string;
788788
}
789789

790+
/**
791+
* Options that can be specified when rephrasing text with `rephraseText()`.
792+
*/
793+
export interface RephraseTextOptions {
794+
/** Writing style of the rephrased text, see `WritingStyle`. Cannot be combined with `tone`. */
795+
writingStyle?: string;
796+
/** Tone of the rephrased text, see `WritingTone`. Cannot be combined with `writingStyle`. */
797+
tone?: string;
798+
/**
799+
* Extra parameters to be added to the request body.
800+
* Keys in this object will be added to the request body, and can override built-in parameters.
801+
* This is mostly used by DeepL employees to test functionality, or for beta programs.
802+
*/
803+
extraBodyParameters?: RequestParameters;
804+
}
805+
790806
/**
791807
* Holds the result of a text rephrasing request.
792808
*/

‎tests/offline/rephraseText.test.ts‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import nock from 'nock';
66

77
import { WritingStyle, WritingTone } from '../../src/deeplClient';
8+
import { ArgumentError } from '../../src/errors';
89
import { makeDeeplClient, serverUrl } from './client';
910

1011
const rephrased = {
@@ -49,6 +50,45 @@ describe('DeepLClient.rephraseText', () => {
4950
},
5051
);
5152

53+
it('sends the writing style, tone and extra body parameters of an options object', async () => {
54+
nock(serverUrl)
55+
.post('/v2/write/rephrase', {
56+
text: 'abc',
57+
target_lang: 'en',
58+
writing_style: 'business',
59+
tone: 'confident',
60+
extra: 'x',
61+
})
62+
.reply(200, rephrased);
63+
64+
await makeDeeplClient().rephraseText('abc', 'en', {
65+
writingStyle: WritingStyle.BUSINESS,
66+
tone: WritingTone.CONFIDENT,
67+
extraBodyParameters: { extra: 'x' },
68+
});
69+
});
70+
71+
it('lets extra body parameters override built-in parameters', async () => {
72+
nock(serverUrl)
73+
.post('/v2/write/rephrase', { text: 'abc', target_lang: 'fr' })
74+
.reply(200, rephrased);
75+
76+
await makeDeeplClient().rephraseText('abc', 'en', {
77+
extraBodyParameters: { target_lang: 'fr' },
78+
});
79+
});
80+
81+
it('throws ArgumentError when an options object is combined with a tone argument', async () => {
82+
const client = makeDeeplClient();
83+
// The overloads reject this at compile time; JavaScript callers can still pass it
84+
const rephraseText = client.rephraseText.bind(client) as (
85+
...args: unknown[]
86+
) => Promise<unknown>;
87+
await expect(rephraseText('abc', 'en', {}, WritingTone.FRIENDLY)).rejects.toThrow(
88+
ArgumentError,
89+
);
90+
});
91+
5292
it('sends every text of an array and returns an array of results', async () => {
5393
nock(serverUrl)
5494
.post('/v2/write/rephrase', { text: ['a', 'b'], target_lang: 'de' })

0 commit comments

Comments
 (0)