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"