@saplingai/sapling-js 1.0.45 → 1.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -76,6 +76,14 @@ You should see something like the following output:
76
76
  }
77
77
  ```
78
78
 
79
+ If you only need to apply the corrections, pass `includeErrorCategories: false`. The API then
80
+ skips error classification (faster and lighter), and each edit comes back without
81
+ `error_type`, `general_error_type` or classifier-generated descriptions:
82
+
83
+ ```javascript
84
+ client.edits('I have a apple!', undefined, { includeErrorCategories: false, autoApply: true })
85
+ ```
86
+
79
87
  ### Text classification
80
88
 
81
89
  Zero-shot classification with your own labels (plain names or `{ name, description }` objects, 2–20):
@@ -94,6 +102,103 @@ client
94
102
  })
95
103
  ```
96
104
 
105
+ ### AI content detection
106
+
107
+ ```javascript
108
+ const { data } = await client.aidetect(documentText);
109
+ // { score: 0.05, ai_fraction: 0.51, text: '...', version: '...',
110
+ // sentence_scores: [{ sentence: '...', score: 0.97, start: 0, end: 112 }, ...],
111
+ // tokens: [...], token_probs: [...] }
112
+ ```
113
+
114
+ `score` (0–1) rates the whole text, so a document that is only partly AI-written can score low;
115
+ `ai_fraction` is the share of the text in sentences scoring ≥ 0.5 (null when nothing could be
116
+ scored), which flags those documents. `sentence_scores` use the same model and 0.5 threshold, and
117
+ `start`/`end` index `text` in Unicode code points (`end` exclusive) — slice with
118
+ `Array.from(text).slice(start, end).join('')` if the text may contain emoji. A response may also
119
+ carry an advisory `language` (`{ code, name, confidence }`) when the text is confidently
120
+ identified; the detector is trained on English. Options: `sent_scores` (default true),
121
+ `score_string` (HTML heatmap), `version` (pin a model). Pass an array of 1–10 texts for the batch
122
+ form, which answers `{ results: [...] }` in input order.
123
+
124
+ ### Rephrase, sentiment and readability statistics
125
+
126
+ ```javascript
127
+ const { data: rephrased } = await client.rephrase('hey, can u send it over', {
128
+ mapping: 'informal_to_formal', // default 'paraphrase'
129
+ num_results: 3, // 1–8, default 5
130
+ });
131
+ // { results: [{ hash: '...', original: '...', replacement: 'Could you please send it over?',
132
+ // rephrase_type: 'informal_to_formal', model_version: '...' }, ...] }
133
+
134
+ const { data: sentiment } = await client.sentiment('Love the new release. The install was painful.');
135
+ // { overall: [[0.71, 'POSITIVE'], [0.29, 'NEGATIVE']],
136
+ // results: [[[0.99, 'POSITIVE']], [[0.95, 'NEGATIVE'], ...]],
137
+ // sents: ['Love the new release.', 'The install was painful.'] }
138
+
139
+ const { data: stats } = await client.statistics(documentText, { lang: 'en' });
140
+ // { chars: 1234, words: 210, sentences: 12, reading_time_sec: 47.55, reading_time_min: 1,
141
+ // readability: 8.2, readability_scores: { flesch_reading_ease: 64.1, gunning_fog: 10.3, ... } }
142
+ ```
143
+
144
+ `rephrase()` mappings: `paraphrase`, `reword`, `expand`, `shorten`, `summarize`,
145
+ `passive_to_active`, `active_to_passive`, `informal_to_formal`, `formal_to_informal`,
146
+ `sentence_split`, `generate_title`, `generate_acronym`, `generate_meta_description`,
147
+ `switch_tone` (with `tone_mapping`) and `switch_tense` (with `tense_mapping`). Sentiment labels
148
+ are `POSITIVE`, `NEUTRAL` and `NEGATIVE`, as `[probability, label]` pairs, most likely first;
149
+ a text with no sentences (markup or punctuation only) gets a 204 with an empty body (`data === ''`),
150
+ and one the API cannot split into sentences gets a 200 with `[]`.
151
+ `statistics()` is unbilled; `lang` is one of `en`, `de`, `es`, `fr`, `it`, `nl`, `pl`, `ru`, `ar`
152
+ or `auto` and picks the readability formulas (`readability_scores` is empty for `auto`).
153
+
154
+ ### Similar terms, profanity and the custom dictionary
155
+
156
+ ```javascript
157
+ const { data: similar } = await client.similarTerms('pet');
158
+ // { neighbors: [[0.81, 'dog'], [0.78, 'cat'], [0.75, 'puppy']],
159
+ // synonyms: ['darling', 'favorite', 'favourite', ...] }
160
+
161
+ const { data: profanity } = await client.profanity('This is so damn stupid.');
162
+ // { toks: ['This', 'is', 'so', 'damn', 'stupid.'], labels: [0, 0, 0, 1, 1] }
163
+
164
+ // Words the grammar and spelling checks should accept (product names, jargon).
165
+ const { data: entry } = await client.addDictionaryEntry('Sapling', { case_sensitive: true });
166
+ // { id: '...', entry: 'Sapling', case_sensitive: true, created_at: '...', updated_at: '...' }
167
+ const { data: entries } = await client.dictionaryEntries(); // a bare array, sorted by entry
168
+ await client.deleteDictionaryEntry(entry.id); // 204, empty body
169
+ ```
170
+
171
+ `similarTerms()` returns up to five `[similarity, term]` neighbors (similarity 0–1, most similar
172
+ first) plus WordNet `synonyms` (multi-word ones use underscores); only the first 100 characters of
173
+ the query are used. `profanity()` splits the text on whitespace and labels each token 1 (profane)
174
+ or 0. Both are unbilled. `addDictionaryEntry()` answers 400 for a duplicate entry or one with more
175
+ than two digits; `deleteDictionaryEntry()` answers 400 (not 404) for an id that is not this
176
+ account's.
177
+
178
+ ### Style-guide rulesets
179
+
180
+ Check text against style rules inline, or save a named ruleset once (owned by
181
+ your API key's account — its team, for team-scoped keys) and check against it
182
+ by name:
183
+
184
+ ```javascript
185
+ // Define the house style once…
186
+ await client.saveStyleguideRuleset('House Style', [
187
+ 'no exclamation marks',
188
+ { name: 'no jargon', description: 'No corporate buzzwords or filler.' },
189
+ ]);
190
+
191
+ // …then check against it by name (names match case-insensitively).
192
+ const response = await client.styleguide('Our synergy-driven solution!!', 'House Style');
193
+ console.log(response.data);
194
+ // { violations: [{ rule: 'no jargon', text: 'synergy-driven solution', ... }],
195
+ // rules: ['no exclamation marks', 'no jargon'], compliant: false }
196
+
197
+ // List and delete:
198
+ await client.styleguideRulesets(); // { rulesets: [{ name, rules, ... }] }
199
+ await client.deleteStyleguideRuleset('House Style');
200
+ ```
201
+
97
202
  ## Frontend Quickstart
98
203
 
99
204
  The SDK provides a way to automatically apply edit suggestions to any HTML contenteditable and textarea elements.
@@ -159,6 +264,28 @@ as `YYYY-MM-DD`, or `'list'`), and every value must be grounded in a quote from
159
264
  extraction, not inference, so a value that isn't stated is reported in `missing` rather than
