@aws-amplify/predictions 6.0.22-unstable.bd1fefd.0 → 6.0.22
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/dist/cjs/Predictions.js +4 -2
- package/dist/cjs/Predictions.js.map +1 -1
- package/dist/cjs/providers/AmazonAIConvertPredictionsProvider.js +9 -9
- package/dist/cjs/providers/AmazonAIConvertPredictionsProvider.js.map +1 -1
- package/dist/cjs/providers/AmazonAIIdentifyPredictionsProvider.js +20 -25
- package/dist/cjs/providers/AmazonAIIdentifyPredictionsProvider.js.map +1 -1
- package/dist/cjs/providers/AmazonAIInterpretPredictionsProvider.js +7 -7
- package/dist/cjs/providers/AmazonAIInterpretPredictionsProvider.js.map +1 -1
- package/dist/cjs/providers/IdentifyTextUtils.js +9 -9
- package/dist/cjs/providers/IdentifyTextUtils.js.map +1 -1
- package/dist/cjs/providers/Utils.js +6 -6
- package/dist/cjs/providers/Utils.js.map +1 -1
- package/dist/cjs/types/Predictions.js +14 -15
- package/dist/cjs/types/Predictions.js.map +1 -1
- package/dist/esm/Predictions.mjs +2 -0
- package/dist/esm/Predictions.mjs.map +1 -1
- package/dist/esm/providers/AmazonAIConvertPredictionsProvider.mjs +9 -9
- package/dist/esm/providers/AmazonAIConvertPredictionsProvider.mjs.map +1 -1
- package/dist/esm/providers/AmazonAIIdentifyPredictionsProvider.d.ts +6 -6
- package/dist/esm/providers/AmazonAIIdentifyPredictionsProvider.mjs +20 -25
- package/dist/esm/providers/AmazonAIIdentifyPredictionsProvider.mjs.map +1 -1
- package/dist/esm/providers/AmazonAIInterpretPredictionsProvider.mjs +7 -7
- package/dist/esm/providers/AmazonAIInterpretPredictionsProvider.mjs.map +1 -1
- package/dist/esm/providers/IdentifyTextUtils.mjs +9 -9
- package/dist/esm/providers/IdentifyTextUtils.mjs.map +1 -1
- package/dist/esm/providers/Utils.mjs +6 -6
- package/dist/esm/providers/Utils.mjs.map +1 -1
- package/dist/esm/types/AWSTypes.d.ts +2 -2
- package/dist/esm/types/Predictions.d.ts +30 -30
- package/dist/esm/types/Predictions.mjs +14 -15
- package/dist/esm/types/Predictions.mjs.map +1 -1
- package/package.json +71 -72
- package/src/Predictions.ts +3 -2
- package/src/providers/AmazonAIConvertPredictionsProvider.ts +10 -20
- package/src/providers/AmazonAIIdentifyPredictionsProvider.ts +26 -41
- package/src/providers/AmazonAIInterpretPredictionsProvider.ts +18 -22
- package/src/providers/IdentifyTextUtils.ts +22 -25
- package/src/providers/Utils.ts +6 -8
- package/src/providers/index.ts +0 -1
- package/src/types/AWSTypes.ts +3 -2
- package/src/types/Predictions.ts +44 -60
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Buffer } from 'buffer';
|
|
4
|
-
|
|
5
3
|
import { Amplify, ConsoleLogger, fetchAuthSession } from '@aws-amplify/core';
|
|
6
4
|
import {
|
|
7
5
|
AWSCredentials,
|
|
@@ -20,7 +18,7 @@ import {
|
|
|
20
18
|
MessageHeaderValue,
|
|
21
19
|
} from '@smithy/eventstream-codec';
|
|
22
20
|
import { fromUtf8, toUtf8 } from '@smithy/util-utf8';
|
|
23
|
-
|
|
21
|
+
import { Buffer } from 'buffer';
|
|
24
22
|
import { PredictionsValidationErrorCode } from '../errors/types/validation';
|
|
25
23
|
import { assertValidationError } from '../errors/utils/assertValidationError';
|
|
26
24
|
import {
|
|
@@ -61,15 +59,12 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
61
59
|
|
|
62
60
|
if (isTranslateTextInput(input)) {
|
|
63
61
|
logger.debug('translateText');
|
|
64
|
-
|
|
65
62
|
return this.translateText(input);
|
|
66
63
|
} else if (isTextToSpeechInput(input)) {
|
|
67
64
|
logger.debug('textToSpeech');
|
|
68
|
-
|
|
69
65
|
return this.convertTextToSpeech(input);
|
|
70
66
|
} else {
|
|
71
67
|
logger.debug('textToSpeech');
|
|
72
|
-
|
|
73
68
|
return this.convertSpeechToText(input);
|
|
74
69
|
}
|
|
75
70
|
}
|
|
@@ -121,7 +116,6 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
121
116
|
Text: input.translateText?.source?.text,
|
|
122
117
|
});
|
|
123
118
|
const data = await this.translateClient.send(translateTextCommand);
|
|
124
|
-
|
|
125
119
|
return {
|
|
126
120
|
text: data.TranslatedText,
|
|
127
121
|
language: data.TargetLanguageCode,
|
|
@@ -167,6 +161,7 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
167
161
|
VoiceId: voiceId,
|
|
168
162
|
TextType: 'text',
|
|
169
163
|
SampleRate: '24000',
|
|
164
|
+
// tslint:disable-next-line: align
|
|
170
165
|
});
|
|
171
166
|
const data = await this.pollyClient.send(synthesizeSpeechCommand);
|
|
172
167
|
const response = new Response(data.AudioStream as ReadableStream);
|
|
@@ -175,7 +170,6 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
175
170
|
type: data.ContentType,
|
|
176
171
|
});
|
|
177
172
|
const url = URL.createObjectURL(blob);
|
|
178
|
-
|
|
179
173
|
return {
|
|
180
174
|
speech: { url },
|
|
181
175
|
audioStream: arrayBuffer,
|
|
@@ -224,7 +218,6 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
224
218
|
raw: source.bytes,
|
|
225
219
|
languageCode: language,
|
|
226
220
|
});
|
|
227
|
-
|
|
228
221
|
return {
|
|
229
222
|
transcription: {
|
|
230
223
|
fullText,
|
|
@@ -268,7 +261,6 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
268
261
|
}
|
|
269
262
|
}
|
|
270
263
|
}
|
|
271
|
-
|
|
272
264
|
return decodedMessage;
|
|
273
265
|
}
|
|
274
266
|
|
|
@@ -277,7 +269,7 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
277
269
|
raw,
|
|
278
270
|
languageCode,
|
|
279
271
|
}: TranscribeData): Promise<string> {
|
|
280
|
-
return new Promise((
|
|
272
|
+
return new Promise((res, rej) => {
|
|
281
273
|
let fullText = '';
|
|
282
274
|
connection.onmessage = message => {
|
|
283
275
|
try {
|
|
@@ -290,19 +282,18 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
290
282
|
}
|
|
291
283
|
} catch (err: unknown) {
|
|
292
284
|
logger.debug(err);
|
|
293
|
-
|
|
285
|
+
rej(err);
|
|
294
286
|
}
|
|
295
287
|
};
|
|
296
288
|
|
|
297
289
|
connection.onerror = errorEvent => {
|
|
298
290
|
logger.debug({ errorEvent });
|
|
299
|
-
|
|
291
|
+
rej('failed to transcribe, network error');
|
|
300
292
|
};
|
|
301
293
|
|
|
302
294
|
connection.onclose = closeEvent => {
|
|
303
295
|
logger.debug({ closeEvent });
|
|
304
|
-
|
|
305
|
-
resolve(fullText.trim());
|
|
296
|
+
return res(fullText.trim());
|
|
306
297
|
};
|
|
307
298
|
|
|
308
299
|
logger.debug({ raw });
|
|
@@ -375,7 +366,6 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
375
366
|
const s = Math.max(-1, Math.min(1, input[i]));
|
|
376
367
|
view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
|
|
377
368
|
}
|
|
378
|
-
|
|
379
369
|
return buffer;
|
|
380
370
|
}
|
|
381
371
|
|
|
@@ -403,8 +393,8 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
403
393
|
let offsetBuffer = 0;
|
|
404
394
|
while (offsetResult < result.length) {
|
|
405
395
|
const nextOffsetBuffer = Math.round((offsetResult + 1) * sampleRateRatio);
|
|
406
|
-
let accum = 0
|
|
407
|
-
|
|
396
|
+
let accum = 0,
|
|
397
|
+
count = 0;
|
|
408
398
|
for (
|
|
409
399
|
let i = offsetBuffer;
|
|
410
400
|
i < nextOffsetBuffer && i < buffer.length;
|
|
@@ -430,7 +420,7 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
430
420
|
region: string;
|
|
431
421
|
languageCode: string;
|
|
432
422
|
}): Promise<WebSocket> {
|
|
433
|
-
return new Promise((
|
|
423
|
+
return new Promise(async (res, rej) => {
|
|
434
424
|
const signedUrl = this.generateTranscribeUrl({
|
|
435
425
|
credentials,
|
|
436
426
|
region,
|
|
@@ -443,7 +433,7 @@ export class AmazonAIConvertPredictionsProvider {
|
|
|
443
433
|
connection.binaryType = 'arraybuffer';
|
|
444
434
|
connection.onopen = () => {
|
|
445
435
|
logger.debug('connected');
|
|
446
|
-
|
|
436
|
+
res(connection);
|
|
447
437
|
};
|
|
448
438
|
});
|
|
449
439
|
}
|
|
@@ -26,7 +26,6 @@ import {
|
|
|
26
26
|
DetectDocumentTextCommandInput,
|
|
27
27
|
TextractClient,
|
|
28
28
|
} from '@aws-sdk/client-textract';
|
|
29
|
-
|
|
30
29
|
import { PredictionsValidationErrorCode } from '../errors/types/validation';
|
|
31
30
|
import { assertValidationError } from '../errors/utils/assertValidationError';
|
|
32
31
|
import {
|
|
@@ -51,8 +50,12 @@ import {
|
|
|
51
50
|
isStorageSource,
|
|
52
51
|
isValidIdentifyInput,
|
|
53
52
|
} from '../types';
|
|
54
|
-
import {
|
|
55
|
-
|
|
53
|
+
import {
|
|
54
|
+
BlockList,
|
|
55
|
+
Document,
|
|
56
|
+
Image,
|
|
57
|
+
TextDetectionList,
|
|
58
|
+
} from '../types/AWSTypes';
|
|
56
59
|
import {
|
|
57
60
|
categorizeRekognitionBlocks,
|
|
58
61
|
categorizeTextractBlocks,
|
|
@@ -81,15 +84,12 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
81
84
|
|
|
82
85
|
if (isIdentifyTextInput(input)) {
|
|
83
86
|
logger.debug('identifyText');
|
|
84
|
-
|
|
85
87
|
return this.identifyText(input);
|
|
86
88
|
} else if (isIdentifyLabelsInput(input)) {
|
|
87
89
|
logger.debug('identifyLabels');
|
|
88
|
-
|
|
89
90
|
return this.identifyLabels(input);
|
|
90
91
|
} else {
|
|
91
92
|
logger.debug('identifyEntities');
|
|
92
|
-
|
|
93
93
|
return this.identifyEntities(input);
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -102,7 +102,7 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
102
102
|
* @return {Promise<Image>} - Promise resolving to the converted source object.
|
|
103
103
|
*/
|
|
104
104
|
private configureSource(source: IdentifySource): Promise<Image> {
|
|
105
|
-
return new Promise((
|
|
105
|
+
return new Promise((res, rej) => {
|
|
106
106
|
if (isStorageSource(source)) {
|
|
107
107
|
const storageConfig = {
|
|
108
108
|
accessLevel: source.level,
|
|
@@ -114,44 +114,37 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
114
114
|
const parser =
|
|
115
115
|
/https:\/\/([a-zA-Z0-9%\-_.]+)\.s3\.[A-Za-z0-9%\-._~]+\/([a-zA-Z0-9%\-._~/]+)\?/;
|
|
116
116
|
const parsedURL = value.url.toString().match(parser) ?? '';
|
|
117
|
-
if (parsedURL.length < 3)
|
|
118
|
-
|
|
119
|
-
resolve({
|
|
117
|
+
if (parsedURL.length < 3) rej('Invalid S3 key was given.');
|
|
118
|
+
res({
|
|
120
119
|
S3Object: {
|
|
121
120
|
Bucket: parsedURL[1],
|
|
122
121
|
Name: decodeURIComponent(parsedURL[2]),
|
|
123
122
|
},
|
|
124
123
|
});
|
|
125
124
|
})
|
|
126
|
-
.catch(err =>
|
|
127
|
-
reject(err);
|
|
128
|
-
});
|
|
125
|
+
.catch(err => rej(err));
|
|
129
126
|
} else if (isFileSource(source)) {
|
|
130
127
|
blobToArrayBuffer(source.file)
|
|
131
128
|
.then(buffer => {
|
|
132
|
-
|
|
129
|
+
res({ Bytes: new Uint8Array(buffer) });
|
|
133
130
|
})
|
|
134
|
-
.catch(err =>
|
|
135
|
-
reject(err);
|
|
136
|
-
});
|
|
131
|
+
.catch(err => rej(err));
|
|
137
132
|
} else if (isIdentifyBytesSource(source)) {
|
|
138
|
-
const
|
|
133
|
+
const bytes = source.bytes;
|
|
139
134
|
if (bytes instanceof Blob) {
|
|
140
135
|
blobToArrayBuffer(bytes)
|
|
141
136
|
.then(buffer => {
|
|
142
|
-
|
|
137
|
+
res({ Bytes: new Uint8Array(buffer) });
|
|
143
138
|
})
|
|
144
|
-
.catch(err =>
|
|
145
|
-
reject(err);
|
|
146
|
-
});
|
|
139
|
+
.catch(err => rej(err));
|
|
147
140
|
}
|
|
148
141
|
if (bytes instanceof ArrayBuffer || bytes instanceof Buffer) {
|
|
149
|
-
|
|
142
|
+
res({ Bytes: new Uint8Array(bytes) } as Image);
|
|
150
143
|
}
|
|
151
144
|
// everything else can be directly passed to Rekognition / Textract.
|
|
152
|
-
|
|
145
|
+
res({ Bytes: bytes } as Image);
|
|
153
146
|
} else {
|
|
154
|
-
|
|
147
|
+
rej('Input source is not configured correctly.');
|
|
155
148
|
}
|
|
156
149
|
});
|
|
157
150
|
}
|
|
@@ -186,8 +179,9 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
186
179
|
credentials,
|
|
187
180
|
customUserAgent: _getPredictionsIdentifyAmplifyUserAgent(),
|
|
188
181
|
});
|
|
182
|
+
let inputDocument: Document;
|
|
189
183
|
|
|
190
|
-
|
|
184
|
+
inputDocument = await this.configureSource(input.text?.source);
|
|
191
185
|
|
|
192
186
|
// get default value if format isn't specified in the input.
|
|
193
187
|
const format = input.text?.format ?? configFormat;
|
|
@@ -243,7 +237,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
243
237
|
|
|
244
238
|
const analyzeDocumentCommand = new AnalyzeDocumentCommand(param);
|
|
245
239
|
const { Blocks } = await this.textractClient.send(analyzeDocumentCommand);
|
|
246
|
-
|
|
247
240
|
return categorizeTextractBlocks(Blocks as BlockList);
|
|
248
241
|
}
|
|
249
242
|
}
|
|
@@ -292,15 +285,14 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
292
285
|
data.forEach(val => {
|
|
293
286
|
identifyResult = { ...identifyResult, ...val };
|
|
294
287
|
});
|
|
295
|
-
|
|
296
288
|
return identifyResult;
|
|
297
289
|
});
|
|
298
290
|
}
|
|
299
291
|
|
|
300
292
|
/**
|
|
301
293
|
* Calls Rekognition.detectLabels and organizes the returned data.
|
|
302
|
-
* @param param -
|
|
303
|
-
* @return
|
|
294
|
+
* @param {DetectLabelsInput} param - parameter to be passed onto Rekognition
|
|
295
|
+
* @return {Promise<IdentifyLabelsOutput>} - Promise resolving to organized detectLabels response.
|
|
304
296
|
*/
|
|
305
297
|
private async detectLabels(
|
|
306
298
|
param: DetectLabelsCommandInput,
|
|
@@ -314,7 +306,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
314
306
|
instance =>
|
|
315
307
|
makeCamelCase(instance.BoundingBox) as BoundingBox | undefined,
|
|
316
308
|
) || [];
|
|
317
|
-
|
|
318
309
|
return {
|
|
319
310
|
name: label.Name,
|
|
320
311
|
boundingBoxes: boxes,
|
|
@@ -324,14 +315,13 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
324
315
|
},
|
|
325
316
|
};
|
|
326
317
|
});
|
|
327
|
-
|
|
328
318
|
return { labels: detectLabelData };
|
|
329
319
|
}
|
|
330
320
|
|
|
331
321
|
/**
|
|
332
322
|
* Calls Rekognition.detectModerationLabels and organizes the returned data.
|
|
333
|
-
* @param param
|
|
334
|
-
* @return
|
|
323
|
+
* @param {Rekognition.DetectLabelsRequest} param - Parameter to be passed onto Rekognition
|
|
324
|
+
* @return {Promise<IdentifyLabelsOutput>} - Promise resolving to organized detectModerationLabels response.
|
|
335
325
|
*/
|
|
336
326
|
private async detectModerationLabels(
|
|
337
327
|
param: DetectModerationLabelsCommandInput,
|
|
@@ -352,8 +342,8 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
352
342
|
/**
|
|
353
343
|
* Identify faces within an image that is provided as input, and match faces from a collection
|
|
354
344
|
* or identify celebrities.
|
|
355
|
-
* @param input - object
|
|
356
|
-
* @return
|
|
345
|
+
* @param {IdentifyEntityInput} input - object containing the source image and face match options.
|
|
346
|
+
* @return {Promise<IdentifyEntityOutput>} Promise resolving to identify results.
|
|
357
347
|
*/
|
|
358
348
|
protected async identifyEntities(
|
|
359
349
|
input: IdentifyEntitiesInput,
|
|
@@ -411,7 +401,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
411
401
|
},
|
|
412
402
|
}) as IdentifyEntity,
|
|
413
403
|
) ?? [];
|
|
414
|
-
|
|
415
404
|
return { entities: faces };
|
|
416
405
|
} else if (
|
|
417
406
|
isIdentifyFromCollection(input.entities) &&
|
|
@@ -436,7 +425,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
436
425
|
const externalImageId = match.Face?.ExternalImageId
|
|
437
426
|
? this.decodeExternalImageId(match.Face.ExternalImageId)
|
|
438
427
|
: undefined;
|
|
439
|
-
|
|
440
428
|
return {
|
|
441
429
|
boundingBox: makeCamelCase(match.Face?.BoundingBox),
|
|
442
430
|
metadata: {
|
|
@@ -445,7 +433,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
445
433
|
},
|
|
446
434
|
} as IdentifyEntity;
|
|
447
435
|
}) ?? [];
|
|
448
|
-
|
|
449
436
|
return { entities: faces };
|
|
450
437
|
} else {
|
|
451
438
|
const detectFacesCommand = new DetectFacesCommand(param);
|
|
@@ -471,7 +458,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
471
458
|
faceAttributes.emotions = detail.Emotions?.map(
|
|
472
459
|
emotion => emotion.Type,
|
|
473
460
|
);
|
|
474
|
-
|
|
475
461
|
return {
|
|
476
462
|
boundingBox: makeCamelCase(detail.BoundingBox),
|
|
477
463
|
landmarks: makeCamelCaseArray(detail.Landmarks),
|
|
@@ -483,7 +469,6 @@ export class AmazonAIIdentifyPredictionsProvider {
|
|
|
483
469
|
},
|
|
484
470
|
} as IdentifyEntity;
|
|
485
471
|
}) ?? [];
|
|
486
|
-
|
|
487
472
|
return { entities: faces };
|
|
488
473
|
}
|
|
489
474
|
}
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
PredictionsAction,
|
|
7
7
|
getAmplifyUserAgentObject,
|
|
8
8
|
} from '@aws-amplify/core/internals/utils';
|
|
9
|
+
|
|
9
10
|
import {
|
|
10
11
|
ComprehendClient,
|
|
11
12
|
DetectDominantLanguageCommand,
|
|
@@ -16,7 +17,6 @@ import {
|
|
|
16
17
|
Entity,
|
|
17
18
|
SyntaxToken,
|
|
18
19
|
} from '@aws-sdk/client-comprehend';
|
|
19
|
-
|
|
20
20
|
import { PredictionsValidationErrorCode } from '../errors/types/validation';
|
|
21
21
|
import { assertValidationError } from '../errors/utils/assertValidationError';
|
|
22
22
|
import {
|
|
@@ -63,9 +63,9 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
63
63
|
const { text: textSource } = input;
|
|
64
64
|
const { source, type = defaultType } = textSource;
|
|
65
65
|
const { text } = source;
|
|
66
|
-
let
|
|
66
|
+
let language;
|
|
67
67
|
if (isInterpretTextOthers(textSource)) {
|
|
68
|
-
|
|
68
|
+
language = (textSource as InterpretTextOthers).source.language;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
this.comprehendClient = new ComprehendClient({
|
|
@@ -79,7 +79,7 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
79
79
|
|
|
80
80
|
const doAll = type === 'all';
|
|
81
81
|
|
|
82
|
-
let languageCode =
|
|
82
|
+
let languageCode = language;
|
|
83
83
|
if (doAll || type === 'language') {
|
|
84
84
|
const languageDetectionParams = {
|
|
85
85
|
Text: text,
|
|
@@ -87,7 +87,7 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
87
87
|
languageCode = await this.detectLanguage(languageDetectionParams);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
let entitiesPromise: Promise<TextEntities
|
|
90
|
+
let entitiesPromise: Promise<Array<TextEntities>> | undefined;
|
|
91
91
|
if (doAll || type === 'entities') {
|
|
92
92
|
assertValidationError(
|
|
93
93
|
!!languageCode,
|
|
@@ -113,7 +113,7 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
113
113
|
sentimentPromise = this.detectSentiment(sentimentParams);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
let syntaxPromise: Promise<TextSyntax
|
|
116
|
+
let syntaxPromise: Promise<Array<TextSyntax>> | undefined;
|
|
117
117
|
if (doAll || type === 'syntax') {
|
|
118
118
|
assertValidationError(
|
|
119
119
|
!!languageCode,
|
|
@@ -145,7 +145,6 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
145
145
|
syntaxPromise,
|
|
146
146
|
keyPhrasesPromise,
|
|
147
147
|
]);
|
|
148
|
-
|
|
149
148
|
return {
|
|
150
149
|
textInterpretation: {
|
|
151
150
|
keyPhrases,
|
|
@@ -161,9 +160,8 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
161
160
|
try {
|
|
162
161
|
const detectKeyPhrasesCommand = new DetectKeyPhrasesCommand(params);
|
|
163
162
|
const data = await this.comprehendClient!.send(detectKeyPhrasesCommand);
|
|
164
|
-
const { KeyPhrases
|
|
165
|
-
|
|
166
|
-
return keyPhrases.map(({ Text: text }) => {
|
|
163
|
+
const { KeyPhrases = [] } = data || {};
|
|
164
|
+
return KeyPhrases.map(({ Text: text }) => {
|
|
167
165
|
return { text };
|
|
168
166
|
});
|
|
169
167
|
} catch (err: any) {
|
|
@@ -178,12 +176,11 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
178
176
|
}
|
|
179
177
|
}
|
|
180
178
|
|
|
181
|
-
private async detectSyntax(params: DetectParams): Promise<TextSyntax
|
|
179
|
+
private async detectSyntax(params: DetectParams): Promise<Array<TextSyntax>> {
|
|
182
180
|
try {
|
|
183
181
|
const detectSyntaxCommand = new DetectSyntaxCommand(params);
|
|
184
182
|
const data = await this.comprehendClient!.send(detectSyntaxCommand);
|
|
185
183
|
const { SyntaxTokens = [] } = data || {};
|
|
186
|
-
|
|
187
184
|
return this.serializeSyntaxFromComprehend(SyntaxTokens);
|
|
188
185
|
} catch (err: any) {
|
|
189
186
|
if (err.code === 'AccessDeniedException') {
|
|
@@ -197,7 +194,9 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
197
194
|
}
|
|
198
195
|
}
|
|
199
196
|
|
|
200
|
-
private serializeSyntaxFromComprehend(
|
|
197
|
+
private serializeSyntaxFromComprehend(
|
|
198
|
+
tokens: SyntaxToken[],
|
|
199
|
+
): Array<TextSyntax> {
|
|
201
200
|
let response: TextSyntax[] = [];
|
|
202
201
|
if (tokens && Array.isArray(tokens)) {
|
|
203
202
|
response = tokens.map(
|
|
@@ -206,7 +205,6 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
206
205
|
},
|
|
207
206
|
);
|
|
208
207
|
}
|
|
209
|
-
|
|
210
208
|
return response;
|
|
211
209
|
}
|
|
212
210
|
|
|
@@ -222,8 +220,7 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
222
220
|
Neutral: neutral = 0,
|
|
223
221
|
Mixed: mixed = 0,
|
|
224
222
|
} = {},
|
|
225
|
-
} =
|
|
226
|
-
|
|
223
|
+
} = ({} = data);
|
|
227
224
|
return { predominant, positive, negative, neutral, mixed };
|
|
228
225
|
} catch (err: any) {
|
|
229
226
|
if (err.code === 'AccessDeniedException') {
|
|
@@ -237,12 +234,13 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
237
234
|
}
|
|
238
235
|
}
|
|
239
236
|
|
|
240
|
-
private async detectEntities(
|
|
237
|
+
private async detectEntities(
|
|
238
|
+
params: DetectParams,
|
|
239
|
+
): Promise<Array<TextEntities>> {
|
|
241
240
|
try {
|
|
242
241
|
const detectEntitiesCommand = new DetectEntitiesCommand(params);
|
|
243
242
|
const data = await this.comprehendClient!.send(detectEntitiesCommand);
|
|
244
243
|
const { Entities = [] } = data || {};
|
|
245
|
-
|
|
246
244
|
return this.serializeEntitiesFromComprehend(Entities);
|
|
247
245
|
} catch (err: any) {
|
|
248
246
|
if (err.code === 'AccessDeniedException') {
|
|
@@ -256,14 +254,13 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
256
254
|
}
|
|
257
255
|
}
|
|
258
256
|
|
|
259
|
-
private serializeEntitiesFromComprehend(data: Entity[]): TextEntities
|
|
257
|
+
private serializeEntitiesFromComprehend(data: Entity[]): Array<TextEntities> {
|
|
260
258
|
let response: TextEntities[] = [];
|
|
261
259
|
if (data && Array.isArray(data)) {
|
|
262
260
|
response = data.map(({ Type: type, Text: text }) => {
|
|
263
261
|
return { type, text };
|
|
264
262
|
});
|
|
265
263
|
}
|
|
266
|
-
|
|
267
264
|
return response;
|
|
268
265
|
}
|
|
269
266
|
|
|
@@ -275,8 +272,7 @@ export class AmazonAIInterpretPredictionsProvider {
|
|
|
275
272
|
const data = await this.comprehendClient!.send(
|
|
276
273
|
detectDominantLanguageCommand,
|
|
277
274
|
);
|
|
278
|
-
const { Languages: [{ LanguageCode }] = [{
|
|
279
|
-
data ?? {};
|
|
275
|
+
const { Languages: [{ LanguageCode }] = [{}] } = ({} = data || {});
|
|
280
276
|
assertValidationError(
|
|
281
277
|
!!LanguageCode,
|
|
282
278
|
PredictionsValidationErrorCode.NoLanguage,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
TableCell,
|
|
12
12
|
} from '../types';
|
|
13
13
|
import { Block, BlockList, TextDetectionList } from '../types/AWSTypes';
|
|
14
|
-
|
|
15
14
|
import { makeCamelCase, makeCamelCaseArray } from './Utils';
|
|
16
15
|
|
|
17
16
|
function getBoundingBox(geometry?: Geometry): BoundingBox | undefined {
|
|
@@ -20,7 +19,6 @@ function getBoundingBox(geometry?: Geometry): BoundingBox | undefined {
|
|
|
20
19
|
|
|
21
20
|
function getPolygon(geometry?: Geometry): Polygon | undefined {
|
|
22
21
|
if (!geometry?.Polygon) return undefined;
|
|
23
|
-
|
|
24
22
|
return makeCamelCaseArray(Array.from(geometry.Polygon)) as Polygon;
|
|
25
23
|
}
|
|
26
24
|
|
|
@@ -71,7 +69,6 @@ export function categorizeRekognitionBlocks(
|
|
|
71
69
|
0,
|
|
72
70
|
response.text.fullText.length - 1,
|
|
73
71
|
);
|
|
74
|
-
|
|
75
72
|
return response;
|
|
76
73
|
}
|
|
77
74
|
|
|
@@ -105,9 +102,9 @@ export function categorizeTextractBlocks(
|
|
|
105
102
|
* Note that we do not map `WORD` and `TABLE` in `blockMap` because they will not be referenced by any other
|
|
106
103
|
* block except the Page block.
|
|
107
104
|
*/
|
|
108
|
-
const tableBlocks: BlockList =
|
|
109
|
-
const keyValueBlocks: BlockList =
|
|
110
|
-
const blockMap:
|
|
105
|
+
const tableBlocks: BlockList = Array();
|
|
106
|
+
const keyValueBlocks: BlockList = Array();
|
|
107
|
+
const blockMap: { [id: string]: Block } = {};
|
|
111
108
|
|
|
112
109
|
blocks.forEach(block => {
|
|
113
110
|
switch (block.BlockType) {
|
|
@@ -133,8 +130,9 @@ export function categorizeTextractBlocks(
|
|
|
133
130
|
blockMap[block.Id] = block;
|
|
134
131
|
}
|
|
135
132
|
break;
|
|
136
|
-
case 'SELECTION_ELEMENT':
|
|
137
|
-
const selectionStatus =
|
|
133
|
+
case 'SELECTION_ELEMENT':
|
|
134
|
+
const selectionStatus =
|
|
135
|
+
block.SelectionStatus === 'SELECTED' ? true : false;
|
|
138
136
|
if (!response.text.selections) response.text.selections = [];
|
|
139
137
|
response.text.selections.push({
|
|
140
138
|
selected: selectionStatus,
|
|
@@ -145,7 +143,6 @@ export function categorizeTextractBlocks(
|
|
|
145
143
|
blockMap[block.Id] = block;
|
|
146
144
|
}
|
|
147
145
|
break;
|
|
148
|
-
}
|
|
149
146
|
case 'TABLE':
|
|
150
147
|
tableBlocks.push(block);
|
|
151
148
|
break;
|
|
@@ -169,14 +166,14 @@ export function categorizeTextractBlocks(
|
|
|
169
166
|
|
|
170
167
|
// Post-process complex structures if they exist.
|
|
171
168
|
if (tableBlocks.length !== 0) {
|
|
172
|
-
const tableResponse: Table[] =
|
|
169
|
+
const tableResponse: Table[] = Array();
|
|
173
170
|
tableBlocks.forEach(table => {
|
|
174
171
|
tableResponse.push(constructTable(table, blockMap));
|
|
175
172
|
});
|
|
176
173
|
response.text.tables = tableResponse;
|
|
177
174
|
}
|
|
178
175
|
if (keyValueBlocks.length !== 0) {
|
|
179
|
-
const keyValueResponse: KeyValue[] =
|
|
176
|
+
const keyValueResponse: KeyValue[] = Array();
|
|
180
177
|
keyValueBlocks.forEach(keyValue => {
|
|
181
178
|
// We need the KeyValue blocks of EntityType = `KEY`, which has both key and value references.
|
|
182
179
|
if (keyValue.EntityTypes) {
|
|
@@ -188,7 +185,6 @@ export function categorizeTextractBlocks(
|
|
|
188
185
|
});
|
|
189
186
|
response.text.keyValues = keyValueResponse;
|
|
190
187
|
}
|
|
191
|
-
|
|
192
188
|
return response;
|
|
193
189
|
}
|
|
194
190
|
|
|
@@ -197,8 +193,12 @@ export function categorizeTextractBlocks(
|
|
|
197
193
|
* @param {Block} table - Table block that has references (`Relationships`) to its cells
|
|
198
194
|
* @param {[id: string]: Block} blockMap - Maps block Ids to blocks.
|
|
199
195
|
*/
|
|
200
|
-
function constructTable(
|
|
201
|
-
|
|
196
|
+
function constructTable(
|
|
197
|
+
table: Block,
|
|
198
|
+
blockMap: { [key: string]: Block },
|
|
199
|
+
): Table {
|
|
200
|
+
let tableMatrix: TableCell[][];
|
|
201
|
+
tableMatrix = [];
|
|
202
202
|
// visit each of the cell associated with the table's relationship.
|
|
203
203
|
for (const tableRelation of table.Relationships ?? []) {
|
|
204
204
|
for (const cellId of tableRelation.Ids ?? []) {
|
|
@@ -225,7 +225,6 @@ function constructTable(table: Block, blockMap: Record<string, Block>): Table {
|
|
|
225
225
|
const columnSize = tableMatrix[0].length;
|
|
226
226
|
const boundingBox = getBoundingBox(table.Geometry);
|
|
227
227
|
const polygon = getPolygon(table.Geometry);
|
|
228
|
-
|
|
229
228
|
// Note that we leave spanned cells undefined for distinction
|
|
230
229
|
return {
|
|
231
230
|
size: { rows: rowSize, columns: columnSize },
|
|
@@ -242,11 +241,11 @@ function constructTable(table: Block, blockMap: Record<string, Block>): Table {
|
|
|
242
241
|
*/
|
|
243
242
|
function constructKeyValue(
|
|
244
243
|
keyBlock: Block,
|
|
245
|
-
blockMap:
|
|
244
|
+
blockMap: { [key: string]: Block },
|
|
246
245
|
): KeyValue {
|
|
247
|
-
let keyText = '';
|
|
248
|
-
let valueText = '';
|
|
249
|
-
let valueSelected = false;
|
|
246
|
+
let keyText: string = '';
|
|
247
|
+
let valueText: string = '';
|
|
248
|
+
let valueSelected: boolean = false;
|
|
250
249
|
for (const keyValueRelation of keyBlock.Relationships ?? []) {
|
|
251
250
|
if (keyValueRelation.Type === 'CHILD') {
|
|
252
251
|
// relation refers to key
|
|
@@ -262,7 +261,6 @@ function constructKeyValue(
|
|
|
262
261
|
}
|
|
263
262
|
}
|
|
264
263
|
}
|
|
265
|
-
|
|
266
264
|
return {
|
|
267
265
|
key: keyText,
|
|
268
266
|
value: { text: valueText, selected: valueSelected },
|
|
@@ -278,10 +276,10 @@ function constructKeyValue(
|
|
|
278
276
|
*/
|
|
279
277
|
function extractContentsFromBlock(
|
|
280
278
|
block: Block,
|
|
281
|
-
blockMap:
|
|
279
|
+
blockMap: { [id: string]: Block },
|
|
282
280
|
): Content {
|
|
283
|
-
let words = '';
|
|
284
|
-
let isSelected = false;
|
|
281
|
+
let words: string = '';
|
|
282
|
+
let isSelected: boolean = false;
|
|
285
283
|
|
|
286
284
|
if (!block.Relationships) {
|
|
287
285
|
// some block might have no content
|
|
@@ -293,12 +291,11 @@ function extractContentsFromBlock(
|
|
|
293
291
|
if (contentBlock.BlockType === 'WORD') {
|
|
294
292
|
words += contentBlock.Text + ' ';
|
|
295
293
|
} else if (contentBlock.BlockType === 'SELECTION_ELEMENT') {
|
|
296
|
-
isSelected = contentBlock.SelectionStatus === 'SELECTED';
|
|
294
|
+
isSelected = contentBlock.SelectionStatus === 'SELECTED' ? true : false;
|
|
297
295
|
}
|
|
298
296
|
}
|
|
299
297
|
}
|
|
300
298
|
|
|
301
299
|
words = words.substr(0, words.length - 1); // remove trailing space.
|
|
302
|
-
|
|
303
300
|
return { text: words, selected: isSelected };
|
|
304
301
|
}
|