Skip to content

Commit

Permalink
Legacy code deprecation cleanup (#1059)
Browse files Browse the repository at this point in the history
* Remove the long-deprecated init().

* Remove the long-deprecated Core and BridgedCore capabilities.

* Remove long-deprecated Camera options.

* Linting.

* Deprecation cleanup.

---------

Co-authored-by: Donavan Becker <beckersmarthome@icloud.com>
  • Loading branch information
hjdhjd and donavanbecker authored Jul 10, 2024
1 parent e20beba commit ac79886
Show file tree
Hide file tree
Showing 23 changed files with 19 additions and 1,569 deletions.
5 changes: 0 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ import "source-map-support/register"; // registering node-source-map-support for
import "./lib/definitions"; // must be loaded before Characteristic and Service class
import createDebug from "debug";

/**
* @group Utils
*/
export * as AccessoryLoader from "./lib/AccessoryLoader";
/**
* @group Utils
*/
Expand All @@ -15,7 +11,6 @@ export * from "./lib/Accessory";
export * from "./lib/Bridge";
export * from "./lib/Service";
export * from "./lib/Characteristic";
export * from "./lib/AccessoryLoader";
export * from "./lib/camera";
export * from "./lib/tv/AccessControlManagement";
export * from "./lib/HAPServer";
Expand Down
40 changes: 2 additions & 38 deletions src/lib/Accessory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
Units,
} from "./Characteristic";
import { CameraController, Controller, ControllerIdentifier, ControllerServiceMap } from "./controller";
import { createCameraControllerOptions, MOCK_IMAGE, MockLegacyCameraSource } from "./controller/CameraController.spec";
import { createCameraControllerOptions, MOCK_IMAGE } from "./controller/CameraController.spec";
import { HAPHTTPCode, HAPStatus, IdentifyCallback, TLVErrorCode } from "./HAPServer";
import { AccessoryInfo, PairingInformation, PermissionTypes } from "./model/AccessoryInfo";
import { IdentifierCache } from "./model/IdentifierCache";
Expand Down Expand Up @@ -201,8 +201,7 @@ describe("Accessory", () => {
expect(accessory.primaryService).toBe(instance);

const outlet = new Service.Outlet("Outlet");
// noinspection JSDeprecatedSymbols
accessory.setPrimaryService(outlet);
outlet.setPrimaryService();
accessory.addService(outlet);

// @ts-expect-error: private access
Expand Down Expand Up @@ -307,41 +306,6 @@ describe("Accessory", () => {
expect(restoredAccessory.getService(Service.Outlet)).toBeDefined();
expect(restoredAccessory.getService(Service.Switch)).toBeUndefined();
});

test("legacy configure camera source", async () => {
const microphone = new Service.Microphone();
const source = new MockLegacyCameraSource(2);
source.services.push(microphone);

const expectedOptions = source.streamControllers[0].options;

// noinspection JSDeprecatedSymbols
accessory.configureCameraSource(source);

expect(accessory.getServiceById(Service.CameraRTPStreamManagement, "0")).toBeDefined();
expect(accessory.getServiceById(Service.CameraRTPStreamManagement, "1")).toBeDefined();
expect(accessory.getService(Service.Microphone)).toBe(microphone);

// @ts-expect-error: private access
const cameraController = accessory.activeCameraController!;
expect(cameraController).toBeDefined();

// @ts-expect-error: private access
expect(cameraController.streamCount).toEqual(2);
// @ts-expect-error: private access
expect(cameraController.streamingOptions).toEqual(expectedOptions);

// @ts-expect-error: private access
accessory.handleResource({
"resource-type": ResourceRequestType.IMAGE,
"image-width": 200,
"image-height": 200,
}, callback);

await callbackPromise;

expect(callback).toHaveBeenCalledWith(undefined, MOCK_IMAGE);
});
});

describe("publish", () => {
Expand Down
135 changes: 3 additions & 132 deletions src/lib/Accessory.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import assert from "assert";
import { MulticastOptions } from "bonjour-hap";
import crypto from "crypto";
import createDebug from "debug";
import { EventEmitter } from "events";
Expand Down Expand Up @@ -30,7 +29,6 @@ import {
} from "../types";
import { Advertiser, AdvertiserEvent, AvahiAdvertiser, BonjourHAPAdvertiser, CiaoAdvertiser, ResolvedAdvertiser } from "./Advertiser";
// noinspection JSDeprecatedSymbols
import { LegacyCameraSource, LegacyCameraSourceAdapter, StreamController } from "./camera";
import {
Access,
ChangeReason,
Expand All @@ -42,7 +40,6 @@ import {
} from "./Characteristic";
import {
CameraController,
CameraControllerOptions,
Controller,
ControllerConstructor,
ControllerIdentifier,
Expand Down Expand Up @@ -188,13 +185,6 @@ export interface CharacteristicWarning {
stack?: string,
}

/**
* @group Characteristic
* @deprecated
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type CharacteristicEvents = Record<string, any>;

/**
* @group Accessory
*/
Expand Down Expand Up @@ -268,11 +258,6 @@ export interface PublishInfo {
* When undefined port 0 will be used resulting in a random port.
*/
port?: number;
/**
* Used to define custom MDNS options. Is not used anymore.
* @deprecated
*/
mdns?: MulticastOptions;
/**
* If this option is set to true, HAP-NodeJS will add identifying material (based on {@link username})
* to the end of the accessory display name (and bonjour instance name).
Expand All @@ -283,11 +268,6 @@ export interface PublishInfo {
* Defines the advertiser used with the published Accessory.
*/
advertiser?: MDNSAdvertiser;
/**
* Use the legacy bonjour-hap as advertiser.
* @deprecated
*/
useLegacyAdvertiser?: boolean;
}

/**
Expand Down Expand Up @@ -336,13 +316,6 @@ const enum WriteRequestState {
TIMED_WRITE_REJECTED
}

// noinspection JSUnusedGlobalSymbols
/**
* @deprecated Use AccessoryEventTypes instead
* @group Accessory
*/
export type EventAccessory = "identify" | "listening" | "service-configurationChange" | "service-characteristic-change";

/**
* @group Accessory
*/
Expand Down Expand Up @@ -421,15 +394,9 @@ export declare interface Accessory {
*/
// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
export class Accessory extends EventEmitter {
/**
* @deprecated Please use the Categories const enum above.
*/
// @ts-expect-error: forceConsistentCasingInFileNames compiler option
static Categories = Categories;

/// Timeout in milliseconds until a characteristic warning is issue
// Timeout in milliseconds until a characteristic warning is issue
private static readonly TIMEOUT_WARNING = 3000;
/// Timeout in milliseconds after `TIMEOUT_WARNING` until the operation on the characteristic is considered timed out.
// Timeout in milliseconds after `TIMEOUT_WARNING` until the operation on the characteristic is considered timed out.
private static readonly TIMEOUT_AFTER_WARNING = 6000;

// NOTICE: when adding/changing properties, remember to possibly adjust the serialize/deserialize functions
Expand Down Expand Up @@ -591,13 +558,6 @@ export class Accessory extends EventEmitter {
return service;
}

/**
* @deprecated use {@link Service.setPrimaryService} directly
*/
public setPrimaryService(service: Service): void {
service.setPrimaryService();
}

public removeService(service: Service): void {
const index = this.services.indexOf(service);

Expand Down Expand Up @@ -665,18 +625,6 @@ export class Accessory extends EventEmitter {
return this.bridged? this.bridge!: this;
};

/**
* @deprecated Not supported anymore
*/
public updateReachability(reachable: boolean): void {
if (!this.bridged) {
throw new Error("Cannot update reachability on non-bridged accessory!");
}
this.reachable = reachable;

debug("Reachability update is no longer being supported.");
}

public addBridgedAccessory(accessory: Accessory, deferUpdate = false): Accessory {
if (accessory._isBridge || accessory === this) {
throw new Error("Illegal state: either trying to bridge a bridge or trying to bridge itself!");
Expand Down Expand Up @@ -778,63 +726,6 @@ export class Accessory extends EventEmitter {
return accessory && accessory.getCharacteristicByIID(iid);
}

// noinspection JSDeprecatedSymbols
/**
* Method is used to configure an old style CameraSource.
* The CameraSource API was fully replaced by the new Controller API used by {@link CameraController}.
* The {@link CameraStreamingDelegate} used by the CameraController is the equivalent to the old CameraSource.
*
* The new Controller API is much more refined and robust way of "grouping" services together.
* It especially is intended to fully support serialization/deserialization to/from persistent storage.
* This feature is also gained when using the old style CameraSource API.
* The {@link CameraStreamingDelegate} improves on the overall camera API though and provides some reworked
* type definitions and a refined callback interface to better signal errors to the requesting HomeKit device.
* It is advised to update to it.
*
* Full backwards compatibility is currently maintained. A legacy CameraSource will be wrapped into an Adapter.
* All legacy StreamControllers in the "streamControllers" property will be replaced by CameraRTPManagement instances.
* Any services in the "services" property which are one of the following are ignored:
* - CameraRTPStreamManagement
* - CameraOperatingMode
* - CameraEventRecordingManagement
*
* @param cameraSource - The instance of the legacy camera source
* @deprecated please refer to the new {@link CameraController} API and {@link configureController}
*/
public configureCameraSource(cameraSource: LegacyCameraSource): CameraController {
if (cameraSource.streamControllers.length === 0) {
throw new Error("Malformed legacy CameraSource. Did not expose any StreamControllers!");
}

const options = cameraSource.streamControllers[0].options; // grab options from one of the StreamControllers
const cameraControllerOptions: CameraControllerOptions = { // build new options set
cameraStreamCount: cameraSource.streamControllers.length,
streamingOptions: options,
delegate: new LegacyCameraSourceAdapter(cameraSource),
};

const cameraController = new CameraController(cameraControllerOptions, true); // create CameraController in legacy mode
this.configureController(cameraController);

// we try here to be as good as possibly of keeping current behaviour
cameraSource.services.forEach(service => {
if (service.UUID === Service.CameraRTPStreamManagement.UUID || service.UUID === Service.CameraOperatingMode.UUID
|| service.UUID === Service.CameraRecordingManagement.UUID) {
return; // ignore those services, as they get replaced by the RTPStreamManagement
}

// all other services get added. We can't really control possibly linking to any of those ignored services
// so this is really only half-baked stuff.
this.addService(service);
});

// replace stream controllers; basically only to still support the "forceStop" call
// noinspection JSDeprecatedSymbols
cameraSource.streamControllers = cameraController.streamManagements as StreamController[];

return cameraController; // return the reference for the controller (maybe this could be useful?)
}

/**
* This method is used to set up a new Controller for this accessory. See {@link Controller} for a more detailed
* explanation what a Controller is and what it is capable of.
Expand Down Expand Up @@ -1213,21 +1104,6 @@ export class Accessory extends EventEmitter {
throw new Error("Can't publish in accessory which is bridged by another accessory. Bridged by " + this.bridge?.displayName);
}

// noinspection JSDeprecatedSymbols
if (!info.advertiser && info.useLegacyAdvertiser != null) {
// noinspection JSDeprecatedSymbols
info.advertiser = info.useLegacyAdvertiser? MDNSAdvertiser.BONJOUR: MDNSAdvertiser.CIAO;
console.warn("DEPRECATED The PublishInfo.useLegacyAdvertiser option has been removed. " +
"Please use the PublishInfo.advertiser property to enable \"ciao\" (useLegacyAdvertiser=false) " +
"or \"bonjour-hap\" (useLegacyAdvertiser=true) mdns advertiser libraries!");
}

// noinspection JSDeprecatedSymbols
if (info.mdns && info.advertiser !== MDNSAdvertiser.BONJOUR) {
console.log("DEPRECATED user supplied a custom 'mdns' option. This option is deprecated and ignored. " +
"Please move to the new 'bind' option.");
}

let service = this.getService(Service.ProtocolInformation);
if (!service) {
service = this.addService(Service.ProtocolInformation); // add the protocol information service to the primary accessory
Expand Down Expand Up @@ -1332,8 +1208,7 @@ export class Accessory extends EventEmitter {
});
break;
case MDNSAdvertiser.BONJOUR:
// noinspection JSDeprecatedSymbols
this._advertiser = new BonjourHAPAdvertiser(this._accessoryInfo, info.mdns, {
this._advertiser = new BonjourHAPAdvertiser(this._accessoryInfo, {
restrictedAddresses: parsed.serviceRestrictedAddress,
disabledIpv6: parsed.serviceDisableIpv6,
});
Expand Down Expand Up @@ -1960,10 +1835,6 @@ export class Accessory extends EventEmitter {
}

private handleHAPConnectionClosed(connection: HAPConnection): void {
if (this.activeCameraController) {
this.activeCameraController.handleCloseConnection(connection.sessionID);
}

for (const event of connection.getRegisteredEvents()) {
const ids = event.split(".");
const aid = parseInt(ids[0], 10);
Expand Down
Loading

0 comments on commit ac79886

Please sign in to comment.