160
265
  guessed.
161
266
 
267
+ ## Translation
268
+
269
+ Translate text into a target language, named by ISO 639 code (`'fr'`, `'zh-TW'`) or English
270
+ name (`'French'`). Line breaks and markup are preserved, and the detected source language is
271
+ reported alongside the translation:
272
+
273
+ ```javascript
274
+ client
275
+ .translate('Hello world.\nSee you at 5pm.', 'fr', { formality: 'formal' })
276
+ .then(function (response) {
277
+ console.log(response.data);
278
+ // { translation: 'Bonjour le monde.\nÀ 17h.',
279
+ // source_lang: 'en', source_lang_name: 'English',
280
+ // target_lang: 'fr', target_lang_name: 'French' }
281
+ })
282
+ ```
283
+
284
+ Region variants `zh-CN`/`zh-TW`/`zh-HK`, `pt-BR`/`pt-PT`, `en-GB`/`en-US`, `fr-CA` and
285
+ `es-419` are supported as targets; the optional `source_lang` hint never overrides what the
286
+ text actually is, and `formality` (`'formal'`/`'informal'`) picks the register where the
287
+ target language distinguishes them.
288
+
162
289
  ## Further Documentation
163
290
 
164
291
  - Full Sapling HTTP API and SDK [documentation](https://sapling.ai/docs).
@@ -179,3 +306,34 @@ try {
179
306
  console.error(error.response?.status, error.response?.data ?? error.message);
180
307
  }
181
308
  ```
309
+
310
+ API error bodies are JSON objects with a human-readable `msg`, for example
311
+ `{ msg: 'Invalid API key.' }`. The one exception is the 4MB `413`, which uses
312
+ `message`/`result` keys. When a `402` or `429` body has a numeric `retry_after`,
313
+ the request can succeed after waiting that many seconds. Without it, retrying
314
+ unchanged won't help. See
315
+ [Rate Limits & Errors](https://sapling.ai/docs/rate_limits/).
316
+
317
+ To find out why a key is blocked, and for how long, call `accountStatus()`. It
318
+ is unbilled and works while the key is blocked. It reports account-wide blocks:
319
+ an expired key or subscription, depleted credits, a billing limit, the trial
320
+ daily allowance or the monthly quota. It does not report a single endpoint's
321
+ short-term rate limit, because each endpoint has its own allowance. For a
322
+ `Capacity used.` 429, use that response's `retry_after` instead:
323
+
324
+ ```javascript
325
+ const { data } = await client.accountStatus();
326
+ if (!data.api_access) {
327
+ // blocked_reason: key_expired | subscription_expired | credits_depleted |
328
+ // monthly_billing_limit | trial_daily_limit | monthly_quota_exhausted
329
+ const retry = data.retry_after ? `, retry in ${data.retry_after}s` : '';
330
+ console.log(`${data.blocked_reason}: ${data.message}${retry}`);
331
+ }
332
+ ```
333
+
334
+ Every response includes `api_access`, `blocked_reason`, `message` and
335
+ `usage.monthly_quota_chars`. Keys that aren't team-scoped also get the
336
+ account's `subscription`, prepaid `credits`, `usage.chars_this_month` and, on a
337
+ free trial, `trial`. See [Account Status](https://sapling.ai/docs/api/account-status/).
338
+ Each call counts as 2,000 characters against the endpoint's own rate-limit
339
+ bucket, so call it when something fails rather than before every request.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saplingai/sapling-js",
3
- "version": "1.0.45",
3
+ "version": "1.0.53",
4
4
  "description": "JavaScript library for using the Sapling.ai API.",
5
5
  "type": "module",
6
6
  "main": "./sapling/client.js",
@@ -32,10 +32,182 @@ export type EditOptions = {
32
32
  lang?: string,
33
33
  medical?: boolean,
34
34
  advancedEdits?: AdvancedEditOptions,
35
+ /** Defaults to true. false skips error classification: edits omit error_type,
36
+ * general_error_type and classifier-generated descriptions. */
37
+ includeErrorCategories?: boolean,
35
38
  }
36
39
 
37
40
  export type AIDetectOptions = {
41
+ /** Include `sentence_scores` (server default true). */
38
42
  sent_scores?: boolean,
43
+ /** Include `score_string`, an HTML heatmap of the scored text. */
44
+ score_string?: boolean,
45
+ /** Pin a detector model version (e.g. `'20251027'`); omitted = current default. */
46
+ version?: string,
47
+ }
48
+
49
+ export type AIDetectSentenceScore = {
50
+ sentence: string;
51
+ /** Same model, 0–1 scale and 0.5 threshold as the overall `score`. */
52
+ score: number;
53
+ /** Offsets into the response `text` (`end` exclusive), counted in Unicode
54
+ * code points — slice with `Array.from(text)` if it may contain emoji. */
55
+ start: number;
56
+ end: number;
57
+ }
58
+
59
+ export type AIDetectLanguage = {
60
+ code: string;
61
+ /** English display name; null for codes without one. */
62
+ name: string | null;
63
+ confidence: number;
64
+ }
65
+
66
+ export type AIDetectResponse = {
67
+ /** 0 (likely human-written) to 1 (likely AI-generated). */
68
+ score: number;
69
+ /** Share of the text in sentences scoring >= 0.5 (flags partially
70
+ * AI-written documents); null when nothing could be scored. */
71
+ ai_fraction: number | null;
72
+ text: string;
73
+ tokens: string[];
74
+ token_probs: number[];
75
+ /** The pinned `version` when one was requested, otherwise an opaque
76
+ * identifier of the default model — log it, don't parse it. */
77
+ version: string;
78
+ /** Present unless `sent_scores: false`. */
79
+ sentence_scores?: AIDetectSentenceScore[];
80
+ /** Present when `score_string: true`. */
81
+ score_string?: string;
82
+ /** Advisory detected language; omitted unless detection is high-confidence.
83
+ * The detector is trained on English. */
84
+ language?: AIDetectLanguage;
85
+ }
86
+
87
+ export type AIDetectBatchResponse = {
88
+ results: AIDetectResponse[];
89
+ }
90
+
91
+ export type StyleguideRule = string | { name: string; description?: string };
92
+
93
+ export type StyleguideViolation = {
94
+ rule: string;
95
+ text: string;
96
+ start: number | null;
97
+ end: number | null;
98
+ note: string;
99
+ suggestion: string;
100
+ }
101
+
102
+ export type StyleguideResponse = {
103
+ violations: StyleguideViolation[];
104
+ rules: string[];
105
+ compliant: boolean;
106
+ }
107
+
108
+ export type StyleguideBatchResponse = {
109
+ results: StyleguideResponse[];
110
+ }
111
+
112
+ export type StyleguideRuleset = {
113
+ name: string;
114
+ rules: { name: string; description: string }[];
115
+ created_at: string | null;
116
+ updated_at: string | null;
117
+ }
118
+
119
+ export type StyleguideRulesetsResponse = {
120
+ rulesets: StyleguideRuleset[];
121
+ }
122
+
123
+ export type SaveStyleguideRulesetResponse = {
124
+ ruleset: StyleguideRuleset;
125
+ created: boolean;
126
+ }
127
+
128
+ export type DeleteStyleguideRulesetResponse = {
129
+ deleted: string;
130
+ }
131
+
132
+ export type AccountBlockedReason =
133
+ | 'key_expired'
134
+ | 'subscription_expired'
135
+ | 'credits_depleted'
136
+ | 'monthly_billing_limit'
137
+ | 'trial_daily_limit'
138
+ | 'monthly_quota_exhausted';
139
+
140
+ export type AccountCreditSummary = {
141
+ enabled: boolean;
142
+ currency: string;
143
+ alert_threshold_percent: number;
144
+ // Present only when `enabled` is true.
145
+ balance_credits?: number;
146
+ purchased_credits?: number;
147
+ consumed_credits?: number;
148
+ consumed_percent?: number;
149
+ low_balance?: boolean;
150
+ depleted?: boolean;
151
+ billing_mode?: string;
152
+ billing_mode_effective_at?: string | null;
153
+ metered_fallback_available?: boolean;
154
+ stops_when_depleted?: boolean;
155
+ billing_started_at?: string;
156
+ auto_topup?: { enabled: boolean; [field: string]: unknown };
157
+ [field: string]: unknown;
158
+ }
159
+
160
+ export type AccountStatusResponse = {
161
+ api_access: boolean;
162
+ blocked_reason: AccountBlockedReason | null;
163
+ message: string | null;
164
+ // Seconds until the block may clear; present only when blocked.
165
+ retry_after?: number;
166
+ usage: {
167
+ monthly_quota_chars: number | null;
168
+ // Omitted for team-scoped keys, like `subscription`, `credits` and `trial`.
169
+ month_start?: string;
170
+ chars_this_month?: number;
171
+ };
172
+ subscription?: {
173
+ active: boolean;
174
+ trial_only: boolean;
175
+ key_expired: boolean;
176
+ };
177
+ credits?: AccountCreditSummary;
178
+ // Present only for free-trial accounts.
179
+ trial?: {
180
+ daily_limit_chars: number | null;
181
+ chars_used_today: number;
182
+ resets_at: 'utc_midnight';
183
+ };
184
+ }
185
+
186
+ export type SimplifyReadingLevel = 'plain' | 'elementary' | 'middle_school' | 'high_school';
187
+
188
+ export type SimplifyOptions = {
189
+ reading_level?: SimplifyReadingLevel,
190
+ preserve_terms?: string[],
191
+ lang?: string,
192
+ }
193
+
194
+ export type SimplifyReadabilityScores = {
195
+ grade: number;
196
+ ease: number;
197
+ }
198
+
199
+ export type SimplifyResponse = {
200
+ simplified: string;
201
+ reading_level: SimplifyReadingLevel;
202
+ lang: string;
203
+ readability?: {
204
+ before: SimplifyReadabilityScores;
205
+ after: SimplifyReadabilityScores;
206
+ };
207
+ }
208
+
209
+ export type SimplifyBatchResponse = {
210
+ results: SimplifyResponse[];
39
211
  }
40
212
 
41
213
  export type LangdetectOptions = {
@@ -59,6 +231,10 @@ export type ClassifyResponse = {
59
231
  multi_label: boolean;
60
232
  }
61
233
 
234
+ export type ClassifyBatchResponse = {
235
+ results: ClassifyResponse[];
236
+ }
237
+
62
238
  export type SeoOptions = {
63
239
  keywords?: string[],
64
240
  suggestions?: boolean,
@@ -137,10 +313,20 @@ export type QualityRubric = {
137
313
  export type QualityResponse = {
138
314
  score: number;
139
315
  sentences?: QualitySentenceScore[];
316
+ truncated?: boolean;
140
317
  rubric?: QualityRubric;
141
318
  }
142
319
 
143
- export type PIIType = 'email' | 'phone' | 'ssn' | 'credit_card' | 'ip_address' | 'iban' | 'us_bank_routing';
320
+ export type QualityBatchResponse = {
321
+ results: QualityResponse[];
322
+ }
323
+
324
+ export type PIIDeterministicType = 'email' | 'phone' | 'ssn' | 'credit_card' | 'ip_address' | 'iban' | 'us_bank_routing';
325
+ // Opt-in, LLM-backed named-entity PII types: detected only when listed in
326
+ // `types` explicitly (a request without them stays deterministic-only), and
327
+ // the text is then capped at 10,000 characters rather than 20,000.
328
+ export type PIINerType = 'person' | 'organization' | 'location';
329
+ export type PIIType = PIIDeterministicType | PIINerType;
144
330
 
145
331
  export type PIIOptions = {
146
332
  types?: PIIType[],
@@ -162,19 +348,55 @@ export type PIIResponse = {
162
348
  redacted_text?: string;
163
349
  }
164
350
 
351
+ export type NERType = 'person' | 'organization' | 'location' | 'date' | 'time' |
352
+ 'money' | 'percent' | 'quantity' | 'product' | 'event';
353
+
354
+ export type NEROptions = {
355
+ types?: NERType[],
356
+ }
357
+
358
+ export type NEREntity = {
359
+ text: string;
360
+ type: NERType;
361
+ start: number;
362
+ end: number;
363
+ }
364
+
365
+ export type NERResponse = {
366
+ entities: NEREntity[];
367
+ types: NERType[];
368
+ }
369
+
370
+ export type NERBatchResponse = {
371
+ results: NERResponse[];
372
+ }
373
+
374
+ export type SafetyCategory = 'toxicity' | 'profanity' | 'harassment' | 'hate_speech' |
375
+ 'self_harm' | 'sexual' | 'violence';
376
+
377
+ export type SafetySpan = {
378
+ text: string;
379
+ start: number | null;
380
+ end: number | null;
381
+ scores: Partial<Record<SafetyCategory, number>>;
382
+ flagged_categories: SafetyCategory[];
383
+ }
384
+
165
385
  export type SafetyResponse = {
166
- toxicity: number;
167
- profanity: number;
168
- harassment: number;
169
- hate_speech: number;
170
- self_harm: number;
171
- sexual: number;
172
- violence: number;
173
- flagged: string[];
386
+ scores: Record<SafetyCategory, number>;
387
+ flagged: boolean;
388
+ flagged_categories: SafetyCategory[];
389
+ threshold: number;
390
+ spans?: SafetySpan[];
391
+ }
392
+
393
+ export type SafetyBatchResponse = {
394
+ results: SafetyResponse[];
174
395
  }
175
396
 
176
397
  export type SafetyOptions = {
177
398
  threshold?: number,
399
+ spans?: boolean,
178
400
  }
179
401
 
180
402
  export type SpellcheckOptions = {
@@ -215,6 +437,142 @@ export type ExtractResponse = {
215
437
  missing: string[],
216
438
  }
217
439
 
440
+ export type ExtractBatchResponse = {
441
+ results: ExtractResponse[];
442
+ }
443
+
444
+ export type TranslateOptions = {
445
+ source_lang?: string,
446
+ formality?: 'formal' | 'informal',
447
+ }
448
+
449
+ export type TranslateResponse = {
450
+ translation: string,
451
+ source_lang: string,
452
+ source_lang_name: string | null,
453
+ target_lang: string,
454
+ target_lang_name: string,
455
+ }
456
+
457
+ export type TranslateBatchResponse = {
458
+ results: TranslateResponse[];
459
+ }
460
+
461
+ export type SummarizeOptions = {
462
+ length?: 'short' | 'medium' | 'long',
463
+ }
464
+
465
+ export type SummarizeResponse = {
466
+ /** Mirrors `summary` — the endpoint's original response key. */
467
+ result: string,
468
+ summary: string,
469
+ key_points: string[],
470
+ length: 'short' | 'medium' | 'long',
471
+ }
472
+
473
+ export type SummarizeBatchResponse = {
474
+ results: SummarizeResponse[];
475
+ }
476
+
477
+ export type RephraseMapping =
478
+ 'paraphrase' | 'passive_to_active' | 'active_to_passive' | 'informal_to_formal' |
479
+ 'formal_to_informal' | 'sentence_split' | 'reword' | 'generate_title' | 'generate_acronym' |
480
+ 'generate_meta_description' | 'summarize' | 'expand' | 'shorten' | 'switch_tone' | 'switch_tense';
481
+
482
+ export type RephraseToneMapping =
483
+ 'straightforward' | 'confident' | 'friendly' | 'empathetic' | 'professional' | 'casual' |
484
+ 'diplomatic' | 'persuasive';
485
+
486
+ export type RephraseTenseMapping =
487
+ 'simple past' | 'past perfect' | 'past continuous' | 'past perfect continuous' |
488
+ 'simple present' | 'present perfect' | 'present continuous' | 'present perfect continuous' |
489
+ 'simple future' | 'future perfect' | 'future continuous' | 'future perfect continuous';
490
+
491
+ export type RephraseOptions = {
492
+ /** Defaults to 'paraphrase'. */
493
+ mapping?: RephraseMapping,
494
+ /** Only used with mapping 'switch_tone'. Defaults to 'straightforward'. */
495
+ tone_mapping?: RephraseToneMapping,
496
+ /** Only used with mapping 'switch_tense'. Defaults to 'simple past'. */
497
+ tense_mapping?: RephraseTenseMapping,
498
+ /** Number of alternatives, 1-8 (default 5). Honored by paraphrase, informal_to_formal,
499
+ * formal_to_informal, generate_title and generate_acronym. */
500
+ num_results?: number,
501
+ session_id?: string,
502
+ }
503
+
504
+ export type RephraseResult = {
505
+ hash: string,
506
+ original: string,
507
+ replacement: string,
508
+ rephrase_type: RephraseMapping,
509
+ model_version: string,
510
+ }
511
+
512
+ export type RephraseResponse = {
513
+ results: RephraseResult[],
514
+ }
515
+
516
+ export type SentimentLabel = 'POSITIVE' | 'NEUTRAL' | 'NEGATIVE';
517
+
518
+ /** [probability, label] pairs, most likely first. */
519
+ export type SentimentScores = Array<[number, SentimentLabel]>;
520
+
521
+ export type SentimentResponse = {
522
+ overall: SentimentScores,
523
+ /** One entry per sentence, aligned with `sents`. */
524
+ results: SentimentScores[],
525
+ sents: string[],
526
+ }
527
+
528
+ export type StatisticsLang = 'en' | 'de' | 'es' | 'fr' | 'it' | 'nl' | 'pl' | 'ru' | 'ar' | 'auto';
529
+
530
+ export type StatisticsOptions = {
531
+ /** Defaults to 'en'. */
532
+ lang?: StatisticsLang,
533
+ }
534
+
535
+ export type StatisticsResponse = {
536
+ chars: number,
537
+ words: number,
538
+ sentences: number,
539
+ reading_time_sec: number,
540
+ reading_time_min: number,
541
+ /** Flesch-Kincaid grade level; -3.4 when the text cannot be scored. */
542
+ readability: number,
543
+ /** Formula name -> score. The formulas present depend on `lang`; empty for 'auto'.
544
+ * `text_standard` is a string (e.g. "8th and 9th grade"). */
545
+ readability_scores: Record<string, number | string>,
546
+ }
547
+
548
+ export type SimilarTermsResponse = {
549
+ /** Up to 5 [similarity, term] pairs (similarity 0-1), most similar first. */
550
+ neighbors: Array<[number, string]>,
551
+ /** WordNet lemma names; multi-word ones use underscores (e.g. "domestic_dog"). */
552
+ synonyms: string[],
553
+ }
554
+
555
+ export type ProfanityResponse = {
556
+ /** The text split on whitespace (punctuation stays attached). */
557
+ toks: string[],
558
+ /** Aligned with `toks`: 1 for profanity, 0 otherwise. */
559
+ labels: Array<0 | 1>,
560
+ }
561
+
562
+ export type DictionaryEntry = {
563
+ id: string,
564
+ entry: string,
565
+ case_sensitive: boolean,
566
+ /** RFC 1123 timestamp, e.g. "Wed, 07 Oct 2020 21:15:47 GMT". */
567
+ created_at: string,
568
+ updated_at: string,
569
+ }
570
+
571
+ export type AddDictionaryEntryOptions = {
572
+ /** Defaults to true. */
573
+ case_sensitive?: boolean,
574
+ }
575
+
218
576
  export type UserDetails = {
219
577
  userId?: string,
220
578
  anonUser?: boolean,
@@ -232,13 +590,54 @@ export declare class Client {
232
590
  complete(query: string, sessionId?: string): Promise<AxiosResponse>;
233
591
  acceptComplete(completeUUID: string, query: string, completion: string, sessionId?: string): Promise<AxiosResponse>;
234
592
  tone(text: string): Promise<AxiosResponse>;
593
+ rephrase(text: string, options?: RephraseOptions): Promise<AxiosResponse<RephraseResponse>>;
594
+ /** A text with no sentences (e.g. markup or punctuation only) gets a 204 with an empty
595
+ * body, so `data` is `''` then; a text the API cannot split into sentences gets a 200
596
+ * with `[]`. Check `Array.isArray(data) || !data` before reading fields. */
597
+ sentiment(text: string): Promise<AxiosResponse<SentimentResponse | '' | never[]>>;
598
+ statistics(text: string, options?: StatisticsOptions): Promise<AxiosResponse<StatisticsResponse>>;
599
+ similarTerms(query: string): Promise<AxiosResponse<SimilarTermsResponse>>;
600
+ profanity(text: string): Promise<AxiosResponse<ProfanityResponse>>;
601
+ dictionaryEntries(): Promise<AxiosResponse<DictionaryEntry[]>>;
602
+ addDictionaryEntry(entry: string, options?: AddDictionaryEntryOptions): Promise<AxiosResponse<DictionaryEntry>>;
603
+ /** Answers 204 with an empty body. */
604
+ deleteDictionaryEntry(entryId: string): Promise<AxiosResponse<''>>;
235
605
  extract(text: string, fields: ExtractField[], options?: ExtractOptions): Promise<AxiosResponse<ExtractResponse>>;
236
-
237
- aidetect(text: string, options?: AIDetectOptions): Promise<AxiosResponse>;
238
- langdetect(text: string, options?: LangdetectOptions): Promise<AxiosResponse>;
606
+ extract(texts: string[], fields: ExtractField[], options?: ExtractOptions): Promise<AxiosResponse<ExtractBatchResponse>>;
607
+ extract(text: string | string[], fields: ExtractField[], options?: ExtractOptions): Promise<AxiosResponse<ExtractResponse | ExtractBatchResponse>>;
608
+ translate(text: string, targetLang: string, options?: TranslateOptions): Promise<AxiosResponse<TranslateResponse>>;
609
+ translate(texts: string[], targetLang: string, options?: TranslateOptions): Promise<AxiosResponse<TranslateBatchResponse>>;
610
+ translate(text: string | string[], targetLang: string, options?: TranslateOptions): Promise<AxiosResponse<TranslateResponse | TranslateBatchResponse>>;
611
+ summarize(text: string, options?: SummarizeOptions): Promise<AxiosResponse<SummarizeResponse>>;
612
+ summarize(texts: string[], options?: SummarizeOptions): Promise<AxiosResponse<SummarizeBatchResponse>>;
613
+ summarize(text: string | string[], options?: SummarizeOptions): Promise<AxiosResponse<SummarizeResponse | SummarizeBatchResponse>>;
614
+
615
+ aidetect(text: string, options?: AIDetectOptions): Promise<AxiosResponse<AIDetectResponse>>;
616
+ aidetect(texts: string[], options?: AIDetectOptions): Promise<AxiosResponse<AIDetectBatchResponse>>;
617
+ aidetect(text: string | string[], options?: AIDetectOptions): Promise<AxiosResponse<AIDetectResponse | AIDetectBatchResponse>>;
618
+ styleguide(text: string, rules: StyleguideRule[] | string): Promise<AxiosResponse<StyleguideResponse>>;
619
+ styleguide(texts: string[], rules: StyleguideRule[] | string): Promise<AxiosResponse<StyleguideBatchResponse>>;
620
+ styleguide(text: string | string[], rules: StyleguideRule[] | string): Promise<AxiosResponse<StyleguideResponse | StyleguideBatchResponse>>;
621
+ styleguideRulesets(): Promise<AxiosResponse<StyleguideRulesetsResponse>>;
622
+ saveStyleguideRuleset(name: string, rules: StyleguideRule[]): Promise<AxiosResponse<SaveStyleguideRulesetResponse>>;
623
+ deleteStyleguideRuleset(name: string): Promise<AxiosResponse<DeleteStyleguideRulesetResponse>>;
624
+ simplify(text: string, options?: SimplifyOptions): Promise<AxiosResponse<SimplifyResponse>>;
625
+ simplify(texts: string[], options?: SimplifyOptions): Promise<AxiosResponse<SimplifyBatchResponse>>;
626
+ simplify(text: string | string[], options?: SimplifyOptions): Promise<AxiosResponse<SimplifyResponse | SimplifyBatchResponse>>;
627
+ langdetect(text: string | string[], options?: LangdetectOptions): Promise<AxiosResponse>;
239
628
  quality(text: string, options?: QualityOptions): Promise<AxiosResponse<QualityResponse>>;
629
+ quality(texts: string[], options?: QualityOptions): Promise<AxiosResponse<QualityBatchResponse>>;
630
+ quality(text: string | string[], options?: QualityOptions): Promise<AxiosResponse<QualityResponse | QualityBatchResponse>>;
240
631
  pii(text: string, options?: PIIOptions): Promise<AxiosResponse<PIIResponse>>;
632
+ ner(text: string, options?: NEROptions): Promise<AxiosResponse<NERResponse>>;
633
+ ner(texts: string[], options?: NEROptions): Promise<AxiosResponse<NERBatchResponse>>;
634
+ ner(text: string | string[], options?: NEROptions): Promise<AxiosResponse<NERResponse | NERBatchResponse>>;
241
635
  safety(text: string, options?: SafetyOptions): Promise<AxiosResponse<SafetyResponse>>;
636
+ safety(texts: string[], options?: SafetyOptions): Promise<AxiosResponse<SafetyBatchResponse>>;
637
+ safety(text: string | string[], options?: SafetyOptions): Promise<AxiosResponse<SafetyResponse | SafetyBatchResponse>>;
242
638
  classify(text: string, labels: ClassifyLabel[], options?: ClassifyOptions): Promise<AxiosResponse<ClassifyResponse>>;
639
+ classify(texts: string[], labels: ClassifyLabel[], options?: ClassifyOptions): Promise<AxiosResponse<ClassifyBatchResponse>>;
640
+ classify(text: string | string[], labels: ClassifyLabel[], options?: ClassifyOptions): Promise<AxiosResponse<ClassifyResponse | ClassifyBatchResponse>>;
243
641
  seo(text: string, options?: SeoOptions): Promise<AxiosResponse<SeoResponse>>;
642
+ accountStatus(): Promise<AxiosResponse<AccountStatusResponse>>;
244
643
  }