askui 0.7.1 → 0.7.2
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/core/annotation/annotation-json.d.ts +5 -0
- package/dist/cjs/core/annotation/annotation-json.js +2 -0
- package/dist/cjs/core/inference-response/inference-response.d.ts +7 -11
- package/dist/cjs/core/inference-response/inference-response.js +8 -13
- package/dist/cjs/core/inference-response/invalid-model-type-error.d.ts +4 -0
- package/dist/cjs/core/inference-response/invalid-model-type-error.js +9 -0
- package/dist/cjs/core/inference-response/model-type.d.ts +1 -0
- package/dist/cjs/core/inference-response/model-type.js +2 -0
- package/dist/cjs/core/model/test-case-dto/custom-element.spec.d.ts +1 -0
- package/dist/cjs/core/model/test-case-dto/custom-element.spec.js +53 -0
- package/dist/cjs/execution/dsl.spec.d.ts +1 -0
- package/dist/cjs/execution/dsl.spec.js +75 -0
- package/dist/cjs/execution/inference-client.d.ts +1 -0
- package/dist/cjs/execution/inference-client.js +17 -8
- package/dist/cjs/execution/read-environment-credentials.spec.d.ts +1 -0
- package/dist/cjs/execution/read-environment-credentials.spec.js +11 -0
- package/dist/cjs/lib/ui-controller-args.spec.d.ts +1 -0
- package/dist/cjs/lib/ui-controller-args.spec.js +23 -0
- package/dist/cjs/utils/http/credentials.spec.d.ts +1 -0
- package/dist/cjs/utils/http/credentials.spec.js +11 -0
- package/dist/cjs/utils/http/http-client-got.d.ts +5 -1
- package/dist/cjs/utils/http/http-client-got.js +12 -4
- package/dist/esm/core/annotation/annotation-json.d.ts +5 -0
- package/dist/esm/core/annotation/annotation-json.js +1 -0
- package/dist/esm/core/inference-response/inference-response.d.ts +7 -11
- package/dist/esm/core/inference-response/inference-response.js +8 -13
- package/dist/esm/core/inference-response/invalid-model-type-error.d.ts +4 -0
- package/dist/esm/core/inference-response/invalid-model-type-error.js +5 -0
- package/dist/esm/core/inference-response/model-type.d.ts +1 -0
- package/dist/esm/core/inference-response/model-type.js +1 -0
- package/dist/esm/core/model/test-case-dto/custom-element.spec.d.ts +1 -0
- package/dist/esm/core/model/test-case-dto/custom-element.spec.js +51 -0
- package/dist/esm/execution/dsl.spec.d.ts +1 -0
- package/dist/esm/execution/dsl.spec.js +73 -0
- package/dist/esm/execution/inference-client.d.ts +1 -0
- package/dist/esm/execution/inference-client.js +17 -8
- package/dist/esm/execution/read-environment-credentials.spec.d.ts +1 -0
- package/dist/esm/execution/read-environment-credentials.spec.js +9 -0
- package/dist/esm/lib/ui-controller-args.spec.d.ts +1 -0
- package/dist/esm/lib/ui-controller-args.spec.js +21 -0
- package/dist/esm/utils/http/credentials.spec.d.ts +1 -0
- package/dist/esm/utils/http/credentials.spec.js +9 -0
- package/dist/esm/utils/http/http-client-got.d.ts +5 -1
- package/dist/esm/utils/http/http-client-got.js +12 -4
- package/package.json +1 -1
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { ControlCommand } from '../ui-control-commands/control-command';
|
|
2
2
|
import { Annotation } from '../annotation/annotation';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
static fromJson(json: unknown, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
8
|
-
static createModels(type: string, data: ControlCommand | Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
9
|
-
static models: Models;
|
|
3
|
+
import { ModelType } from './model-type';
|
|
4
|
+
export interface InferenceResponseBody {
|
|
5
|
+
type: ModelType;
|
|
6
|
+
data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation;
|
|
10
7
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
COMMANDS:
|
|
8
|
+
export declare class InferenceResponse {
|
|
9
|
+
static fromJson(json: InferenceResponseBody, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
10
|
+
static createModels(type: ModelType, data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
14
11
|
}
|
|
15
|
-
export {};
|
|
@@ -3,23 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.InferenceResponse = void 0;
|
|
4
4
|
const control_command_1 = require("../ui-control-commands/control-command");
|
|
5
5
|
const annotation_1 = require("../annotation/annotation");
|
|
6
|
+
const invalid_model_type_error_1 = require("./invalid-model-type-error");
|
|
6
7
|
class InferenceResponse {
|
|
7
|
-
constructor(type, data) {
|
|
8
|
-
this.type = type;
|
|
9
|
-
this.data = data;
|
|
10
|
-
}
|
|
11
8
|
static fromJson(json, resizeRatio = 1, image) {
|
|
12
|
-
|
|
13
|
-
return this.createModels(inferenceResponse.type, inferenceResponse.data, resizeRatio, image);
|
|
9
|
+
return this.createModels(json.type, json.data, resizeRatio, image);
|
|
14
10
|
}
|
|
15
11
|
static createModels(type, data, resizeRatio, image) {
|
|
16
|
-
|
|
12
|
+
if (type === 'COMMANDS')
|
|
13
|
+
return control_command_1.ControlCommand.fromJson(data, resizeRatio);
|
|
14
|
+
if (type === 'DETECTED_ELEMENTS') {
|
|
15
|
+
return annotation_1.Annotation.fromJson({ image, detected_elements: data.detected_elements }, resizeRatio);
|
|
16
|
+
}
|
|
17
|
+
throw new invalid_model_type_error_1.InvalidModelTypeError(type);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
exports.InferenceResponse = InferenceResponse;
|
|
20
|
-
InferenceResponse.models = {
|
|
21
|
-
DETECTED_ELEMENTS: (data, resizeRatio, image) => annotation_1.Annotation
|
|
22
|
-
.fromJson({ image, detected_elements: data.detected_elements }, resizeRatio),
|
|
23
|
-
COMMANDS: (data, resizeRatio) => control_command_1.ControlCommand
|
|
24
|
-
.fromJson(data, resizeRatio),
|
|
25
|
-
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InvalidModelTypeError = void 0;
|
|
4
|
+
class InvalidModelTypeError extends Error {
|
|
5
|
+
constructor(type) {
|
|
6
|
+
super(`Invalid model type: ${type}`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.InvalidModelTypeError = InvalidModelTypeError;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type ModelType = 'DETECTED_ELEMENTS' | 'COMMANDS';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const custom_element_1 = require("./custom-element");
|
|
13
|
+
const base64ImageString = 'data:image/png;base64,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';
|
|
14
|
+
describe('CustomElement', () => {
|
|
15
|
+
describe('fromJsonWithImagePathOrImage', () => {
|
|
16
|
+
test('should return CustomElement if CustomElement created from JSON is valid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
17
|
+
const expected = new custom_element_1.CustomElement(base64ImageString, 'Dummy_element', 0.7, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
18
|
+
const actual = yield custom_element_1.CustomElement.fromJsonWithImagePathOrImage({
|
|
19
|
+
customImage: base64ImageString,
|
|
20
|
+
name: 'Dummy_element',
|
|
21
|
+
threshold: 0.7,
|
|
22
|
+
rotationDegreePerStep: 10,
|
|
23
|
+
imageCompareFormat: 'RGB',
|
|
24
|
+
mask: [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }],
|
|
25
|
+
});
|
|
26
|
+
expect(actual).toStrictEqual(expected);
|
|
27
|
+
}));
|
|
28
|
+
test('should throw ValidationError if threshold is invalid', () => {
|
|
29
|
+
expect(() => {
|
|
30
|
+
const customElement = new custom_element_1.CustomElement(base64ImageString, 'Dummy_element', 1.1, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
31
|
+
customElement.validate();
|
|
32
|
+
}).toThrow('threshold must be less than or equal to 1');
|
|
33
|
+
});
|
|
34
|
+
test('should throw ValidationError if rotationDegreePerStep is invalid', () => {
|
|
35
|
+
expect(() => {
|
|
36
|
+
const customElement = new custom_element_1.CustomElement(base64ImageString, 'Dummy_element', 0.9, -90, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
37
|
+
customElement.validate();
|
|
38
|
+
}).toThrow('rotationDegreePerStep must be greater than or equal to 0');
|
|
39
|
+
});
|
|
40
|
+
test('should throw ValidationError if mask is invalid', () => {
|
|
41
|
+
expect(() => {
|
|
42
|
+
const customElement = new custom_element_1.CustomElement(base64ImageString, 'Dummy_element', 0.9, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }]);
|
|
43
|
+
customElement.validate();
|
|
44
|
+
}).toThrow('mask must contain at least 3 points');
|
|
45
|
+
});
|
|
46
|
+
test('should throw ValidationError if mask and threshold are both invalid', () => {
|
|
47
|
+
expect(() => {
|
|
48
|
+
const customElement = new custom_element_1.CustomElement(base64ImageString, 'Dummy_element', 90, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }]);
|
|
49
|
+
customElement.validate();
|
|
50
|
+
}).toThrow('threshold must be less than or equal to 1, mask must contain at least 3 points');
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const dsl_1 = require("./dsl");
|
|
13
|
+
class TestCommand extends dsl_1.FluentCommand {
|
|
14
|
+
// eslint-disable-next-line class-methods-use-this
|
|
15
|
+
fluentCommandExecutor(instruction, customElements) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.log(`${instruction} ${customElements}`);
|
|
19
|
+
return Promise.resolve();
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
describe('DSL', () => {
|
|
24
|
+
describe('custom element', () => {
|
|
25
|
+
test('should call exec function with zero custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
const underTest = new TestCommand();
|
|
27
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
28
|
+
yield underTest.click().button()
|
|
29
|
+
.exec();
|
|
30
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on button', []);
|
|
31
|
+
}));
|
|
32
|
+
test('should call exec function with one custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const underTest = new TestCommand();
|
|
34
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
35
|
+
yield underTest.click().customElement({
|
|
36
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
37
|
+
imageCompareFormat: 'grayscale',
|
|
38
|
+
name: 'custom element 1',
|
|
39
|
+
}).button()
|
|
40
|
+
.exec();
|
|
41
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on custom element button', [{
|
|
42
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
43
|
+
imageCompareFormat: 'grayscale',
|
|
44
|
+
name: 'custom element 1',
|
|
45
|
+
}]);
|
|
46
|
+
}));
|
|
47
|
+
test('should call exec function with two custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
const underTest = new TestCommand();
|
|
49
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
50
|
+
yield underTest.click().customElement({
|
|
51
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
52
|
+
imageCompareFormat: 'grayscale',
|
|
53
|
+
name: 'custom element 1',
|
|
54
|
+
})
|
|
55
|
+
.button()
|
|
56
|
+
.customElement({
|
|
57
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
58
|
+
imageCompareFormat: 'grayscale',
|
|
59
|
+
name: 'custom element 2',
|
|
60
|
+
})
|
|
61
|
+
.exec();
|
|
62
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on custom element button custom element', [{
|
|
63
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
64
|
+
imageCompareFormat: 'grayscale',
|
|
65
|
+
name: 'custom element 1',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
69
|
+
imageCompareFormat: 'grayscale',
|
|
70
|
+
name: 'custom element 2',
|
|
71
|
+
},
|
|
72
|
+
]);
|
|
73
|
+
}));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -14,6 +14,7 @@ export declare class InferenceClient {
|
|
|
14
14
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
15
15
|
private resizeIfNeeded;
|
|
16
16
|
inference(customElements?: CustomElement[], image?: string, instruction?: string): Promise<ControlCommand | Annotation>;
|
|
17
|
+
private static logMetaInformation;
|
|
17
18
|
predictControlCommand(instruction: string, customElements?: CustomElement[], image?: string): Promise<ControlCommand>;
|
|
18
19
|
getDetectedElements(instruction: string, image: string, customElements?: CustomElement[]): Promise<DetectedElement[]>;
|
|
19
20
|
predictImageAnnotation(image: string, customElements?: CustomElement[]): Promise<Annotation>;
|
|
@@ -19,6 +19,7 @@ const annotation_1 = require("../core/annotation/annotation");
|
|
|
19
19
|
const transformations_1 = require("../utils/transformations");
|
|
20
20
|
const inference_response_error_1 = require("./inference-response-error");
|
|
21
21
|
const config_error_1 = require("./config-error");
|
|
22
|
+
const logger_1 = require("../lib/logger");
|
|
22
23
|
class InferenceClient {
|
|
23
24
|
constructor(baseUrl, httpClient, resize, workspaceId, apiVersion = 'v3') {
|
|
24
25
|
this.baseUrl = baseUrl;
|
|
@@ -27,7 +28,9 @@ class InferenceClient {
|
|
|
27
28
|
this.workspaceId = workspaceId;
|
|
28
29
|
this.apiVersion = apiVersion;
|
|
29
30
|
const versionedBaseUrl = (0, url_join_1.default)(this.baseUrl, 'api', this.apiVersion);
|
|
30
|
-
this.url = workspaceId
|
|
31
|
+
this.url = workspaceId
|
|
32
|
+
? (0, url_join_1.default)(versionedBaseUrl, 'workspaces', workspaceId)
|
|
33
|
+
: versionedBaseUrl;
|
|
31
34
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
32
35
|
throw new config_error_1.ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
33
36
|
}
|
|
@@ -36,17 +39,17 @@ class InferenceClient {
|
|
|
36
39
|
isImageRequired(instruction) {
|
|
37
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
41
|
const url = (0, url_join_1.default)(this.url, 'instruction', 'is-image-required');
|
|
39
|
-
const
|
|
42
|
+
const requestBody = {
|
|
40
43
|
instruction,
|
|
41
44
|
};
|
|
42
|
-
const
|
|
43
|
-
return
|
|
45
|
+
const response = yield this.httpClient.post(url, requestBody);
|
|
46
|
+
return response.body.isImageRequired;
|
|
44
47
|
});
|
|
45
48
|
}
|
|
46
49
|
// eslint-disable-next-line class-methods-use-this
|
|
47
50
|
resizeIfNeeded(customElements, image) {
|
|
48
51
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
if (!
|
|
52
|
+
if (!image || customElements.length > 0 || this.resize === undefined) {
|
|
50
53
|
return { base64Image: image, resizeRatio: 1 };
|
|
51
54
|
}
|
|
52
55
|
return (0, transformations_1.resizeBase64ImageWithSameRatio)(image, this.resize);
|
|
@@ -55,16 +58,22 @@ class InferenceClient {
|
|
|
55
58
|
inference(customElements = [], image, instruction) {
|
|
56
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
60
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
58
|
-
const
|
|
61
|
+
const requestBody = {
|
|
59
62
|
image: resizedImage.base64Image,
|
|
60
63
|
instruction,
|
|
61
64
|
customElements,
|
|
62
65
|
};
|
|
63
66
|
const url = (0, url_join_1.default)(this.url, 'inference');
|
|
64
|
-
const
|
|
65
|
-
|
|
67
|
+
const response = yield this.httpClient.post(url, requestBody);
|
|
68
|
+
InferenceClient.logMetaInformation(response);
|
|
69
|
+
return ui_control_commands_1.InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
66
70
|
});
|
|
67
71
|
}
|
|
72
|
+
static logMetaInformation(response) {
|
|
73
|
+
if (response.headers['askui-usage-warnings'] !== undefined) {
|
|
74
|
+
logger_1.logger.warn(response.headers['askui-usage-warnings']);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
68
77
|
predictControlCommand(instruction, customElements = [], image) {
|
|
69
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
79
|
const inferenceResponse = yield this.inference(customElements, image, instruction);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const read_environment_credentials_1 = require("./read-environment-credentials");
|
|
4
|
+
describe('envCredentials()', () => {
|
|
5
|
+
test('should read the credentials from the environment variables', () => {
|
|
6
|
+
process.env['ASKUI_TOKEN'] = 'token';
|
|
7
|
+
process.env['ASKUI_WORKSPACE_ID'] = 'id123';
|
|
8
|
+
const credentialsFromTheEnv = (0, read_environment_credentials_1.envCredentials)();
|
|
9
|
+
expect(credentialsFromTheEnv).toStrictEqual({ workspaceId: 'id123', token: 'token' });
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ui_controller_args_1 = require("./ui-controller-args");
|
|
4
|
+
describe('createCliFlagsFromArgs()', () => {
|
|
5
|
+
test('test createCliFlagsFromArgs should return -d 0 as default output', () => {
|
|
6
|
+
const expected = ['-d 0', '-p 6769', '--action_wait_time 1000', '--host 127.0.0.1', '-m ', '--log-level debug'];
|
|
7
|
+
const argsWithDefaults = (0, ui_controller_args_1.createArgsWithDefaults)();
|
|
8
|
+
const actual = (0, ui_controller_args_1.createCliFlagsFromArgs)(argsWithDefaults);
|
|
9
|
+
expect(actual).toStrictEqual(expected);
|
|
10
|
+
});
|
|
11
|
+
test('test createCliFlagsFromArgs output should include -d 0 when no display was selected', () => {
|
|
12
|
+
const expected = ['-d 0', '-p 6777', '--action_wait_time 1000', '--host 0.0.0.0', '-m ', '--log-level debug'];
|
|
13
|
+
const argsWithDefaults = (0, ui_controller_args_1.createArgsWithDefaults)({ port: 6777, host: '0.0.0.0' });
|
|
14
|
+
const actual = (0, ui_controller_args_1.createCliFlagsFromArgs)(argsWithDefaults);
|
|
15
|
+
expect(actual).toStrictEqual(expected);
|
|
16
|
+
});
|
|
17
|
+
test('test createCliFlagsFromArgs output should include the display that was selected ', () => {
|
|
18
|
+
const expected = ['-d 99', '-p 6777', '--action_wait_time 1000', '--host 0.0.0.0', '-m ', '--log-level debug'];
|
|
19
|
+
const argsWithDefaults = (0, ui_controller_args_1.createArgsWithDefaults)({ port: 6777, host: '0.0.0.0', display: 99 });
|
|
20
|
+
const actual = (0, ui_controller_args_1.createCliFlagsFromArgs)(argsWithDefaults);
|
|
21
|
+
expect(actual).toStrictEqual(expected);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const credentials_1 = require("./credentials");
|
|
4
|
+
describe('Credentials', () => {
|
|
5
|
+
describe('base64Encoded()', () => {
|
|
6
|
+
test('should return base64-encoded credentials', () => {
|
|
7
|
+
const credentials = new credentials_1.Credentials('password');
|
|
8
|
+
expect(credentials.base64Encoded).toBe('cGFzc3dvcmQ=');
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { OptionsOfJSONResponseBody } from 'got';
|
|
2
3
|
import http from 'http';
|
|
3
4
|
import https from 'https';
|
|
@@ -17,6 +18,9 @@ export declare class HttpClientGot {
|
|
|
17
18
|
} | undefined);
|
|
18
19
|
private initHeaders;
|
|
19
20
|
private injectHeadersAndCookies;
|
|
20
|
-
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<
|
|
21
|
+
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
22
|
+
headers: http.IncomingHttpHeaders;
|
|
23
|
+
body: T;
|
|
24
|
+
}>;
|
|
21
25
|
get<T>(url: string, options?: OptionsOfJSONResponseBody): Promise<T>;
|
|
22
26
|
}
|
|
@@ -30,18 +30,26 @@ class HttpClientGot {
|
|
|
30
30
|
}
|
|
31
31
|
initHeaders(token, customHeaders = {}) {
|
|
32
32
|
const credentials = token ? new credentials_1.Credentials(token) : undefined;
|
|
33
|
-
this.headers = Object.assign(Object.assign({}, (credentials
|
|
33
|
+
this.headers = Object.assign(Object.assign({}, (credentials
|
|
34
|
+
? { Authorization: `Basic ${credentials === null || credentials === void 0 ? void 0 : credentials.base64Encoded}` }
|
|
35
|
+
: {})), customHeaders);
|
|
34
36
|
}
|
|
35
37
|
injectHeadersAndCookies(url, options) {
|
|
36
38
|
const cookieJar = new tough_cookie_1.CookieJar();
|
|
37
|
-
Object.keys(this.cookies)
|
|
39
|
+
Object.keys(this.cookies)
|
|
40
|
+
.map((key) => `${key}=${this.cookies[key]}`)
|
|
41
|
+
.forEach((cookie) => {
|
|
38
42
|
cookieJar.setCookieSync(cookie, url);
|
|
39
43
|
});
|
|
40
44
|
return Object.assign(Object.assign({}, options), { headers: this.headers, cookieJar });
|
|
41
45
|
}
|
|
42
46
|
post(url, data) {
|
|
43
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
-
const options = this.injectHeadersAndCookies(url, {
|
|
48
|
+
const options = this.injectHeadersAndCookies(url, {
|
|
49
|
+
json: data,
|
|
50
|
+
responseType: 'json',
|
|
51
|
+
throwHttpErrors: false,
|
|
52
|
+
});
|
|
45
53
|
const { body, statusCode, headers } = yield this.askuiGot.post(url, options);
|
|
46
54
|
if (headers['deprecation'] !== undefined) {
|
|
47
55
|
lib_1.logger.warn(headers['deprecation']);
|
|
@@ -49,7 +57,7 @@ class HttpClientGot {
|
|
|
49
57
|
if (statusCode !== 200) {
|
|
50
58
|
throw (0, custom_errors_1.httpClientErrorHandler)(statusCode, JSON.stringify(body));
|
|
51
59
|
}
|
|
52
|
-
return body;
|
|
60
|
+
return { headers, body };
|
|
53
61
|
});
|
|
54
62
|
}
|
|
55
63
|
get(url, options = { responseType: 'json' }) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import { ControlCommand } from '../ui-control-commands/control-command';
|
|
2
2
|
import { Annotation } from '../annotation/annotation';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
static fromJson(json: unknown, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
8
|
-
static createModels(type: string, data: ControlCommand | Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
9
|
-
static models: Models;
|
|
3
|
+
import { ModelType } from './model-type';
|
|
4
|
+
export interface InferenceResponseBody {
|
|
5
|
+
type: ModelType;
|
|
6
|
+
data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation;
|
|
10
7
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
COMMANDS:
|
|
8
|
+
export declare class InferenceResponse {
|
|
9
|
+
static fromJson(json: InferenceResponseBody, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
10
|
+
static createModels(type: ModelType, data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
14
11
|
}
|
|
15
|
-
export {};
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import { ControlCommand } from '../ui-control-commands/control-command';
|
|
2
2
|
import { Annotation } from '../annotation/annotation';
|
|
3
|
+
import { InvalidModelTypeError } from './invalid-model-type-error';
|
|
3
4
|
export class InferenceResponse {
|
|
4
|
-
constructor(type, data) {
|
|
5
|
-
this.type = type;
|
|
6
|
-
this.data = data;
|
|
7
|
-
}
|
|
8
5
|
static fromJson(json, resizeRatio = 1, image) {
|
|
9
|
-
|
|
10
|
-
return this.createModels(inferenceResponse.type, inferenceResponse.data, resizeRatio, image);
|
|
6
|
+
return this.createModels(json.type, json.data, resizeRatio, image);
|
|
11
7
|
}
|
|
12
8
|
static createModels(type, data, resizeRatio, image) {
|
|
13
|
-
|
|
9
|
+
if (type === 'COMMANDS')
|
|
10
|
+
return ControlCommand.fromJson(data, resizeRatio);
|
|
11
|
+
if (type === 'DETECTED_ELEMENTS') {
|
|
12
|
+
return Annotation.fromJson({ image, detected_elements: data.detected_elements }, resizeRatio);
|
|
13
|
+
}
|
|
14
|
+
throw new InvalidModelTypeError(type);
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
|
-
InferenceResponse.models = {
|
|
17
|
-
DETECTED_ELEMENTS: (data, resizeRatio, image) => Annotation
|
|
18
|
-
.fromJson({ image, detected_elements: data.detected_elements }, resizeRatio),
|
|
19
|
-
COMMANDS: (data, resizeRatio) => ControlCommand
|
|
20
|
-
.fromJson(data, resizeRatio),
|
|
21
|
-
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare type ModelType = 'DETECTED_ELEMENTS' | 'COMMANDS';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { CustomElement } from './custom-element';
|
|
11
|
+
const base64ImageString = 'data:image/png;base64,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';
|
|
12
|
+
describe('CustomElement', () => {
|
|
13
|
+
describe('fromJsonWithImagePathOrImage', () => {
|
|
14
|
+
test('should return CustomElement if CustomElement created from JSON is valid', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
const expected = new CustomElement(base64ImageString, 'Dummy_element', 0.7, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
16
|
+
const actual = yield CustomElement.fromJsonWithImagePathOrImage({
|
|
17
|
+
customImage: base64ImageString,
|
|
18
|
+
name: 'Dummy_element',
|
|
19
|
+
threshold: 0.7,
|
|
20
|
+
rotationDegreePerStep: 10,
|
|
21
|
+
imageCompareFormat: 'RGB',
|
|
22
|
+
mask: [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }],
|
|
23
|
+
});
|
|
24
|
+
expect(actual).toStrictEqual(expected);
|
|
25
|
+
}));
|
|
26
|
+
test('should throw ValidationError if threshold is invalid', () => {
|
|
27
|
+
expect(() => {
|
|
28
|
+
const customElement = new CustomElement(base64ImageString, 'Dummy_element', 1.1, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
29
|
+
customElement.validate();
|
|
30
|
+
}).toThrow('threshold must be less than or equal to 1');
|
|
31
|
+
});
|
|
32
|
+
test('should throw ValidationError if rotationDegreePerStep is invalid', () => {
|
|
33
|
+
expect(() => {
|
|
34
|
+
const customElement = new CustomElement(base64ImageString, 'Dummy_element', 0.9, -90, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 3, y: 4 }]);
|
|
35
|
+
customElement.validate();
|
|
36
|
+
}).toThrow('rotationDegreePerStep must be greater than or equal to 0');
|
|
37
|
+
});
|
|
38
|
+
test('should throw ValidationError if mask is invalid', () => {
|
|
39
|
+
expect(() => {
|
|
40
|
+
const customElement = new CustomElement(base64ImageString, 'Dummy_element', 0.9, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }]);
|
|
41
|
+
customElement.validate();
|
|
42
|
+
}).toThrow('mask must contain at least 3 points');
|
|
43
|
+
});
|
|
44
|
+
test('should throw ValidationError if mask and threshold are both invalid', () => {
|
|
45
|
+
expect(() => {
|
|
46
|
+
const customElement = new CustomElement(base64ImageString, 'Dummy_element', 90, 10, 'RGB', [{ x: 0, y: 1 }, { x: 1, y: 2 }]);
|
|
47
|
+
customElement.validate();
|
|
48
|
+
}).toThrow('threshold must be less than or equal to 1, mask must contain at least 3 points');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { FluentCommand } from './dsl';
|
|
11
|
+
class TestCommand extends FluentCommand {
|
|
12
|
+
// eslint-disable-next-line class-methods-use-this
|
|
13
|
+
fluentCommandExecutor(instruction, customElements) {
|
|
14
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
// eslint-disable-next-line no-console
|
|
16
|
+
console.log(`${instruction} ${customElements}`);
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
describe('DSL', () => {
|
|
22
|
+
describe('custom element', () => {
|
|
23
|
+
test('should call exec function with zero custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
|
+
const underTest = new TestCommand();
|
|
25
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
26
|
+
yield underTest.click().button()
|
|
27
|
+
.exec();
|
|
28
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on button', []);
|
|
29
|
+
}));
|
|
30
|
+
test('should call exec function with one custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
const underTest = new TestCommand();
|
|
32
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
33
|
+
yield underTest.click().customElement({
|
|
34
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
35
|
+
imageCompareFormat: 'grayscale',
|
|
36
|
+
name: 'custom element 1',
|
|
37
|
+
}).button()
|
|
38
|
+
.exec();
|
|
39
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on custom element button', [{
|
|
40
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
41
|
+
imageCompareFormat: 'grayscale',
|
|
42
|
+
name: 'custom element 1',
|
|
43
|
+
}]);
|
|
44
|
+
}));
|
|
45
|
+
test('should call exec function with two custom element', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
const underTest = new TestCommand();
|
|
47
|
+
const testCommandSpy = jest.spyOn(underTest, 'fluentCommandExecutor');
|
|
48
|
+
yield underTest.click().customElement({
|
|
49
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
50
|
+
imageCompareFormat: 'grayscale',
|
|
51
|
+
name: 'custom element 1',
|
|
52
|
+
})
|
|
53
|
+
.button()
|
|
54
|
+
.customElement({
|
|
55
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
56
|
+
imageCompareFormat: 'grayscale',
|
|
57
|
+
name: 'custom element 2',
|
|
58
|
+
})
|
|
59
|
+
.exec();
|
|
60
|
+
expect(testCommandSpy).toHaveBeenCalledWith('Click on custom element button custom element', [{
|
|
61
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
62
|
+
imageCompareFormat: 'grayscale',
|
|
63
|
+
name: 'custom element 1',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
customImage: 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==',
|
|
67
|
+
imageCompareFormat: 'grayscale',
|
|
68
|
+
name: 'custom element 2',
|
|
69
|
+
},
|
|
70
|
+
]);
|
|
71
|
+
}));
|
|
72
|
+
});
|
|
73
|
+
});
|
|
@@ -14,6 +14,7 @@ export declare class InferenceClient {
|
|
|
14
14
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
15
15
|
private resizeIfNeeded;
|
|
16
16
|
inference(customElements?: CustomElement[], image?: string, instruction?: string): Promise<ControlCommand | Annotation>;
|
|
17
|
+
private static logMetaInformation;
|
|
17
18
|
predictControlCommand(instruction: string, customElements?: CustomElement[], image?: string): Promise<ControlCommand>;
|
|
18
19
|
getDetectedElements(instruction: string, image: string, customElements?: CustomElement[]): Promise<DetectedElement[]>;
|
|
19
20
|
predictImageAnnotation(image: string, customElements?: CustomElement[]): Promise<Annotation>;
|
|
@@ -13,6 +13,7 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
13
13
|
import { resizeBase64ImageWithSameRatio } from '../utils/transformations';
|
|
14
14
|
import { InferenceResponseError } from './inference-response-error';
|
|
15
15
|
import { ConfigurationError } from './config-error';
|
|
16
|
+
import { logger } from '../lib/logger';
|
|
16
17
|
export class InferenceClient {
|
|
17
18
|
constructor(baseUrl, httpClient, resize, workspaceId, apiVersion = 'v3') {
|
|
18
19
|
this.baseUrl = baseUrl;
|
|
@@ -21,7 +22,9 @@ export class InferenceClient {
|
|
|
21
22
|
this.workspaceId = workspaceId;
|
|
22
23
|
this.apiVersion = apiVersion;
|
|
23
24
|
const versionedBaseUrl = urljoin(this.baseUrl, 'api', this.apiVersion);
|
|
24
|
-
this.url = workspaceId
|
|
25
|
+
this.url = workspaceId
|
|
26
|
+
? urljoin(versionedBaseUrl, 'workspaces', workspaceId)
|
|
27
|
+
: versionedBaseUrl;
|
|
25
28
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
26
29
|
throw new ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
27
30
|
}
|
|
@@ -30,17 +33,17 @@ export class InferenceClient {
|
|
|
30
33
|
isImageRequired(instruction) {
|
|
31
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
35
|
const url = urljoin(this.url, 'instruction', 'is-image-required');
|
|
33
|
-
const
|
|
36
|
+
const requestBody = {
|
|
34
37
|
instruction,
|
|
35
38
|
};
|
|
36
|
-
const
|
|
37
|
-
return
|
|
39
|
+
const response = yield this.httpClient.post(url, requestBody);
|
|
40
|
+
return response.body.isImageRequired;
|
|
38
41
|
});
|
|
39
42
|
}
|
|
40
43
|
// eslint-disable-next-line class-methods-use-this
|
|
41
44
|
resizeIfNeeded(customElements, image) {
|
|
42
45
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
-
if (!
|
|
46
|
+
if (!image || customElements.length > 0 || this.resize === undefined) {
|
|
44
47
|
return { base64Image: image, resizeRatio: 1 };
|
|
45
48
|
}
|
|
46
49
|
return resizeBase64ImageWithSameRatio(image, this.resize);
|
|
@@ -49,16 +52,22 @@ export class InferenceClient {
|
|
|
49
52
|
inference(customElements = [], image, instruction) {
|
|
50
53
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
54
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
52
|
-
const
|
|
55
|
+
const requestBody = {
|
|
53
56
|
image: resizedImage.base64Image,
|
|
54
57
|
instruction,
|
|
55
58
|
customElements,
|
|
56
59
|
};
|
|
57
60
|
const url = urljoin(this.url, 'inference');
|
|
58
|
-
const
|
|
59
|
-
|
|
61
|
+
const response = yield this.httpClient.post(url, requestBody);
|
|
62
|
+
InferenceClient.logMetaInformation(response);
|
|
63
|
+
return InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
60
64
|
});
|
|
61
65
|
}
|
|
66
|
+
static logMetaInformation(response) {
|
|
67
|
+
if (response.headers['askui-usage-warnings'] !== undefined) {
|
|
68
|
+
logger.warn(response.headers['askui-usage-warnings']);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
62
71
|
predictControlCommand(instruction, customElements = [], image) {
|
|
63
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
73
|
const inferenceResponse = yield this.inference(customElements, image, instruction);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { envCredentials } from './read-environment-credentials';
|
|
2
|
+
describe('envCredentials()', () => {
|
|
3
|
+
test('should read the credentials from the environment variables', () => {
|
|
4
|
+
process.env['ASKUI_TOKEN'] = 'token';
|
|
5
|
+
process.env['ASKUI_WORKSPACE_ID'] = 'id123';
|
|
6
|
+
const credentialsFromTheEnv = envCredentials();
|
|
7
|
+
expect(credentialsFromTheEnv).toStrictEqual({ workspaceId: 'id123', token: 'token' });
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createArgsWithDefaults, createCliFlagsFromArgs } from './ui-controller-args';
|
|
2
|
+
describe('createCliFlagsFromArgs()', () => {
|
|
3
|
+
test('test createCliFlagsFromArgs should return -d 0 as default output', () => {
|
|
4
|
+
const expected = ['-d 0', '-p 6769', '--action_wait_time 1000', '--host 127.0.0.1', '-m ', '--log-level debug'];
|
|
5
|
+
const argsWithDefaults = createArgsWithDefaults();
|
|
6
|
+
const actual = createCliFlagsFromArgs(argsWithDefaults);
|
|
7
|
+
expect(actual).toStrictEqual(expected);
|
|
8
|
+
});
|
|
9
|
+
test('test createCliFlagsFromArgs output should include -d 0 when no display was selected', () => {
|
|
10
|
+
const expected = ['-d 0', '-p 6777', '--action_wait_time 1000', '--host 0.0.0.0', '-m ', '--log-level debug'];
|
|
11
|
+
const argsWithDefaults = createArgsWithDefaults({ port: 6777, host: '0.0.0.0' });
|
|
12
|
+
const actual = createCliFlagsFromArgs(argsWithDefaults);
|
|
13
|
+
expect(actual).toStrictEqual(expected);
|
|
14
|
+
});
|
|
15
|
+
test('test createCliFlagsFromArgs output should include the display that was selected ', () => {
|
|
16
|
+
const expected = ['-d 99', '-p 6777', '--action_wait_time 1000', '--host 0.0.0.0', '-m ', '--log-level debug'];
|
|
17
|
+
const argsWithDefaults = createArgsWithDefaults({ port: 6777, host: '0.0.0.0', display: 99 });
|
|
18
|
+
const actual = createCliFlagsFromArgs(argsWithDefaults);
|
|
19
|
+
expect(actual).toStrictEqual(expected);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Credentials } from './credentials';
|
|
2
|
+
describe('Credentials', () => {
|
|
3
|
+
describe('base64Encoded()', () => {
|
|
4
|
+
test('should return base64-encoded credentials', () => {
|
|
5
|
+
const credentials = new Credentials('password');
|
|
6
|
+
expect(credentials.base64Encoded).toBe('cGFzc3dvcmQ=');
|
|
7
|
+
});
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { OptionsOfJSONResponseBody } from 'got';
|
|
2
3
|
import http from 'http';
|
|
3
4
|
import https from 'https';
|
|
@@ -17,6 +18,9 @@ export declare class HttpClientGot {
|
|
|
17
18
|
} | undefined);
|
|
18
19
|
private initHeaders;
|
|
19
20
|
private injectHeadersAndCookies;
|
|
20
|
-
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<
|
|
21
|
+
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
22
|
+
headers: http.IncomingHttpHeaders;
|
|
23
|
+
body: T;
|
|
24
|
+
}>;
|
|
21
25
|
get<T>(url: string, options?: OptionsOfJSONResponseBody): Promise<T>;
|
|
22
26
|
}
|
|
@@ -24,18 +24,26 @@ export class HttpClientGot {
|
|
|
24
24
|
}
|
|
25
25
|
initHeaders(token, customHeaders = {}) {
|
|
26
26
|
const credentials = token ? new Credentials(token) : undefined;
|
|
27
|
-
this.headers = Object.assign(Object.assign({}, (credentials
|
|
27
|
+
this.headers = Object.assign(Object.assign({}, (credentials
|
|
28
|
+
? { Authorization: `Basic ${credentials === null || credentials === void 0 ? void 0 : credentials.base64Encoded}` }
|
|
29
|
+
: {})), customHeaders);
|
|
28
30
|
}
|
|
29
31
|
injectHeadersAndCookies(url, options) {
|
|
30
32
|
const cookieJar = new CookieJar();
|
|
31
|
-
Object.keys(this.cookies)
|
|
33
|
+
Object.keys(this.cookies)
|
|
34
|
+
.map((key) => `${key}=${this.cookies[key]}`)
|
|
35
|
+
.forEach((cookie) => {
|
|
32
36
|
cookieJar.setCookieSync(cookie, url);
|
|
33
37
|
});
|
|
34
38
|
return Object.assign(Object.assign({}, options), { headers: this.headers, cookieJar });
|
|
35
39
|
}
|
|
36
40
|
post(url, data) {
|
|
37
41
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
-
const options = this.injectHeadersAndCookies(url, {
|
|
42
|
+
const options = this.injectHeadersAndCookies(url, {
|
|
43
|
+
json: data,
|
|
44
|
+
responseType: 'json',
|
|
45
|
+
throwHttpErrors: false,
|
|
46
|
+
});
|
|
39
47
|
const { body, statusCode, headers } = yield this.askuiGot.post(url, options);
|
|
40
48
|
if (headers['deprecation'] !== undefined) {
|
|
41
49
|
logger.warn(headers['deprecation']);
|
|
@@ -43,7 +51,7 @@ export class HttpClientGot {
|
|
|
43
51
|
if (statusCode !== 200) {
|
|
44
52
|
throw httpClientErrorHandler(statusCode, JSON.stringify(body));
|
|
45
53
|
}
|
|
46
|
-
return body;
|
|
54
|
+
return { headers, body };
|
|
47
55
|
});
|
|
48
56
|
}
|
|
49
57
|
get(url, options = { responseType: 'json' }) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "askui",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "askui GmbH <info@askui.com> (http://www.askui.com/)",
|
|
6
6
|
"description": "Reliable, automated end-to-end-testing that depends on what is shown on your screen instead of the technology you are running on",
|