Provides a comprehensive deprecation management workflow for Ember applications.
npx @tessl/cli install tessl/npm-ember-cli-deprecation-workflow@3.4.0ember-cli-deprecation-workflow is an Ember CLI addon that provides a comprehensive deprecation management workflow for Ember applications. It helps developers systematically address deprecations during Ember upgrades by controlling console output, collecting deprecation data, and enabling incremental deprecation resolution.
ember install ember-cli-deprecation-workflowimport setupDeprecationWorkflow from 'ember-cli-deprecation-workflow';For named exports:
import {
detectWorkflow,
flushDeprecations,
handleDeprecationWorkflow,
deprecationCollector
} from 'ember-cli-deprecation-workflow';// 1. Create app/deprecation-workflow.js
import setupDeprecationWorkflow from 'ember-cli-deprecation-workflow';
setupDeprecationWorkflow({
throwOnUnhandled: false,
workflow: [
{ handler: 'silence', matchId: 'some.deprecation.id' },
{ handler: 'log', matchMessage: /pattern/ },
{ handler: 'throw', matchId: 'critical.deprecation' }
]
});
// 2. Import in app/app.js
import './deprecation-workflow';
// 3. Collect deprecations during testing
// Run in browser console: deprecationWorkflow.flushDeprecations()ember-cli-deprecation-workflow is built around several key components:
Maximum number of log messages per deprecation before rate limiting takes effect.
/** Maximum number of console log messages per deprecation ID */
const LOG_LIMIT: number = 100;Primary function to set up the deprecation workflow system with custom configuration.
/**
* Sets up deprecation workflow with custom configuration
* @param config - Optional configuration object
*/
function setupDeprecationWorkflow(config?: DeprecationWorkflowConfig): void;
interface DeprecationWorkflowConfig {
/** Throw error for deprecations that don't match any workflow rule */
throwOnUnhandled?: boolean;
/** Array of workflow rules for handling specific deprecations */
workflow?: Workflow[];
}
interface WorkflowMatchId {
/** How to handle the matched deprecation */
handler?: 'silence' | 'log' | 'throw';
/** Match deprecations by their unique ID (string or regex) */
matchId: string | RegExp;
}
interface WorkflowMatchMessage {
/** How to handle the matched deprecation */
handler?: 'silence' | 'log' | 'throw';
/** Match deprecations by their message content (string or regex) */
matchMessage: string | RegExp;
}
type Workflow = WorkflowMatchId | WorkflowMatchMessage;Usage Examples:
// Basic setup with no configuration (uses defaults)
setupDeprecationWorkflow();
// Setup with throwOnUnhandled enabled
setupDeprecationWorkflow({
throwOnUnhandled: true
});
// Setup with specific workflow rules
setupDeprecationWorkflow({
workflow: [
{ handler: 'silence', matchId: 'ember-data.deprecation' },
{ handler: 'log', matchMessage: /template/ },
{ handler: 'throw', matchId: 'critical.breaking.change' }
]
});
// Handler is optional - defaults to application or console behavior
setupDeprecationWorkflow({
workflow: [
{ matchId: 'some.deprecation' }, // Uses default behavior
{ handler: 'silence', matchMessage: /pattern/ }
]
});Generate configuration code from collected deprecations during runtime.
/**
* Generate JavaScript configuration code from collected deprecations
* @param options - Optional flush configuration with destructuring default
* @returns Generated JavaScript code string for deprecation workflow setup
*/
function flushDeprecations(options?: {
/** Default handler for newly discovered deprecations (defaults to 'silence') */
handler?: 'silence' | 'log' | 'throw';
/** Existing configuration to merge with collected deprecations (defaults to empty config) */
config?: DeprecationWorkflowConfig;
}): string;Usage Examples:
// Flush with default 'silence' handler
const config = deprecationWorkflow.flushDeprecations();
// Flush with 'log' handler for new deprecations
const config = deprecationWorkflow.flushDeprecations({ handler: 'log' });
// Flush and merge with existing configuration
const existingConfig = { throwOnUnhandled: true, workflow: [] };
const config = deprecationWorkflow.flushDeprecations({
handler: 'silence',
config: existingConfig
});
// Note: Only newly collected deprecations not already in existing config will be addedDetermine which workflow rule matches a given deprecation.
/**
* Detect which workflow rule matches a deprecation
* @param config - Deprecation workflow configuration
* @param message - Deprecation message
* @param options - Deprecation metadata from Ember
* @returns Matching workflow rule or undefined
*/
function detectWorkflow(
config: DeprecationWorkflowConfig,
message: string,
options: DeprecationOptions
): Workflow | undefined;
interface DeprecationOptions {
/** Unique identifier for the deprecation */
id?: string;
/** Version when the feature was deprecated */
since?: string;
/** Version when the feature will be removed */
until?: string;
/** Description of what is being deprecated */
for?: string;
}Core function that processes deprecations according to workflow configuration.
/**
* Handle a deprecation according to workflow configuration
* @param config - Deprecation workflow configuration
* @param message - Deprecation message
* @param options - Deprecation metadata
* @param next - Callback to pass control to next handler
*/
function handleDeprecationWorkflow(
config: DeprecationWorkflowConfig,
message: string,
options: DeprecationOptions,
next: (message: string, options: DeprecationOptions) => void
): void;Collect deprecation IDs for later configuration generation.
/**
* Collect deprecation IDs for configuration generation
* @param message - Deprecation message
* @param options - Deprecation metadata
* @param next - Callback to continue deprecation chain
*/
function deprecationCollector(
message: string,
options: DeprecationOptions,
next: (message: string, options: DeprecationOptions) => void
): void;Completely suppresses deprecation output with no console logging.
{ handler: 'silence', matchId: 'some.deprecation.id' }Allows normal deprecation logging with rate limiting (maximum 100 messages per deprecation).
{ handler: 'log', matchMessage: /template-related/ }Converts deprecation to thrown error, halting execution. Warning: May break application.
{ handler: 'throw', matchId: 'critical.breaking.change' }The addon exposes global functionality for runtime deprecation management.
interface DeprecationWorkflowGlobal {
/** Global access to flush deprecations function */
flushDeprecations(options?: {
handler?: 'silence' | 'log' | 'throw';
config?: DeprecationWorkflowConfig;
}): string;
/** Collected deprecation data */
deprecationLog: {
/** Set of unique deprecation IDs encountered */
messages: Set<string>;
};
/** Count of log messages per deprecation (for rate limiting, initialized on first log) */
logCounts?: Record<string, number>;
}
/** Global deprecation workflow instance */
declare const deprecationWorkflow: DeprecationWorkflowGlobal;Usage Examples:
// Access collected deprecation IDs
console.log(deprecationWorkflow.deprecationLog.messages);
// Generate configuration from collected deprecations
const config = deprecationWorkflow.flushDeprecations();
// Check log counts for rate limiting
console.log(deprecationWorkflow.logCounts);Configure the addon behavior in your Ember CLI build.
interface EmberCLIDeprecationWorkflowConfig {
/** Force enable/disable the addon (bypasses test detection) */
enabled?: boolean;
}Usage in ember-cli-build.js:
module.exports = function(defaults) {
let app = new EmberApp(defaults, {
'ember-cli-deprecation-workflow': {
enabled: true // Force enable in development even without tests
}
});
return app.toTree();
};Exact string matching for deprecation IDs or messages.
{ handler: 'silence', matchId: 'ember-data.deprecation.exact-match' }
{ handler: 'log', matchMessage: 'Exact deprecation message' }Pattern-based matching using JavaScript RegExp objects.
{ handler: 'silence', matchId: /^ember-data\./ }
{ handler: 'log', matchMessage: /template.*deprecated/ }When throwOnUnhandled: true, unmatched deprecations throw errors:
// Throws: Error with original deprecation message
setupDeprecationWorkflow({ throwOnUnhandled: true });When using handler: 'throw', matched deprecations throw formatted errors:
// Throws: Error("Deprecation message (id: deprecation.id)")
// If no id provided: Error("Deprecation message (id: unknown)")
{ handler: 'throw', matchId: 'some.deprecation' }The addon automatically includes a vendor bridge script that attempts to call setupDeprecationWorkflow() with no configuration when the addon is loaded. This provides basic deprecation collection even without explicit configuration.
// Vendor bridge behavior (automatic)
try {
require('ember-cli-deprecation-workflow').default();
} catch (e) {
// Silently fails if addon not available
}silence, log, throw) only operate in development/test environmentsember install ember-cli-deprecation-workflowapp/deprecation-workflow.js with setupDeprecationWorkflow()import './deprecation-workflow'; to app/app.jsdeprecationWorkflow.flushDeprecations() in browser consoleapp/deprecation-workflow.js contentsilence to throw, fix, and remove