/** * Hook types for CLI plugin extensibility. * * This module defines the hook interfaces that plugins can implement to extend * CLI functionality, particularly for custom configuration sources. * * ## Custom Config Sources Hook * * The `b2c:config-sources` hook allows plugins to provide custom {@link ConfigSource} * implementations that integrate with the CLI's configuration resolution system. * * @example * ```typescript * // In your plugin's hooks/config-sources.ts * import type { ConfigSourcesHook } from '@salesforce/b2c-tooling-sdk/cli'; * import { MyCustomSource } from '../sources/my-custom-source.js'; * * const hook: ConfigSourcesHook = async function(options) { * return { * sources: [new MyCustomSource()], * priority: 'before', // Override dw.json defaults * }; * }; * * export default hook; * ``` * * @module cli/hooks */ import type { Hook } from '@oclif/core'; import type { ConfigSource, ResolveConfigOptions } from '../config/types.js'; import type { HttpMiddlewareProvider } from '../clients/middleware-registry.js'; import type { AuthMiddlewareProvider } from '../auth/middleware.js'; /** * Options passed to the `b2c:config-sources` hook. * * These options provide context about the current CLI invocation, * allowing plugins to customize their config sources based on user input. */ export interface ConfigSourcesHookOptions { /** The --instance flag value (if provided) */ instance?: string; /** The --config flag value (if provided) */ configPath?: string; /** Full ResolveConfigOptions for advanced sources that need more context */ resolveOptions: ResolveConfigOptions; /** * All parsed CLI flags from the current command. * * Plugins can check for flags they care about. Note that plugins cannot * add flags to commands - they can only read flags that the CLI defines. * For plugin-specific configuration, use environment variables instead. */ flags?: Record; /** Index signature for oclif hook compatibility */ [key: string]: unknown; } /** * Result returned by the `b2c:config-sources` hook. * * Plugins return one or more ConfigSource instances that will be integrated * into the configuration resolution chain. */ export interface ConfigSourcesHookResult { /** Config sources to add to the resolution chain */ sources: ConfigSource[]; /** * Priority for the returned sources. Can be a string or number: * * String values (legacy, still supported): * - `'before'`: Maps to priority -1 (higher priority than defaults) * - `'after'`: Maps to priority 10 (lower priority than defaults) * * Numeric values (preferred): * - Any number. Lower numbers = higher priority. * - Built-in sources use priority 0. * - package.json uses priority 1000. * * If a source already has a `priority` property set, it will not be overridden. * * @default 'after' (maps to 10) */ priority?: 'before' | 'after' | number; } /** * Hook type for `b2c:config-sources`. * * Implement this hook in your oclif plugin to provide custom configuration sources. * The hook is called during command initialization, after CLI flags are parsed * but before configuration is resolved. * * ## Plugin Registration * * Register the hook in your plugin's package.json: * * ```json * { * "oclif": { * "hooks": { * "b2c:config-sources": "./dist/hooks/config-sources.js" * } * } * } * ``` * * ## Hook Context * * Inside the hook function, you have access to: * - `this.config` - oclif Config object * - `this.debug()`, `this.log()`, `this.warn()`, `this.error()` - logging methods * * @example * ```typescript * import type { ConfigSourcesHook } from '@salesforce/b2c-tooling-sdk/cli'; * * const hook: ConfigSourcesHook = async function(options) { * this.debug(`Hook called with instance: ${options.instance}`); * * // Load config from a custom source (e.g., secrets manager) * const source = new VaultConfigSource(options.instance); * * return { * sources: [source], * priority: 'before', // Override dw.json with secrets * }; * }; * * export default hook; * ``` */ export type ConfigSourcesHook = Hook<'b2c:config-sources'>; /** * Options passed to the `b2c:http-middleware` hook. */ export interface HttpMiddlewareHookOptions { /** * All parsed CLI flags from the current command. * * Plugins can inspect flags but cannot add new flags to commands. * For plugin-specific configuration, use environment variables instead. */ flags?: Record; /** Index signature for oclif hook compatibility */ [key: string]: unknown; } /** * Result returned by the `b2c:http-middleware` hook. * * Plugins return one or more HttpMiddlewareProvider instances that will be * registered with the global middleware registry. */ export interface HttpMiddlewareHookResult { /** Middleware providers to register */ providers: HttpMiddlewareProvider[]; } /** * Hook type for `b2c:http-middleware`. * * Implement this hook in your oclif plugin to provide custom HTTP middleware * that will be applied to all API clients (OCAPI, SLAS, WebDAV, etc.). * * The hook is called during command initialization, after flags are parsed * but before any API clients are created. * * ## Plugin Registration * * Register the hook in your plugin's package.json: * * ```json * { * "oclif": { * "hooks": { * "b2c:http-middleware": "./dist/hooks/http-middleware.js" * } * } * } * ``` * * ## Hook Context * * Inside the hook function, you have access to: * - `this.config` - oclif Config object * - `this.debug()`, `this.log()`, `this.warn()`, `this.error()` - logging methods * * @example * ```typescript * import type { HttpMiddlewareHook } from '@salesforce/b2c-tooling-sdk/cli'; * import type { HttpMiddlewareProvider } from '@salesforce/b2c-tooling-sdk/clients'; * * const hook: HttpMiddlewareHook = async function(options) { * this.debug('Registering custom middleware'); * * const metricsProvider: HttpMiddlewareProvider = { * name: 'metrics-collector', * getMiddleware(clientType) { * return { * onRequest({ request }) { * (request as any)._startTime = Date.now(); * return request; * }, * onResponse({ request, response }) { * const duration = Date.now() - (request as any)._startTime; * console.log(`[${clientType}] ${request.method} ${request.url} ${response.status} ${duration}ms`); * return response; * }, * }; * }, * }; * * return { providers: [metricsProvider] }; * }; * * export default hook; * ``` */ export type HttpMiddlewareHook = Hook<'b2c:http-middleware'>; /** * Options passed to the `b2c:auth-middleware` hook. */ export interface AuthMiddlewareHookOptions { /** * All parsed CLI flags from the current command. * * Plugins can inspect flags but cannot add new flags to commands. * For plugin-specific configuration, use environment variables instead. */ flags?: Record; /** Index signature for oclif hook compatibility */ [key: string]: unknown; } /** * Result returned by the `b2c:auth-middleware` hook. * * Plugins return one or more AuthMiddlewareProvider instances that will be * registered with the global auth middleware registry. */ export interface AuthMiddlewareHookResult { /** Middleware providers to register */ providers: AuthMiddlewareProvider[]; } /** * Hook type for `b2c:auth-middleware`. * * Implement this hook in your oclif plugin to provide custom middleware * that will be applied to OAuth token requests. * * The hook is called during command initialization, after flags are parsed * but before any authentication is performed. * * ## Plugin Registration * * Register the hook in your plugin's package.json: * * ```json * { * "oclif": { * "hooks": { * "b2c:auth-middleware": "./dist/hooks/auth-middleware.js" * } * } * } * ``` * * ## Hook Context * * Inside the hook function, you have access to: * - `this.config` - oclif Config object * - `this.debug()`, `this.log()`, `this.warn()`, `this.error()` - logging methods * * @example * ```typescript * import type { AuthMiddlewareHook } from '@salesforce/b2c-tooling-sdk/cli'; * import type { AuthMiddlewareProvider } from '@salesforce/b2c-tooling-sdk/auth'; * * const hook: AuthMiddlewareHook = async function(options) { * this.debug('Registering auth middleware'); * * const userAgentProvider: AuthMiddlewareProvider = { * name: 'custom-user-agent', * getMiddleware() { * return { * onRequest({ request }) { * request.headers.set('User-Agent', 'my-app/1.0'); * return request; * }, * }; * }, * }; * * return { providers: [userAgentProvider] }; * }; * * export default hook; * ``` */ export type AuthMiddlewareHook = Hook<'b2c:auth-middleware'>; export type { B2COperationType, B2COperationContext, BeforeB2COperationResult, B2COperationResult, AfterB2COperationResult, B2COperationLifecycleProvider, B2COperationLifecycleHookOptions, B2COperationLifecycleHookResult, B2COperationLifecycleHook, } from './lifecycle.js'; export { createB2COperationContext, B2CLifecycleRunner } from './lifecycle.js'; export type { CartridgeDiscoveryOptions, CartridgeProvider, CartridgeTransformer, CartridgeProvidersHookOptions, CartridgeProvidersHookResult, CartridgeProvidersHook, } from './cartridge-providers.js'; export { CartridgeProviderRunner } from './cartridge-providers.js'; declare module '@oclif/core' { interface Hooks { 'b2c:config-sources': { options: ConfigSourcesHookOptions; return: ConfigSourcesHookResult; }; 'b2c:http-middleware': { options: HttpMiddlewareHookOptions; return: HttpMiddlewareHookResult; }; 'b2c:auth-middleware': { options: AuthMiddlewareHookOptions; return: AuthMiddlewareHookResult; }; 'b2c:operation-lifecycle': { options: import('./lifecycle.js').B2COperationLifecycleHookOptions; return: import('./lifecycle.js').B2COperationLifecycleHookResult; }; 'b2c:cartridge-providers': { options: import('./cartridge-providers.js').CartridgeProvidersHookOptions; return: import('./cartridge-providers.js').CartridgeProvidersHookResult; }; } }