diff --git a/README.md b/README.md
index 79b23ae8..7f08df9d 100644
--- a/README.md
+++ b/README.md
@@ -544,7 +544,7 @@ Enables or disables the identifiers widget. This widget can be used to set the i
Enables or disables the phone widget. This widget can be used to send SMS or phone call the Android virtual device.
-### `Baseband`
+### `baseband`
diff --git a/gulpfile.js b/gulpfile.js
index 9e08812b..763db1fb 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -72,12 +72,12 @@ function getTemplatesStream() {
}
// Clean dist dir
-gulp.task('clean', function(cb) {
+gulp.task('clean', function (cb) {
del([PATHS.DEST.BASE + ' --force']).then(
- function() {
+ function () {
cb();
},
- function(err) {
+ function (err) {
cb(err);
},
);
@@ -105,6 +105,11 @@ gulp.task('app-styles', function () {
.pipe(gulp.dest(PATHS.DEST.ASSETS.CSS));
});
+// TS declaration files
+gulp.task('app-dts', function () {
+ return gulp.src(PATHS.SRC.BASE + './../*.d.ts').pipe(gulp.dest(PATHS.DEST.BASE));
+});
+
gulp.task('app-templates', function () {
return getTemplatesStream().pipe(
tap(function (file) {
@@ -119,6 +124,14 @@ gulp.task('app-templates', function () {
);
});
+function setupBrowserify() {
+ return browserify({
+ entries: [PATHS.SRC.BASE + '/' + PATHS.SRC.APP],
+ standalone: 'genyDeviceWebPlayer',
+ debug: true,
+ }).transform(graspify, ['#GEN_TEMPLATES', templates]);
+}
+
function getBundler() {
return new Promise((resolve) => {
if (!templates) {
@@ -131,14 +144,6 @@ function getBundler() {
});
}
-function setupBrowserify() {
- return browserify({
- entries: [PATHS.SRC.BASE + '/' + PATHS.SRC.APP],
- standalone: 'genyDeviceWebPlayer',
- debug: true,
- }).transform(graspify, ['#GEN_TEMPLATES', templates]);
-}
-
gulp.task('app-js', async function () {
const bundler = await getBundler();
return merge2(bundler.bundle().pipe(source(PATHS.SRC.APP)), {end: true})
@@ -196,7 +201,7 @@ gulp.task(
gulp.series(
'clean',
'app-templates',
- gulp.parallel('app-partials', 'app-styles', 'app-js'),
+ gulp.parallel('app-partials', 'app-styles', 'app-js', 'app-dts'),
'inject',
function (cb) {
cb();
diff --git a/index.d.ts b/index.d.ts
new file mode 100644
index 00000000..498ef9b1
--- /dev/null
+++ b/index.d.ts
@@ -0,0 +1,157 @@
+type KeyEffectDistance = {
+ distanceX: number;
+ distanceY: number;
+};
+
+interface KeyEffect {
+ initialX: number;
+ initialY: number;
+ name?: string;
+ description?: string;
+}
+
+interface KeyMap {
+ keys: Record;
+ name?: string;
+ description?: string;
+}
+
+interface KeyMappingConfig {
+ dpad?: KeyMap[];
+ tap?: KeyMap[];
+ swipe?: KeyMap[];
+}
+
+type DeviceRendererKeyMapping = {
+ enable(isEnable: boolean): void;
+ setConfig(config: KeyMappingConfig): void;
+ activeKeyMappingDebug(isTraceActivate?: boolean, isGridActivate?: boolean): void;
+};
+
+type VmEvent =
+ | 'ANDROID_ID'
+ | 'baseband'
+ | 'BATTERY_LEVEL'
+ | 'BATTERY_STATUS'
+ | 'battery'
+ | 'beforeunload'
+ | 'BLK'
+ | 'CLIPBOARD'
+ | 'diskio'
+ | 'fingerprint'
+ | 'framework'
+ | 'gps'
+ | 'IMEI'
+ | 'network_profile'
+ | 'NETWORK'
+ | 'settings'
+ | 'SYSTEM_PATCHER_LAST_RESULT'
+ | 'SYSTEM_PATCHER_STATUS'
+ | 'systempatcher'
+ | 'vinput'
+ | string // This list is not exhaustive and should be completed
+
+type VmCommunication = {
+ disconnect(): void;
+ addEventListener(event: VmEvent, callback: (msg: string) => void): void;
+ sendData(data: { channel: string; messages: string[] }): void;
+};
+
+type RegisteredFunctionDoc = {
+ apiName: string,
+ apiDescription: string,
+}
+
+type Utils = {
+ getRegisteredFunctions(): RegisteredFunctionDoc[];
+};
+
+type Media = {
+ mute(): void;
+ unmute(): void;
+};
+
+type Video = {
+ fullscreen: () => void;
+};
+
+type Template = 'bootstrap'
+ | 'fullscreen'
+ | 'fullwindow'
+ | 'renderer'
+ | 'renderer_minimal'
+ | 'renderer_no_toolbar'
+ | 'renderer_partial';
+
+interface RendererSetupOptions {
+ baseband?: boolean; // Default: false
+ battery?: boolean; // Default: true
+ biometrics?: boolean; // Default: true
+ camera?: boolean; // Default: true
+ capture?: boolean; // Default: true
+ clipboard?: boolean; // Default: true
+ connectionFailedURL?: string;
+ diskIO?: boolean; // Default: true
+ fileUpload?: boolean; // Default: true
+ fileUploadUrl?: string;
+ fullscreen?: boolean; // Default: true
+ gamepad?: boolean; // Default: true
+ giveFeedbackLink?: string;
+ gps?: boolean; // Default: true
+ gpsSpeedSupport?: boolean; // Default: false
+ i18n?: Record;
+ identifiers?: boolean; // Default: true
+ keyboard?: boolean; // Default: true
+ keyboardMapping?: boolean; // Default: true
+ microphone?: boolean; // Default: false
+ mobilethrottling?: boolean; // Default: false
+ mouse?: boolean; // Default: true
+ navbar?: boolean; // Default: true
+ network?: boolean; // Default: true
+ phone?: boolean; // Default: true
+ power?: boolean; // Default: true
+ rotation?: boolean; // Default: true
+ streamBitrate?: boolean; // Default: false
+ streamResolution?: boolean; // Default: true
+ stun?: { urls?: string[] };
+ template?: Template; // Default: 'renderer'
+ token?: string;
+ touch?: boolean; // Default: true
+ translateHomeKey?: boolean; // Default: false
+ turn?: {
+ urls?: string[];
+ username?: string;
+ credential?: string;
+ default?: boolean; // Default: false
+ };
+ volume?: boolean; // Default: true
+}
+
+type DefaultTrue = B extends void
+? T // Key is not present
+: B extends true | undefined
+ ? T // Key is true or undefined
+ : B extends false
+ ? undefined // Key is false
+ : T | undefined; // Key is true, false or undefined (we cannot infer anything)
+
+type ExtractKey = O extends { [P in K]: infer T } ? T : void;
+
+type DeviceRendererApi = {
+ keyMapping: DefaultTrue, DeviceRendererKeyMapping>;
+ media: Media;
+ utils: Utils;
+ video?: Video; // Available if any plugin (e.g. fullscreen) using it is enabled.
+ VM_communication: VmCommunication;
+};
+
+declare class DeviceRendererFactory {
+ constructor();
+ setupRenderer(
+ targetElement: HTMLDivElement,
+ webrtcAddress: string,
+ options?: O,
+ ): DeviceRendererApi;
+}
+
+export { DeviceRendererApi, DeviceRendererFactory, RendererSetupOptions, KeyMappingConfig }
diff --git a/package.json b/package.json
index 661c3298..83e96770 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"files": [
"dist"
],
+ "types": "dist/index.d.ts",
"engines": {
"node": ">=16"
},
@@ -71,6 +72,7 @@
"prettier": "^3.3.2",
"sass": "^1.53.0",
"through2": "^4.0.2",
+ "typescript": "^5.5.4",
"vinyl": "^2.2.1",
"vinyl-source-stream": "^2.0.0"
},
diff --git a/yarn.lock b/yarn.lock
index a674a9a2..088ca194 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8794,6 +8794,11 @@ typescript@^4.6.2:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz"
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
+typescript@^5.5.4:
+ version "5.5.4"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
+ integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
+
ua-parser-js@1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz"