/** * @license * Copyright 2022-2026 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ import type { AttributeModel, CommandModel, EventModel } from "@matter/model"; import { ClusterModel, ClusterModifier } from "@matter/model"; import type { AttributeId } from "../datatype/AttributeId.js"; import { ClusterId } from "../datatype/ClusterId.js"; import type { CommandId } from "../datatype/CommandId.js"; import type { EventId } from "../datatype/EventId.js"; import type { BitSchema, TypeFromPartialBitSchema } from "../schema/BitmapSchema.js"; import { RetiredClusterType } from "./RetiredClusterType.js"; /** * Describes the shape of generated namespace objects for standard Matter clusters (`typeof OnOff`). * * For many standard clusters, API varies based on configuration such as cluster features. Matter.js generates this API * dynamically based on information stored in these namespaces. The namespace also conveys compile-time type * information. * * For hand-crafted clusters, decorated classes may be preferable to replicating matter.js's code generation. * * ## Namespace layout * * Generated cluster namespaces contain: * * - **Per-component attribute interfaces** (`BaseAttributes`, `LightingAttributes`, etc.) — each feature component * gets its own interface with mandatory attributes required and optional attributes using `?`. These carry full * JSDoc and are what the IDE navigates to for go-to-definition and hover. * * - **Attributes** — flat interface listing every attribute the cluster defines with its value type. All properties * are required (no `?`). This is used by `ClusterEvents` for `$Changed`/`$Changing` observable key generation * where value types must be read via `A[K]` without `undefined` contamination. * * - **Per-component command interfaces** (`BaseCommands`, `FrequencyCommands`, etc.) — method signatures per feature * component. Each feature's commands live in a separate interface so that users clicking through to a command see * a normal, readable interface. * * - **Commands** — flat interface extending all per-component command interfaces. * * - **Events** — flat interface, same design as Attributes (all required, string-union optionality in Components). * * - **Components** — tuple of `{ flags, attributes?, commands?, events? }` entries. `attributes` references a * per-component attribute interface. `commands` references a per-component command interface. `events` uses * `{ mandatory?, optional? }` string-union maps. */ export interface ClusterType { readonly Typing: ClusterTyping; readonly schema: ClusterModel; readonly id?: ClusterId; readonly name: string; readonly revision?: number; readonly attributes?: Record; readonly commands?: Record; readonly events?: Record; readonly features?: Record; } /** * Describes the shape of types matter.js uses for compile-time generation of Matter cluster-related APIs. * * This does not represent an actual object. It only exists to convey type information that is input to matter.js's * type system. For standard clusters this information has no other compile-time representation as matter.js generates * related classes at runtime. */ export interface ClusterTyping { Attributes?: {}; Commands?: {}; Events?: {}; Features?: {}; Components?: {}; SupportedFeatures?: {}; readonly schema?: ClusterModel; } /** * Create or retrieve the runtime namespace object for a cluster model. * * The result is cached per model instance via a {@link WeakMap}, so repeated calls with the same model return the * identical object. The object carries all runtime properties: `id`, `name`, `revision`, `schema`, enum values, * feature enum, error classes, plus lazy getters for `attributes`, `commands`, `events`, `features`, `Cluster`, * and `Complete`. * * @deprecated Use ClusterType with a ClusterModel instead. */ export declare function ClusterType(options: T): ClusterType.Concrete & { Typing: RetiredClusterType.TypingOfOptions; }; export declare function ClusterType(model: ClusterModel): object; export declare namespace ClusterType { interface Component { flags: TypeFromPartialBitSchema; attributes?: {}; commands?: {}; events?: {}; } interface Attribute { id: AttributeId; name: string; schema: AttributeModel; readonly __phantom?: T; } interface Command unknown = (...args: unknown[]) => unknown> { id: CommandId; name: string; schema: CommandModel; readonly __phantom?: T; } interface Event { id: EventId; name: string; schema: EventModel; readonly __phantom?: T; } interface Feature { id: number; name: string; } /** * A {@link ClusterType} with a concrete cluster ID. Used for behavior types that are known to be associated * with a non-abstract cluster. */ interface Concrete extends ClusterType { readonly id: ClusterId; } /** * Default namespace used before a real cluster is assigned. */ const Unknown: Concrete; type Attributes = { [K in keyof A]: Attribute; }; type Commands = { [K in keyof C]: Command; }; type Events = { [K in keyof E]: Event; }; type Features = { [K in F]: Feature; }; type AttributeObjects = { [K in keyof A]-?: Attribute>; }; type CommandObjects = { [K in keyof C]: C[K] extends (...args: unknown[]) => unknown ? Command : Command; }; type EventObjects = { [K in keyof E]-?: Event>; }; /** * Set supported feature flags on a namespace, replacing any previous selection. */ type WithSupportedFeatures = Omit & { SupportedFeatures: S; }; /** * Compat layer for pre-PR #3466 call sites that pin features via `Cluster.with(...)`. Returns the namespace * shape with a `with()` method that shifts `Typing.SupportedFeatures`. Feature selection has no further runtime * effect; the shim exists only to keep existing call sites typing correctly during the 0.17 → 0.18 migration. * * @deprecated Scheduled for removal in 0.18. New code should type the cluster via * {@link WithSupportedFeatures} directly. */ type WithCompat = NS & { /** * @deprecated Feature selection is a typing-only compat shim for pre-PR #3466 call sites. * Scheduled for removal in 0.18. Prefer typing the cluster via {@link WithSupportedFeatures} directly. */ with(...features: F): Omit & { Typing: WithSupportedFeatures>; }; }; /** * Extract supported feature flags from a namespace, defaulting to {}. */ type SupportedFeaturesOf = N extends { SupportedFeatures: infer S; } ? S : N extends { Features: infer F extends string; } ? { [K in Uncapitalize]: false; } : {}; /** * Derive the feature flags object type from a namespace's Features string union. */ type FeaturesOf = N extends { Features: infer F extends string; } ? { [K in Uncapitalize]: boolean; } : Record; /** * Extract the Components tuple from a namespace. */ type ComponentsOf = N extends { Components: infer C extends Component[]; } ? C : []; /** * Augment a namespace with attribute keys forced mandatory (e.g. via `enable()` or `alter()`). * * Injects a synthetic base component (`flags: {}`) with the enabled keys as mandatory. */ type WithEnabledAttributes = Omit & { Components: [ ...(N extends { Components: infer C extends Component[]; } ? C : []), { flags: {}; attributes: N extends { Attributes: infer A; } ? { [P in K & keyof A]: A[P]; } : never; } ]; }; /** * Extract attribute key names from ElementFlags (used by `enable()`). */ type EnabledAttributeKeysOf = F extends { attributes: infer A; } ? keyof A & string : never; /** * Extract attribute key names made mandatory by Alterations (used by `alter()`). */ type AlteredMandatoryAttributeKeysOf = A extends { attributes: infer E; } ? { [K in keyof E & string]: E[K] extends { optional: false; } ? K : never; }[keyof E & string] : never; /** * Augment a namespace with event keys forced mandatory (e.g. via `enable()`). * * Injects a synthetic base component (`flags: {}`) with the enabled keys as mandatory. */ type WithEnabledEvents = Omit & { Components: [ ...(N extends { Components: infer C extends Component[]; } ? C : []), { flags: {}; events: N extends { Events: infer E; } ? { [P in K & keyof E]: E[P]; } : never; } ]; }; /** * Extract event key names from ElementFlags (used by `enable()`). * Input shape: `{ events?: { eventName: true } }` */ type EnabledEventKeysOf = F extends { events: infer E; } ? keyof E & string : never; /** * Extract event key names made mandatory by Alterations (used by `alter()`). * Input shape: `{ events?: { eventName: { optional: false } } }` */ type AlteredMandatoryEventKeysOf = A extends { events: infer E; } ? { [K in keyof E & string]: E[K] extends { optional: false; } ? K : never; }[keyof E & string] : never; /** * Extract attribute key names from a namespace. */ type AttrKeysOf = N extends { Attributes: infer A; } ? keyof A & string : never; /** * Extract command key names from a namespace. */ type CommandKeysOf = N extends { Commands: infer C; } ? keyof C & string : never; /** * Extract event key names from a namespace. */ type EventKeysOf = N extends { Events: infer E; } ? keyof E & string : never; /** * Produce a typing with all feature flags set to true. Used by `complete` to make all component attributes * mandatory. */ type AllFeaturesAsFlags = N extends { Features: infer F extends string; } ? { [K in Uncapitalize]: true; } : {}; /** * Valid feature names for a namespace's feature selection. */ type FeatureSelection = N extends { Features: infer F extends string; } ? readonly F[] : readonly string[]; /** * Convert a feature name tuple to a feature flags object with explicit true/false for all features. * * Unselected features are explicitly `false` (not absent), * so that `S extends C["flags"]` matches components with `{ offOnly: false }` when offOnly is not selected. */ type FeaturesAsFlags = N extends { Features: infer All extends string; } ? { [K in Uncapitalize]: Capitalize extends `${F[number]}` ? true : false; } : { [K in F[number] as Uncapitalize]: true; }; /** * Constraint for `alter()` input based on namespace element keys. */ type Alterations = { attributes?: { [K in AttrKeysOf]?: ClusterModifier.RequirementModification; }; commands?: { [K in CommandKeysOf]?: ClusterModifier.RequirementModification; }; events?: { [K in EventKeysOf]?: ClusterModifier.RequirementModification; }; }; /** * Constraint for `enable()` input based on namespace element keys. */ type ElementFlags = { attributes?: { [K in AttrKeysOf]?: true; }; commands?: { [K in CommandKeysOf]?: true; }; events?: { [K in EventKeysOf]?: true; }; }; /** * Create a typed map of cluster attributes from a {@link ClusterModel}. */ function attributes(model: ClusterModel): Record>; /** * Create a typed map of cluster commands from a {@link ClusterModel}. */ function commands(model: ClusterModel): Record unknown>>; /** * Create a typed map of cluster events from a {@link ClusterModel}. */ function events(model: ClusterModel): Record>; /** * Create a typed map of cluster features from a {@link ClusterModel}. */ function features(model: ClusterModel): Record; /** * @deprecated Provided for compatibility with external consumers. */ type AttributeValues = RetiredClusterType.AttributeValues; /** * @deprecated Provided for compatibility with external consumers. */ type CommandsOf = RetiredClusterType.CommandsOf; } //# sourceMappingURL=ClusterType.d.ts.map