A JavaScript framework for creating ambitious web applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Development tools and debugging utilities for inspecting application state and troubleshooting issues.
Core debugging functions for assertions, warnings, and development-time feedback.
/**
* Runtime assertion that throws error if condition is false
* @param message - Error message to display
* @param condition - Condition that must be true
*/
function assert(message: string, condition: boolean): void;
/**
* Display warning message in development builds
* @param message - Warning message
* @param condition - Condition to test (warning shown if false)
* @param options - Additional warning options
*/
function warn(message: string, condition?: boolean, options?: WarnOptions): void;
/**
* Log debug message (only in debug builds)
* @param message - Debug message to log
*/
function debug(message: string): void;
/**
* Display deprecation warning for outdated API usage
* @param message - Deprecation message
* @param condition - Condition to test (deprecation shown if false)
* @param options - Deprecation options including id and until version
*/
function deprecate(message: string, condition?: boolean, options?: DeprecateOptions): void;
/**
* Execute code only in debug builds
* @param fn - Function to execute in debug mode
*/
function runInDebug(fn: () => void): void;Usage Examples:
import { assert, warn, debug, deprecate, runInDebug } from "@ember/debug";
export default class UserService extends Service {
createUser(userData) {
// Assertions for required parameters
assert('User data is required', userData != null);
assert('User must have email', userData.email);
assert('Email must be valid', userData.email.includes('@'));
// Warnings for potentially problematic situations
warn('User age not provided, defaulting to 0', userData.age != null, {
id: 'user-service.missing-age'
});
// Debug logging (only appears in development)
debug(`Creating user: ${userData.email}`);
// Deprecation warning for old API usage
if (userData.userName) {
deprecate('userName is deprecated, use username instead', false, {
id: 'user-service.user-name-deprecated',
until: '4.0.0',
url: 'https://example.com/migration-guide'
});
userData.username = userData.userName;
}
// Development-only code
runInDebug(() => {
console.log('User creation debug info:', {
timestamp: new Date(),
userData: userData,
stackTrace: new Error().stack
});
});
return this.store.createRecord('user', userData);
}
}
// Component example
export default class FormComponent extends Component {
@action
submitForm(event) {
event.preventDefault();
const formData = new FormData(event.target);
const email = formData.get('email');
const password = formData.get('password');
// Validate inputs with assertions
assert('Email is required for form submission', email);
assert('Password is required for form submission', password);
// Warn about potential issues
warn('Password is very short', password.length >= 8, {
id: 'form.weak-password'
});
debug(`Form submitted with email: ${email}`);
this.onSubmit?.({ email, password });
}
}Functions for inspecting and debugging object state.
/**
* Create detailed string representation of object for debugging
* @param obj - Object to inspect
* @param options - Inspection options
* @returns String representation of object
*/
function inspect(obj: any, options?: InspectOptions): string;Usage Examples:
import { inspect } from "@ember/debug";
export default class DebuggingService extends Service {
@tracked debugData = null;
@action
captureState() {
const appState = {
currentUser: this.session.currentUser,
route: this.router.currentRouteName,
queryParams: this.router.currentRoute.queryParams,
timestamp: new Date()
};
// Create detailed inspection for debugging
const inspected = inspect(appState, {
depth: 3,
showHidden: false,
showProxy: true
});
console.log('Application state:', inspected);
this.debugData = inspected;
}
@action
inspectObject(object) {
console.log('Object details:', inspect(object));
// Different inspection levels
console.log('Shallow:', inspect(object, { depth: 1 }));
console.log('Deep:', inspect(object, { depth: 5 }));
}
}Adapter classes for integrating with browser developer tools.
/**
* Container debug adapter for inspecting dependency injection container
*/
class ContainerDebugAdapter extends EmberObject {
/**
* Create container debug adapter
* @param properties - Adapter properties
* @returns ContainerDebugAdapter instance
*/
static create(properties?: object): ContainerDebugAdapter;
/**
* Get all registered factories by type
* @param type - Factory type (e.g., 'service', 'route', 'component')
* @returns Array of factory information
*/
catalogEntriesByType(type: string): FactoryInfo[];
/**
* Get container information
* @returns Container debug information
*/
getContainerInfo(): ContainerInfo;
}
/**
* Data adapter for inspecting data layer (typically for Ember Data)
*/
class DataAdapter extends EmberObject {
/**
* Create data debug adapter
* @param properties - Adapter properties
* @returns DataAdapter instance
*/
static create(properties?: object): DataAdapter;
/**
* Get model types for data inspector
* @returns Array of model type information
*/
getModelTypes(): ModelTypeInfo[];
/**
* Get records for a model type
* @param modelType - Model type to get records for
* @returns Array of record information
*/
getRecords(modelType: string): RecordInfo[];
/**
* Watch model type for changes
* @param modelType - Model type to watch
* @param recordsAdded - Callback for added records
* @param recordsUpdated - Callback for updated records
* @param recordsRemoved - Callback for removed records
* @returns Release function to stop watching
*/
watchModelType(
modelType: string,
recordsAdded: (records: any[]) => void,
recordsUpdated: (records: any[]) => void,
recordsRemoved: (records: any[]) => void
): () => void;
}Development-time error handling and reporting utilities.
/**
* Register global error handler for development debugging
* @param handler - Error handling function
*/
function registerErrorHandler(handler: (error: Error) => void): void;
/**
* Register warning handler for custom warning processing
* @param handler - Warning handling function
*/
function registerWarnHandler(handler: (message: string, options: any, next: Function) => void): void;
/**
* Register deprecation handler for custom deprecation processing
* @param handler - Deprecation handling function
*/
function registerDeprecationHandler(handler: (message: string, options: any, next: Function) => void): void;Usage Examples:
import {
registerErrorHandler,
registerWarnHandler,
registerDeprecationHandler
} from "@ember/debug";
// Custom error tracking in development
if (ENV.environment === 'development') {
registerErrorHandler((error) => {
console.group('🚨 Ember Error');
console.error('Error:', error.message);
console.error('Stack:', error.stack);
console.error('Context:', {
route: window.location.pathname,
timestamp: new Date().toISOString()
});
console.groupEnd();
// Send to error tracking service
this.errorTracking.captureException(error);
});
registerWarnHandler((message, options, next) => {
// Custom warning processing
console.warn(`⚠️ Warning: ${message}`, options);
// Log to analytics
this.analytics.track('ember-warning', {
message,
id: options?.id,
url: options?.url
});
// Call default handler
next(message, options);
});
registerDeprecationHandler((message, options, next) => {
// Track deprecation usage
this.analytics.track('ember-deprecation', {
message,
id: options?.id,
until: options?.until
});
// Call default handler
next(message, options);
});
}Additional utilities for development and debugging workflows.
/**
* Get Ember version information
* @returns Version string
*/
function getEmberVersion(): string;
/**
* Check if running in development environment
* @returns Whether in development mode
*/
function isDevelopment(): boolean;
/**
* Check if running in testing environment
* @returns Whether in testing mode
*/
function isTesting(): boolean;
/**
* Enable or disable specific debug features
* @param feature - Feature name to toggle
* @param enabled - Whether to enable the feature
*/
function toggleDebugFeature(feature: string, enabled: boolean): void;Usage Examples:
import {
getEmberVersion,
isDevelopment,
isTesting,
toggleDebugFeature
} from "@ember/debug";
export default class ApplicationController extends Controller {
init() {
super.init(...arguments);
if (isDevelopment()) {
console.log(`Running Ember ${getEmberVersion()}`);
// Enable additional debugging features
toggleDebugFeature('ds-warn-on-unknown-keys', true);
toggleDebugFeature('ds-improve-debug', true);
// Add global debugging helpers
window.debugApp = this;
window.inspectRoute = () => {
const route = this.router.currentRoute;
console.log('Current route:', inspect(route));
};
}
if (isTesting()) {
// Disable certain features in testing
toggleDebugFeature('ds-warn-on-unknown-keys', false);
}
}
}interface WarnOptions {
/** Unique identifier for this warning */
id?: string;
/** URL with more information */
url?: string;
}
interface DeprecateOptions {
/** Unique identifier for this deprecation */
id: string;
/** Version when this will be removed */
until: string;
/** URL with migration information */
url?: string;
/** Additional context */
for?: string;
/** Since which version this is deprecated */
since?: string;
}
interface InspectOptions {
/** Maximum depth to inspect */
depth?: number;
/** Show hidden properties */
showHidden?: boolean;
/** Show proxy information */
showProxy?: boolean;
/** Custom colors */
colors?: boolean;
}
interface FactoryInfo {
/** Factory name */
name: string;
/** Factory type */
type: string;
/** Whether factory is singleton */
singleton: boolean;
/** Whether factory is instantiable */
instantiate: boolean;
}
interface ContainerInfo {
/** Registered factories */
registrations: Record<string, any>;
/** Container cache */
cache: Record<string, any>;
/** Factory cache */
factoryManagerCache: Record<string, any>;
}
interface ModelTypeInfo {
/** Model name */
name: string;
/** Model count */
count: number;
/** Model columns/attributes */
columns: ColumnInfo[];
}
interface RecordInfo {
/** Record identifier */
id: string;
/** Record attributes */
attributes: Record<string, any>;
/** Record relationships */
relationships: Record<string, any>;
}
interface ColumnInfo {
/** Column name */
name: string;
/** Column description */
desc: string;
}Install with Tessl CLI
npx tessl i tessl/npm-ember-source