@aws-amplify/predictions 5.5.6-api-v6-models.b3abc9b.0 → 6.0.0
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 +3 -0
- package/lib/Predictions.d.ts +11 -45
- package/lib/Predictions.js +24 -132
- package/lib/errors/PredictionsError.d.ts +4 -0
- package/lib/errors/PredictionsError.js +15 -0
- package/lib/errors/types/validation.d.ts +14 -0
- package/lib/errors/types/validation.js +50 -0
- package/lib/errors/utils/assertValidationError.d.ts +2 -0
- package/lib/errors/utils/assertValidationError.js +14 -0
- package/lib/index.d.ts +2 -4
- package/lib/index.js +2 -9
- package/{lib-esm/Providers → lib/providers}/AmazonAIConvertPredictionsProvider.d.ts +6 -7
- package/lib/providers/AmazonAIConvertPredictionsProvider.js +307 -0
- package/lib/{Providers → providers}/AmazonAIIdentifyPredictionsProvider.d.ts +5 -6
- package/lib/providers/AmazonAIIdentifyPredictionsProvider.js +334 -0
- package/lib/{Providers → providers}/AmazonAIInterpretPredictionsProvider.d.ts +3 -4
- package/lib/providers/AmazonAIInterpretPredictionsProvider.js +208 -0
- package/lib/providers/IdentifyTextUtils.d.ts +16 -0
- package/lib/{Providers → providers}/IdentifyTextUtils.js +97 -148
- package/lib/{Providers → providers}/Utils.d.ts +2 -2
- package/lib/{Providers → providers}/Utils.js +11 -12
- package/lib/{Providers → providers}/index.d.ts +1 -2
- package/lib/providers/index.js +11 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/AWSTypes.d.ts +8 -9
- package/lib/types/AWSTypes.js +0 -1
- package/lib/types/Predictions.d.ts +63 -59
- package/lib/types/Predictions.js +41 -28
- package/lib/types/index.js +1 -2
- package/lib-esm/Predictions.d.ts +11 -45
- package/lib-esm/Predictions.js +23 -133
- package/lib-esm/errors/PredictionsError.d.ts +4 -0
- package/lib-esm/errors/PredictionsError.js +11 -0
- package/lib-esm/errors/types/validation.d.ts +14 -0
- package/lib-esm/errors/types/validation.js +47 -0
- package/lib-esm/errors/utils/assertValidationError.d.ts +2 -0
- package/lib-esm/errors/utils/assertValidationError.js +10 -0
- package/lib-esm/index.d.ts +2 -4
- package/lib-esm/index.js +1 -5
- package/{lib/Providers → lib-esm/providers}/AmazonAIConvertPredictionsProvider.d.ts +6 -7
- package/lib-esm/providers/AmazonAIConvertPredictionsProvider.js +303 -0
- package/lib-esm/{Providers → providers}/AmazonAIIdentifyPredictionsProvider.d.ts +5 -6
- package/lib-esm/providers/AmazonAIIdentifyPredictionsProvider.js +330 -0
- package/lib-esm/{Providers → providers}/AmazonAIInterpretPredictionsProvider.d.ts +3 -4
- package/lib-esm/providers/AmazonAIInterpretPredictionsProvider.js +204 -0
- package/lib-esm/providers/IdentifyTextUtils.d.ts +16 -0
- package/lib-esm/providers/IdentifyTextUtils.js +264 -0
- package/lib-esm/{Providers → providers}/Utils.d.ts +2 -2
- package/lib-esm/{Providers → providers}/Utils.js +10 -12
- package/lib-esm/{Providers → providers}/index.d.ts +1 -2
- package/lib-esm/{Providers → providers}/index.js +1 -3
- package/lib-esm/tsconfig.tsbuildinfo +1 -0
- package/lib-esm/types/AWSTypes.d.ts +8 -9
- package/lib-esm/types/AWSTypes.js +1 -1
- package/lib-esm/types/Predictions.d.ts +63 -59
- package/lib-esm/types/Predictions.js +34 -27
- package/lib-esm/types/index.js +0 -1
- package/package.json +39 -48
- package/src/Predictions.ts +33 -220
- package/src/errors/PredictionsError.ts +16 -0
- package/src/errors/types/validation.ts +51 -0
- package/src/errors/utils/assertValidationError.ts +18 -0
- package/src/index.ts +16 -16
- package/src/{Providers → providers}/AmazonAIConvertPredictionsProvider.ts +210 -171
- package/src/{Providers → providers}/AmazonAIIdentifyPredictionsProvider.ts +244 -246
- package/src/providers/AmazonAIInterpretPredictionsProvider.ts +293 -0
- package/src/{Providers → providers}/IdentifyTextUtils.ts +69 -52
- package/src/{Providers → providers}/Utils.ts +2 -2
- package/src/{Providers → providers}/index.ts +0 -2
- package/src/types/AWSTypes.ts +5 -6
- package/src/types/Predictions.ts +107 -62
- package/lib/.tsbuildinfo +0 -3
- package/lib/Predictions.js.map +0 -1
- package/lib/Providers/AmazonAIConvertPredictionsProvider.js +0 -377
- package/lib/Providers/AmazonAIConvertPredictionsProvider.js.map +0 -1
- package/lib/Providers/AmazonAIIdentifyPredictionsProvider.js +0 -441
- package/lib/Providers/AmazonAIIdentifyPredictionsProvider.js.map +0 -1
- package/lib/Providers/AmazonAIInterpretPredictionsProvider.js +0 -321
- package/lib/Providers/AmazonAIInterpretPredictionsProvider.js.map +0 -1
- package/lib/Providers/AmazonAIPredictionsProvider.d.ts +0 -14
- package/lib/Providers/AmazonAIPredictionsProvider.js +0 -43
- package/lib/Providers/AmazonAIPredictionsProvider.js.map +0 -1
- package/lib/Providers/IdentifyTextUtils.d.ts +0 -40
- package/lib/Providers/IdentifyTextUtils.js.map +0 -1
- package/lib/Providers/Utils.js.map +0 -1
- package/lib/Providers/index.js +0 -13
- package/lib/Providers/index.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/types/AWSTypes.js.map +0 -1
- package/lib/types/Predictions.js.map +0 -1
- package/lib/types/Providers/AbstractConvertPredictionsProvider.d.ts +0 -9
- package/lib/types/Providers/AbstractConvertPredictionsProvider.js +0 -44
- package/lib/types/Providers/AbstractConvertPredictionsProvider.js.map +0 -1
- package/lib/types/Providers/AbstractIdentifyPredictionsProvider.d.ts +0 -9
- package/lib/types/Providers/AbstractIdentifyPredictionsProvider.js +0 -44
- package/lib/types/Providers/AbstractIdentifyPredictionsProvider.js.map +0 -1
- package/lib/types/Providers/AbstractInterpretPredictionsProvider.d.ts +0 -7
- package/lib/types/Providers/AbstractInterpretPredictionsProvider.js +0 -27
- package/lib/types/Providers/AbstractInterpretPredictionsProvider.js.map +0 -1
- package/lib/types/Providers/AbstractPredictionsProvider.d.ts +0 -7
- package/lib/types/Providers/AbstractPredictionsProvider.js +0 -16
- package/lib/types/Providers/AbstractPredictionsProvider.js.map +0 -1
- package/lib/types/Providers/index.d.ts +0 -4
- package/lib/types/Providers/index.js +0 -10
- package/lib/types/Providers/index.js.map +0 -1
- package/lib/types/index.js.map +0 -1
- package/lib-esm/.tsbuildinfo +0 -3
- package/lib-esm/Predictions.js.map +0 -1
- package/lib-esm/Providers/AmazonAIConvertPredictionsProvider.js +0 -375
- package/lib-esm/Providers/AmazonAIConvertPredictionsProvider.js.map +0 -1
- package/lib-esm/Providers/AmazonAIIdentifyPredictionsProvider.js +0 -439
- package/lib-esm/Providers/AmazonAIIdentifyPredictionsProvider.js.map +0 -1
- package/lib-esm/Providers/AmazonAIInterpretPredictionsProvider.js +0 -319
- package/lib-esm/Providers/AmazonAIInterpretPredictionsProvider.js.map +0 -1
- package/lib-esm/Providers/AmazonAIPredictionsProvider.d.ts +0 -14
- package/lib-esm/Providers/AmazonAIPredictionsProvider.js +0 -41
- package/lib-esm/Providers/AmazonAIPredictionsProvider.js.map +0 -1
- package/lib-esm/Providers/IdentifyTextUtils.d.ts +0 -40
- package/lib-esm/Providers/IdentifyTextUtils.js +0 -313
- package/lib-esm/Providers/IdentifyTextUtils.js.map +0 -1
- package/lib-esm/Providers/Utils.js.map +0 -1
- package/lib-esm/Providers/index.js.map +0 -1
- package/lib-esm/index.js.map +0 -1
- package/lib-esm/types/AWSTypes.js.map +0 -1
- package/lib-esm/types/Predictions.js.map +0 -1
- package/lib-esm/types/Providers/AbstractConvertPredictionsProvider.d.ts +0 -9
- package/lib-esm/types/Providers/AbstractConvertPredictionsProvider.js +0 -42
- package/lib-esm/types/Providers/AbstractConvertPredictionsProvider.js.map +0 -1
- package/lib-esm/types/Providers/AbstractIdentifyPredictionsProvider.d.ts +0 -9
- package/lib-esm/types/Providers/AbstractIdentifyPredictionsProvider.js +0 -42
- package/lib-esm/types/Providers/AbstractIdentifyPredictionsProvider.js.map +0 -1
- package/lib-esm/types/Providers/AbstractInterpretPredictionsProvider.d.ts +0 -7
- package/lib-esm/types/Providers/AbstractInterpretPredictionsProvider.js +0 -25
- package/lib-esm/types/Providers/AbstractInterpretPredictionsProvider.js.map +0 -1
- package/lib-esm/types/Providers/AbstractPredictionsProvider.d.ts +0 -7
- package/lib-esm/types/Providers/AbstractPredictionsProvider.js +0 -14
- package/lib-esm/types/Providers/AbstractPredictionsProvider.js.map +0 -1
- package/lib-esm/types/Providers/index.d.ts +0 -4
- package/lib-esm/types/Providers/index.js +0 -7
- package/lib-esm/types/Providers/index.js.map +0 -1
- package/lib-esm/types/index.js.map +0 -1
- package/src/Providers/AmazonAIInterpretPredictionsProvider.ts +0 -281
- package/src/Providers/AmazonAIPredictionsProvider.ts +0 -69
- package/src/types/Providers/AbstractConvertPredictionsProvider.ts +0 -55
- package/src/types/Providers/AbstractIdentifyPredictionsProvider.ts +0 -57
- package/src/types/Providers/AbstractInterpretPredictionsProvider.ts +0 -26
- package/src/types/Providers/AbstractPredictionsProvider.ts +0 -20
- package/src/types/Providers/index.ts +0 -6
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Amplify, fetchAuthSession } from '@aws-amplify/core';
|
|
4
|
+
import {
|
|
5
|
+
Category,
|
|
6
|
+
PredictionsAction,
|
|
7
|
+
getAmplifyUserAgentObject,
|
|
8
|
+
} from '@aws-amplify/core/internals/utils';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
ComprehendClient,
|
|
12
|
+
DetectDominantLanguageCommand,
|
|
13
|
+
DetectEntitiesCommand,
|
|
14
|
+
DetectKeyPhrasesCommand,
|
|
15
|
+
DetectSentimentCommand,
|
|
16
|
+
DetectSyntaxCommand,
|
|
17
|
+
Entity,
|
|
18
|
+
SyntaxToken,
|
|
19
|
+
} from '@aws-sdk/client-comprehend';
|
|
20
|
+
import { PredictionsValidationErrorCode } from '../errors/types/validation';
|
|
21
|
+
import { assertValidationError } from '../errors/utils/assertValidationError';
|
|
22
|
+
import {
|
|
23
|
+
DetectParams,
|
|
24
|
+
InterpretTextInput,
|
|
25
|
+
InterpretTextOthers,
|
|
26
|
+
InterpretTextOutput,
|
|
27
|
+
KeyPhrases,
|
|
28
|
+
TextEntities,
|
|
29
|
+
TextSentiment,
|
|
30
|
+
TextSyntax,
|
|
31
|
+
isInterpretTextOthers,
|
|
32
|
+
isValidInterpretInput,
|
|
33
|
+
} from '../types';
|
|
34
|
+
|
|
35
|
+
export class AmazonAIInterpretPredictionsProvider {
|
|
36
|
+
private comprehendClient?: ComprehendClient;
|
|
37
|
+
|
|
38
|
+
getProviderName() {
|
|
39
|
+
return 'AmazonAIInterpretPredictionsProvider';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interpret(input: InterpretTextInput): Promise<InterpretTextOutput> {
|
|
43
|
+
assertValidationError(
|
|
44
|
+
isValidInterpretInput(input),
|
|
45
|
+
PredictionsValidationErrorCode.InvalidInput
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
return this.interpretText(input);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async interpretText(input: InterpretTextInput): Promise<InterpretTextOutput> {
|
|
52
|
+
const { credentials } = await fetchAuthSession();
|
|
53
|
+
assertValidationError(
|
|
54
|
+
!!credentials,
|
|
55
|
+
PredictionsValidationErrorCode.NoCredentials
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const { interpretText = {} } =
|
|
59
|
+
Amplify.getConfig().Predictions?.interpret ?? {};
|
|
60
|
+
const { region = '', defaults = {} } = interpretText;
|
|
61
|
+
const { type: defaultType = '' } = defaults;
|
|
62
|
+
|
|
63
|
+
const { text: textSource } = input;
|
|
64
|
+
const { source, type = defaultType } = textSource;
|
|
65
|
+
const { text } = source;
|
|
66
|
+
let language;
|
|
67
|
+
if (isInterpretTextOthers(textSource)) {
|
|
68
|
+
language = (textSource as InterpretTextOthers).source.language;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this.comprehendClient = new ComprehendClient({
|
|
72
|
+
credentials,
|
|
73
|
+
region,
|
|
74
|
+
customUserAgent: getAmplifyUserAgentObject({
|
|
75
|
+
category: Category.Predictions,
|
|
76
|
+
action: PredictionsAction.Interpret,
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const doAll = type === 'all';
|
|
81
|
+
|
|
82
|
+
let languageCode = language;
|
|
83
|
+
if (doAll || type === 'language') {
|
|
84
|
+
const languageDetectionParams = {
|
|
85
|
+
Text: text,
|
|
86
|
+
};
|
|
87
|
+
languageCode = await this.detectLanguage(languageDetectionParams);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
let entitiesPromise: Promise<Array<TextEntities>> | undefined;
|
|
91
|
+
if (doAll || type === 'entities') {
|
|
92
|
+
assertValidationError(
|
|
93
|
+
!!languageCode,
|
|
94
|
+
PredictionsValidationErrorCode.NoLanguage
|
|
95
|
+
);
|
|
96
|
+
const entitiesDetectionParams = {
|
|
97
|
+
Text: text,
|
|
98
|
+
LanguageCode: languageCode,
|
|
99
|
+
};
|
|
100
|
+
entitiesPromise = this.detectEntities(entitiesDetectionParams);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let sentimentPromise: Promise<TextSentiment> | undefined;
|
|
104
|
+
if (doAll || type === 'sentiment') {
|
|
105
|
+
assertValidationError(
|
|
106
|
+
!!languageCode,
|
|
107
|
+
PredictionsValidationErrorCode.NoLanguage
|
|
108
|
+
);
|
|
109
|
+
const sentimentParams = {
|
|
110
|
+
Text: text,
|
|
111
|
+
LanguageCode: languageCode,
|
|
112
|
+
};
|
|
113
|
+
sentimentPromise = this.detectSentiment(sentimentParams);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
let syntaxPromise: Promise<Array<TextSyntax>> | undefined;
|
|
117
|
+
if (doAll || type === 'syntax') {
|
|
118
|
+
assertValidationError(
|
|
119
|
+
!!languageCode,
|
|
120
|
+
PredictionsValidationErrorCode.NoLanguage
|
|
121
|
+
);
|
|
122
|
+
const syntaxParams = {
|
|
123
|
+
Text: text,
|
|
124
|
+
LanguageCode: languageCode,
|
|
125
|
+
};
|
|
126
|
+
syntaxPromise = this.detectSyntax(syntaxParams);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
let keyPhrasesPromise: Promise<KeyPhrases> | undefined;
|
|
130
|
+
if (doAll || type === 'keyPhrases') {
|
|
131
|
+
assertValidationError(
|
|
132
|
+
!!languageCode,
|
|
133
|
+
PredictionsValidationErrorCode.NoLanguage
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const keyPhrasesParams = {
|
|
137
|
+
Text: text,
|
|
138
|
+
LanguageCode: languageCode,
|
|
139
|
+
};
|
|
140
|
+
keyPhrasesPromise = this.detectKeyPhrases(keyPhrasesParams);
|
|
141
|
+
}
|
|
142
|
+
const [textEntities, sentiment, syntax, keyPhrases] = await Promise.all([
|
|
143
|
+
entitiesPromise,
|
|
144
|
+
sentimentPromise,
|
|
145
|
+
syntaxPromise,
|
|
146
|
+
keyPhrasesPromise,
|
|
147
|
+
]);
|
|
148
|
+
return {
|
|
149
|
+
textInterpretation: {
|
|
150
|
+
keyPhrases,
|
|
151
|
+
language: languageCode,
|
|
152
|
+
sentiment,
|
|
153
|
+
syntax,
|
|
154
|
+
textEntities,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
private async detectKeyPhrases(params: DetectParams): Promise<KeyPhrases> {
|
|
160
|
+
try {
|
|
161
|
+
const detectKeyPhrasesCommand = new DetectKeyPhrasesCommand(params);
|
|
162
|
+
const data = await this.comprehendClient!.send(detectKeyPhrasesCommand);
|
|
163
|
+
const { KeyPhrases = [] } = data || {};
|
|
164
|
+
return KeyPhrases.map(({ Text: text }) => {
|
|
165
|
+
return { text };
|
|
166
|
+
});
|
|
167
|
+
} catch (err: any) {
|
|
168
|
+
if (err.code === 'AccessDeniedException') {
|
|
169
|
+
throw new Error(
|
|
170
|
+
'Not authorized, did you enable Interpret Text on predictions category Amplify CLI? try: ' +
|
|
171
|
+
'amplify predictions add'
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
throw err;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private async detectSyntax(params: DetectParams): Promise<Array<TextSyntax>> {
|
|
180
|
+
try {
|
|
181
|
+
const detectSyntaxCommand = new DetectSyntaxCommand(params);
|
|
182
|
+
const data = await this.comprehendClient!.send(detectSyntaxCommand);
|
|
183
|
+
const { SyntaxTokens = [] } = data || {};
|
|
184
|
+
return this.serializeSyntaxFromComprehend(SyntaxTokens);
|
|
185
|
+
} catch (err: any) {
|
|
186
|
+
if (err.code === 'AccessDeniedException') {
|
|
187
|
+
throw new Error(
|
|
188
|
+
'Not authorized, did you enable Interpret Text on predictions category Amplify CLI? try: ' +
|
|
189
|
+
'amplify predictions add'
|
|
190
|
+
);
|
|
191
|
+
} else {
|
|
192
|
+
throw err;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private serializeSyntaxFromComprehend(
|
|
198
|
+
tokens: SyntaxToken[]
|
|
199
|
+
): Array<TextSyntax> {
|
|
200
|
+
let response: TextSyntax[] = [];
|
|
201
|
+
if (tokens && Array.isArray(tokens)) {
|
|
202
|
+
response = tokens.map(
|
|
203
|
+
({ Text: text = '', PartOfSpeech: { Tag: syntax = '' } = {} }) => {
|
|
204
|
+
return { text, syntax };
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
return response;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private async detectSentiment(params: DetectParams): Promise<TextSentiment> {
|
|
212
|
+
try {
|
|
213
|
+
const detectSentimentCommand = new DetectSentimentCommand(params);
|
|
214
|
+
const data = await this.comprehendClient!.send(detectSentimentCommand);
|
|
215
|
+
const {
|
|
216
|
+
Sentiment: predominant = '',
|
|
217
|
+
SentimentScore: {
|
|
218
|
+
Positive: positive = 0,
|
|
219
|
+
Negative: negative = 0,
|
|
220
|
+
Neutral: neutral = 0,
|
|
221
|
+
Mixed: mixed = 0,
|
|
222
|
+
} = {},
|
|
223
|
+
} = ({} = data);
|
|
224
|
+
return { predominant, positive, negative, neutral, mixed };
|
|
225
|
+
} catch (err: any) {
|
|
226
|
+
if (err.code === 'AccessDeniedException') {
|
|
227
|
+
throw new Error(
|
|
228
|
+
'Not authorized, did you enable Interpret Text on predictions category Amplify CLI? try: ' +
|
|
229
|
+
'amplify predictions add'
|
|
230
|
+
);
|
|
231
|
+
} else {
|
|
232
|
+
throw err;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private async detectEntities(
|
|
238
|
+
params: DetectParams
|
|
239
|
+
): Promise<Array<TextEntities>> {
|
|
240
|
+
try {
|
|
241
|
+
const detectEntitiesCommand = new DetectEntitiesCommand(params);
|
|
242
|
+
const data = await this.comprehendClient!.send(detectEntitiesCommand);
|
|
243
|
+
const { Entities = [] } = data || {};
|
|
244
|
+
return this.serializeEntitiesFromComprehend(Entities);
|
|
245
|
+
} catch (err: any) {
|
|
246
|
+
if (err.code === 'AccessDeniedException') {
|
|
247
|
+
throw new Error(
|
|
248
|
+
'Not authorized, did you enable Interpret Text on predictions category Amplify CLI? try: ' +
|
|
249
|
+
'amplify predictions add'
|
|
250
|
+
);
|
|
251
|
+
} else {
|
|
252
|
+
throw err;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
private serializeEntitiesFromComprehend(data: Entity[]): Array<TextEntities> {
|
|
258
|
+
let response: TextEntities[] = [];
|
|
259
|
+
if (data && Array.isArray(data)) {
|
|
260
|
+
response = data.map(({ Type: type, Text: text }) => {
|
|
261
|
+
return { type, text };
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
return response;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private async detectLanguage(params: { Text: string }): Promise<string> {
|
|
268
|
+
try {
|
|
269
|
+
const detectDominantLanguageCommand = new DetectDominantLanguageCommand(
|
|
270
|
+
params
|
|
271
|
+
);
|
|
272
|
+
const data = await this.comprehendClient!.send(
|
|
273
|
+
detectDominantLanguageCommand
|
|
274
|
+
);
|
|
275
|
+
const { Languages: [{ LanguageCode }] = [{}] } = ({} = data || {});
|
|
276
|
+
assertValidationError(
|
|
277
|
+
!!LanguageCode,
|
|
278
|
+
PredictionsValidationErrorCode.NoLanguage
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
return LanguageCode;
|
|
282
|
+
} catch (err: any) {
|
|
283
|
+
if (err.code === 'AccessDeniedException') {
|
|
284
|
+
throw new Error(
|
|
285
|
+
'Not authorized, did you enable Interpret Text on predictions category Amplify CLI? try: ' +
|
|
286
|
+
'amplify predictions add'
|
|
287
|
+
);
|
|
288
|
+
} else {
|
|
289
|
+
throw err;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import {
|
|
4
|
+
BoundingBox,
|
|
5
|
+
Content,
|
|
6
|
+
Geometry,
|
|
4
7
|
IdentifyTextOutput,
|
|
5
|
-
Table,
|
|
6
8
|
KeyValue,
|
|
7
|
-
TableCell,
|
|
8
|
-
Content,
|
|
9
|
-
BoundingBox,
|
|
10
9
|
Polygon,
|
|
11
|
-
|
|
10
|
+
Table,
|
|
11
|
+
TableCell,
|
|
12
12
|
} from '../types';
|
|
13
13
|
import { Block, BlockList, TextDetectionList } from '../types/AWSTypes';
|
|
14
|
-
import {
|
|
14
|
+
import { makeCamelCase, makeCamelCaseArray } from './Utils';
|
|
15
15
|
|
|
16
|
-
function getBoundingBox(geometry
|
|
17
|
-
|
|
18
|
-
return makeCamelCase(geometry.BoundingBox);
|
|
16
|
+
function getBoundingBox(geometry?: Geometry): BoundingBox | undefined {
|
|
17
|
+
return makeCamelCase(geometry?.BoundingBox);
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
function getPolygon(geometry
|
|
22
|
-
if (!geometry) return undefined;
|
|
23
|
-
return makeCamelCaseArray(Array.from(geometry.Polygon));
|
|
20
|
+
function getPolygon(geometry?: Geometry): Polygon | undefined {
|
|
21
|
+
if (!geometry?.Polygon) return undefined;
|
|
22
|
+
return makeCamelCaseArray(Array.from(geometry.Polygon)) as Polygon;
|
|
24
23
|
}
|
|
25
24
|
|
|
26
25
|
/**
|
|
@@ -45,12 +44,14 @@ export function categorizeRekognitionBlocks(
|
|
|
45
44
|
blocks.forEach(block => {
|
|
46
45
|
switch (block.Type) {
|
|
47
46
|
case 'LINE':
|
|
48
|
-
|
|
47
|
+
if (block.DetectedText) {
|
|
48
|
+
response.text.lines.push(block.DetectedText);
|
|
49
|
+
}
|
|
49
50
|
response.text.linesDetailed.push({
|
|
50
51
|
text: block.DetectedText,
|
|
51
52
|
polygon: getPolygon(block.Geometry),
|
|
52
53
|
boundingBox: getBoundingBox(block.Geometry),
|
|
53
|
-
page:
|
|
54
|
+
page: undefined, // rekognition doesn't have this info
|
|
54
55
|
});
|
|
55
56
|
break;
|
|
56
57
|
case 'WORD':
|
|
@@ -108,7 +109,9 @@ export function categorizeTextractBlocks(
|
|
|
108
109
|
blocks.forEach(block => {
|
|
109
110
|
switch (block.BlockType) {
|
|
110
111
|
case 'LINE':
|
|
111
|
-
|
|
112
|
+
if (block.Text) {
|
|
113
|
+
response.text.lines.push(block.Text);
|
|
114
|
+
}
|
|
112
115
|
response.text.linesDetailed.push({
|
|
113
116
|
text: block.Text,
|
|
114
117
|
polygon: getPolygon(block.Geometry),
|
|
@@ -123,7 +126,9 @@ export function categorizeTextractBlocks(
|
|
|
123
126
|
polygon: getPolygon(block.Geometry),
|
|
124
127
|
boundingBox: getBoundingBox(block.Geometry),
|
|
125
128
|
});
|
|
126
|
-
|
|
129
|
+
if (block.Id) {
|
|
130
|
+
blockMap[block.Id] = block;
|
|
131
|
+
}
|
|
127
132
|
break;
|
|
128
133
|
case 'SELECTION_ELEMENT':
|
|
129
134
|
const selectionStatus =
|
|
@@ -131,20 +136,26 @@ export function categorizeTextractBlocks(
|
|
|
131
136
|
if (!response.text.selections) response.text.selections = [];
|
|
132
137
|
response.text.selections.push({
|
|
133
138
|
selected: selectionStatus,
|
|
134
|
-
polygon: getPolygon(block.Geometry)
|
|
135
|
-
boundingBox: getBoundingBox(block.Geometry)
|
|
139
|
+
polygon: getPolygon(block.Geometry)!,
|
|
140
|
+
boundingBox: getBoundingBox(block.Geometry)!,
|
|
136
141
|
});
|
|
137
|
-
|
|
142
|
+
if (block.Id) {
|
|
143
|
+
blockMap[block.Id] = block;
|
|
144
|
+
}
|
|
138
145
|
break;
|
|
139
146
|
case 'TABLE':
|
|
140
147
|
tableBlocks.push(block);
|
|
141
148
|
break;
|
|
142
149
|
case 'KEY_VALUE_SET':
|
|
143
150
|
keyValueBlocks.push(block);
|
|
144
|
-
|
|
151
|
+
if (block.Id) {
|
|
152
|
+
blockMap[block.Id] = block;
|
|
153
|
+
}
|
|
145
154
|
break;
|
|
146
155
|
default:
|
|
147
|
-
|
|
156
|
+
if (block.Id) {
|
|
157
|
+
blockMap[block.Id] = block;
|
|
158
|
+
}
|
|
148
159
|
}
|
|
149
160
|
});
|
|
150
161
|
// remove trailing space in fullText
|
|
@@ -165,9 +176,11 @@ export function categorizeTextractBlocks(
|
|
|
165
176
|
const keyValueResponse: KeyValue[] = Array();
|
|
166
177
|
keyValueBlocks.forEach(keyValue => {
|
|
167
178
|
// We need the KeyValue blocks of EntityType = `KEY`, which has both key and value references.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
179
|
+
if (keyValue.EntityTypes) {
|
|
180
|
+
const entityTypes = Array.from(keyValue.EntityTypes);
|
|
181
|
+
if (entityTypes.indexOf('KEY') !== -1) {
|
|
182
|
+
keyValueResponse.push(constructKeyValue(keyValue, blockMap));
|
|
183
|
+
}
|
|
171
184
|
}
|
|
172
185
|
});
|
|
173
186
|
response.text.keyValues = keyValueResponse;
|
|
@@ -180,40 +193,44 @@ export function categorizeTextractBlocks(
|
|
|
180
193
|
* @param {Block} table - Table block that has references (`Relationships`) to its cells
|
|
181
194
|
* @param {[id: string]: Block} blockMap - Maps block Ids to blocks.
|
|
182
195
|
*/
|
|
183
|
-
|
|
196
|
+
function constructTable(
|
|
184
197
|
table: Block,
|
|
185
198
|
blockMap: { [key: string]: Block }
|
|
186
199
|
): Table {
|
|
187
200
|
let tableMatrix: TableCell[][];
|
|
188
201
|
tableMatrix = [];
|
|
189
202
|
// visit each of the cell associated with the table's relationship.
|
|
190
|
-
for (const tableRelation of table.Relationships) {
|
|
191
|
-
for (const cellId of tableRelation.Ids) {
|
|
203
|
+
for (const tableRelation of table.Relationships ?? []) {
|
|
204
|
+
for (const cellId of tableRelation.Ids ?? []) {
|
|
192
205
|
const cellBlock: Block = blockMap[cellId];
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
206
|
+
if (cellBlock.RowIndex && cellBlock.ColumnIndex) {
|
|
207
|
+
const row = cellBlock.RowIndex - 1; // textract starts indexing at 1, so subtract it by 1.
|
|
208
|
+
const col = cellBlock.ColumnIndex - 1; // textract starts indexing at 1, so subtract it by 1.
|
|
209
|
+
// extract data contained inside the cell.
|
|
210
|
+
const content = extractContentsFromBlock(cellBlock, blockMap);
|
|
211
|
+
const cell: TableCell = {
|
|
212
|
+
text: content.text,
|
|
213
|
+
boundingBox: getBoundingBox(cellBlock.Geometry),
|
|
214
|
+
polygon: getPolygon(cellBlock.Geometry),
|
|
215
|
+
selected: content.selected,
|
|
216
|
+
rowSpan: cellBlock.RowSpan,
|
|
217
|
+
columnSpan: cellBlock.ColumnSpan,
|
|
218
|
+
};
|
|
219
|
+
if (!tableMatrix[row]) tableMatrix[row] = [];
|
|
220
|
+
tableMatrix[row][col] = cell;
|
|
221
|
+
}
|
|
207
222
|
}
|
|
208
223
|
}
|
|
209
224
|
const rowSize = tableMatrix.length;
|
|
210
225
|
const columnSize = tableMatrix[0].length;
|
|
226
|
+
const boundingBox = getBoundingBox(table.Geometry);
|
|
227
|
+
const polygon = getPolygon(table.Geometry);
|
|
211
228
|
// Note that we leave spanned cells undefined for distinction
|
|
212
229
|
return {
|
|
213
230
|
size: { rows: rowSize, columns: columnSize },
|
|
214
231
|
table: tableMatrix,
|
|
215
|
-
boundingBox
|
|
216
|
-
polygon
|
|
232
|
+
boundingBox,
|
|
233
|
+
polygon,
|
|
217
234
|
};
|
|
218
235
|
}
|
|
219
236
|
|
|
@@ -222,24 +239,24 @@ export function constructTable(
|
|
|
222
239
|
* @param {Block} KeyValue - KeyValue block that has references (`Relationships`) to its children.
|
|
223
240
|
* @param {[id: string]: Block} blockMap - Maps block Ids to blocks.
|
|
224
241
|
*/
|
|
225
|
-
|
|
242
|
+
function constructKeyValue(
|
|
226
243
|
keyBlock: Block,
|
|
227
244
|
blockMap: { [key: string]: Block }
|
|
228
245
|
): KeyValue {
|
|
229
246
|
let keyText: string = '';
|
|
230
247
|
let valueText: string = '';
|
|
231
|
-
let valueSelected: boolean;
|
|
232
|
-
for (const keyValueRelation of keyBlock.Relationships) {
|
|
248
|
+
let valueSelected: boolean = false;
|
|
249
|
+
for (const keyValueRelation of keyBlock.Relationships ?? []) {
|
|
233
250
|
if (keyValueRelation.Type === 'CHILD') {
|
|
234
251
|
// relation refers to key
|
|
235
252
|
const contents = extractContentsFromBlock(keyBlock, blockMap);
|
|
236
|
-
keyText = contents.text;
|
|
253
|
+
keyText = contents.text ?? '';
|
|
237
254
|
} else if (keyValueRelation.Type === 'VALUE') {
|
|
238
255
|
// relation refers to value
|
|
239
|
-
for (const valueId of keyValueRelation.Ids) {
|
|
256
|
+
for (const valueId of keyValueRelation.Ids ?? []) {
|
|
240
257
|
const valueBlock = blockMap[valueId];
|
|
241
258
|
const contents = extractContentsFromBlock(valueBlock, blockMap);
|
|
242
|
-
valueText = contents.text;
|
|
259
|
+
valueText = contents.text ?? '';
|
|
243
260
|
if (contents.selected != null) valueSelected = contents.selected;
|
|
244
261
|
}
|
|
245
262
|
}
|
|
@@ -257,19 +274,19 @@ export function constructKeyValue(
|
|
|
257
274
|
* @param {Block}} block - Block that we want to extract contents from.
|
|
258
275
|
* @param {[id: string]: Block} blockMap - Maps block Ids to blocks.
|
|
259
276
|
*/
|
|
260
|
-
|
|
277
|
+
function extractContentsFromBlock(
|
|
261
278
|
block: Block,
|
|
262
279
|
blockMap: { [id: string]: Block }
|
|
263
280
|
): Content {
|
|
264
281
|
let words: string = '';
|
|
265
|
-
let isSelected: boolean;
|
|
282
|
+
let isSelected: boolean = false;
|
|
266
283
|
|
|
267
284
|
if (!block.Relationships) {
|
|
268
285
|
// some block might have no content
|
|
269
286
|
return { text: '', selected: undefined };
|
|
270
287
|
}
|
|
271
288
|
for (const relation of block.Relationships) {
|
|
272
|
-
for (const contentId of relation.Ids) {
|
|
289
|
+
for (const contentId of relation.Ids ?? []) {
|
|
273
290
|
const contentBlock = blockMap[contentId];
|
|
274
291
|
if (contentBlock.BlockType === 'WORD') {
|
|
275
292
|
words += contentBlock.Text + ' ';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Changes object keys to camel case. If optional parameter `keys` is given, then we extract only the
|
|
5
5
|
* keys specified in `keys`.
|
|
6
6
|
*/
|
|
7
|
-
export function makeCamelCase(obj
|
|
7
|
+
export function makeCamelCase(obj?: any, keys?: string[]) {
|
|
8
8
|
if (!obj) return undefined;
|
|
9
9
|
const newObj = {};
|
|
10
10
|
const keysToRename = keys ? keys : Object.keys(obj);
|
|
@@ -21,7 +21,7 @@ export function makeCamelCase(obj: object, keys?: string[]) {
|
|
|
21
21
|
/**
|
|
22
22
|
* Given an array of object, call makeCamelCase(...) on each option.
|
|
23
23
|
*/
|
|
24
|
-
export function makeCamelCaseArray(objArr
|
|
24
|
+
export function makeCamelCaseArray(objArr?: object[], keys?: string[]) {
|
|
25
25
|
if (!objArr) return undefined;
|
|
26
26
|
return objArr.map(obj => makeCamelCase(obj, keys));
|
|
27
27
|
}
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
import { AmazonAIConvertPredictionsProvider } from './AmazonAIConvertPredictionsProvider';
|
|
4
4
|
import { AmazonAIIdentifyPredictionsProvider } from './AmazonAIIdentifyPredictionsProvider';
|
|
5
5
|
import { AmazonAIInterpretPredictionsProvider } from './AmazonAIInterpretPredictionsProvider';
|
|
6
|
-
import { AmazonAIPredictionsProvider } from './AmazonAIPredictionsProvider';
|
|
7
6
|
export {
|
|
8
7
|
AmazonAIConvertPredictionsProvider,
|
|
9
8
|
AmazonAIIdentifyPredictionsProvider,
|
|
10
9
|
AmazonAIInterpretPredictionsProvider,
|
|
11
|
-
AmazonAIPredictionsProvider,
|
|
12
10
|
};
|
package/src/types/AWSTypes.ts
CHANGED
|
@@ -83,7 +83,7 @@ export interface Block {
|
|
|
83
83
|
|
|
84
84
|
export type TextDetectionList = TextDetection[];
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
interface TextDetection {
|
|
87
87
|
/**
|
|
88
88
|
* <p>The word or line of text recognized by Amazon Rekognition. </p>
|
|
89
89
|
*/
|
|
@@ -127,9 +127,8 @@ export interface Image {
|
|
|
127
127
|
S3Object?: S3Object;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
export interface S3Object {
|
|
130
|
+
type S3Bucket = string;
|
|
131
|
+
interface S3Object {
|
|
133
132
|
/**
|
|
134
133
|
* Name of the S3 bucket.
|
|
135
134
|
*/
|
|
@@ -143,8 +142,8 @@ export interface S3Object {
|
|
|
143
142
|
*/
|
|
144
143
|
Version?: S3ObjectVersion;
|
|
145
144
|
}
|
|
146
|
-
|
|
147
|
-
|
|
145
|
+
type S3ObjectName = string;
|
|
146
|
+
type S3ObjectVersion = string;
|
|
148
147
|
|
|
149
148
|
/**
|
|
150
149
|
* <p>The input document, either as bytes or as an S3 object.</p> <p>You pass image bytes to an Amazon Textract API operation by using the <code>Bytes</code> property. For example, you would use the <code>Bytes</code> property to pass a document loaded from a local file system. Image bytes passed by using the <code>Bytes</code> property must be base64 encoded. Your code might not need to encode document file bytes if you're using an AWS SDK to call Amazon Textract API operations. </p> <p>You pass images stored in an S3 bucket to an Amazon Textract API operation by using the <code>S3Object</code> property. Documents stored in an S3 bucket don't need to be base64 encoded.</p> <p>The AWS Region for the S3 bucket that contains the S3 object must match the AWS Region that you use for Amazon Textract operations.</p> <p>If you use the AWS CLI to call Amazon Textract operations, passing image bytes using the Bytes property isn't supported. You must first upload the document to an Amazon S3 bucket, and then call the operation using the S3Object property.</p> <p>For Amazon Textract to process an S3 object, the user must have permission to access the S3 object. </p>
|