// SPDX-FileCopyrightText: © 2026 LEDGER SAS // SPDX-License-Identifier: Apache-2.0 /** * Marks a function as a framework-built "not supported" stub. * * `Symbol.for` (the global registry) is used deliberately: in a monorepo the framework * may be present as more than one physical module instance, and a locally-scoped symbol * would not match across them. */ const NOT_SUPPORTED_STUB = Symbol.for('@ledgerhq/coin-module-framework:notSupportedStub') /** * Build a {@link CoinModuleApi} method stub that always throws a standardized * "not supported" error. Use it for optional API methods a module does not implement. * * The returned function is tagged so the framework can tell it apart from a real * implementation — see {@link isNotSupportedStub}. * * @param name the API method name, used in the error message * @returns a function that throws `" is not supported"` when invoked */ export const notSupported = (name: string) => { const stub = (): never => { throw new Error(`${name} is not supported`) } Object.defineProperty(stub, NOT_SUPPORTED_STUB, { value: true, enumerable: false }) return stub } /** * Tells whether a value is a stub produced by {@link notSupported}, i.e. a placeholder * rather than a real implementation. * * **Limitation** — only stubs built by {@link notSupported} are detectable. A module that * hand-rolls `() => { throw new Error('x is not supported') }` inline is indistinguishable * from a real implementation, because whether a function throws cannot be known without * calling it. Modules should therefore either omit an unsupported method entirely (the * migrated shape) or build its stub with {@link notSupported}. */ export function isNotSupportedStub(value: unknown): boolean { return typeof value === 'function' && NOT_SUPPORTED_STUB in value }