From a1b0cd1f4991b0dbbff64fae72284962292245f7 Mon Sep 17 00:00:00 2001 From: Rudolph Gottesheim Date: Mon, 4 Sep 2023 14:22:12 +0200 Subject: [PATCH 1/2] Enable `noUncheckedIndexedAccess` in tsconfig.json --- src/camera/core-impl.ts | 7 ++++--- src/core.ts | 2 +- src/html5-qrcode-scanner.ts | 2 +- src/html5-qrcode.ts | 4 ++-- src/ui/scanner/file-selection-ui.ts | 5 ++--- src/ui/scanner/scan-type-selector.ts | 10 +++++----- tsconfig.json | 1 + 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/camera/core-impl.ts b/src/camera/core-impl.ts index ad29ec4..7109174 100644 --- a/src/camera/core-impl.ts +++ b/src/camera/core-impl.ts @@ -218,11 +218,12 @@ class RenderedCameraImpl implements RenderedCamera { private getFirstTrackOrFail(): MediaStreamTrack { this.failIfClosed(); - if (this.mediaStream.getVideoTracks().length === 0) { + const firstTrack = this.mediaStream.getVideoTracks()[0]; + if (!firstTrack) { throw "No video tracks found"; - } - return this.mediaStream.getVideoTracks()[0]; + } + return firstTrack; } //#region Public APIs. diff --git a/src/core.ts b/src/core.ts index 8d3d965..7e14dd2 100644 --- a/src/core.ts +++ b/src/core.ts @@ -89,7 +89,7 @@ export class Html5QrcodeConstants { static DEFAULT_REMEMBER_LAST_CAMERA_USED = true; static DEFAULT_SUPPORTED_SCAN_TYPE = [ Html5QrcodeScanType.SCAN_TYPE_CAMERA, - Html5QrcodeScanType.SCAN_TYPE_FILE]; + Html5QrcodeScanType.SCAN_TYPE_FILE] as const; } /** Defines dimension for QR Code Scanner. */ diff --git a/src/html5-qrcode-scanner.ts b/src/html5-qrcode-scanner.ts index 028262f..a29bc48 100644 --- a/src/html5-qrcode-scanner.ts +++ b/src/html5-qrcode-scanner.ts @@ -114,7 +114,7 @@ export interface Html5QrcodeScannerConfig * - [SCAN_TYPE_FILE] - Only file based scan supported. * - Setting wrong values or multiple values will fail. */ - supportedScanTypes?: Array | []; + supportedScanTypes?: ReadonlyArray | []; /** * If `true` the rendered UI will have button to turn flash on or off diff --git a/src/html5-qrcode.ts b/src/html5-qrcode.ts index b3fcbda..ec05fc4 100644 --- a/src/html5-qrcode.ts +++ b/src/html5-qrcode.ts @@ -1259,12 +1259,12 @@ export class Html5Qrcode { }; const keys = Object.keys(cameraIdOrConfig); - if (keys.length !== 1) { + const key = keys[0]; + if (!key) { throw "'cameraIdOrConfig' object should have exactly 1 key," + ` if passed as an object, found ${keys.length} keys`; } - const key:string = Object.keys(cameraIdOrConfig)[0]; if (key !== facingModeKey && key !== deviceIdKey) { throw `Only '${facingModeKey}' and '${deviceIdKey}' ` + " are supported for 'cameraIdOrConfig'"; diff --git a/src/ui/scanner/file-selection-ui.ts b/src/ui/scanner/file-selection-ui.ts index ebf68f7..9118677 100644 --- a/src/ui/scanner/file-selection-ui.ts +++ b/src/ui/scanner/file-selection-ui.ts @@ -69,11 +69,10 @@ export class FileSelectionUi { return; } let target: HTMLInputElement = e.target as HTMLInputElement; - if (target.files && target.files.length === 0) { + const file = target.files?.[0]; + if (!file) { return; } - let fileList: FileList = target.files!; - const file: File = fileList[0]; let fileName = file.name; $this.setImageNameToButton(fileName); diff --git a/src/ui/scanner/scan-type-selector.ts b/src/ui/scanner/scan-type-selector.ts index d822e16..f7fd887 100644 --- a/src/ui/scanner/scan-type-selector.ts +++ b/src/ui/scanner/scan-type-selector.ts @@ -15,9 +15,9 @@ import { /** Util class to help with scan type selection in scanner class. */ export class ScanTypeSelector { - private supportedScanTypes: Array; + private supportedScanTypes: readonly [Html5QrcodeScanType, ...Array]; - constructor(supportedScanTypes?: Array | []) { + constructor(supportedScanTypes?: ReadonlyArray | []) { this.supportedScanTypes = this.validateAndReturnScanTypes( supportedScanTypes); } @@ -65,8 +65,8 @@ export class ScanTypeSelector { * Fails early if the config values is incorrectly set. */ private validateAndReturnScanTypes( - supportedScanTypes?:Array): - Array { + supportedScanTypes?:ReadonlyArray): + readonly [Html5QrcodeScanType, ...Array] { // If not set, use the default values and order. if (!supportedScanTypes || supportedScanTypes.length === 0) { return Html5QrcodeConstants.DEFAULT_SUPPORTED_SCAN_TYPE; @@ -88,7 +88,7 @@ export class ScanTypeSelector { } } - return supportedScanTypes; + return supportedScanTypes as [Html5QrcodeScanType, ...Array]; } //#endregion } diff --git a/tsconfig.json b/tsconfig.json index 67e237a..092f018 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ // Flags to ensure code quality. "strict": true, "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, "noUnusedParameters": true, "experimentalDecorators": true, "removeComments": true, From 1f95e04f9de5ab48e3f06802d5d20d0edd20006d Mon Sep 17 00:00:00 2001 From: Rudolph Gottesheim Date: Mon, 4 Sep 2023 14:26:50 +0200 Subject: [PATCH 2/2] Add non-null assertions to tests --- tests/ui/scanner/camera-selection-ui.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ui/scanner/camera-selection-ui.test.ts b/tests/ui/scanner/camera-selection-ui.test.ts index 2289618..428b13e 100644 --- a/tests/ui/scanner/camera-selection-ui.test.ts +++ b/tests/ui/scanner/camera-selection-ui.test.ts @@ -123,10 +123,10 @@ describe("CameraSelectionUi setting and getting values", () => { let cameraSelectUi = CameraSelectionUi.create(parentElement!, cameras); // First camera is default. - expect(cameraSelectUi.getValue()).eq(cameras[0].id); + expect(cameraSelectUi.getValue()).eq(cameras[0]!.id); - cameraSelectUi.setValue(cameras[1].id); - expect(cameraSelectUi.getValue()).eq(cameras[1].id); + cameraSelectUi.setValue(cameras[1]!.id); + expect(cameraSelectUi.getValue()).eq(cameras[1]!.id); expect(() => { cameraSelectUi.setValue("random string"); @@ -138,7 +138,7 @@ describe("CameraSelectionUi setting and getting values", () => { let cameras = createCameraList(numCameras); let cameraSelectUi = CameraSelectionUi.create(parentElement!, cameras); - expect(cameraSelectUi.hasValue(cameras[1].id)).to.be.true; + expect(cameraSelectUi.hasValue(cameras[1]!.id)).to.be.true; expect(cameraSelectUi.hasValue("random string")).to.be.false; }); });