or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

component-rules.mdcomputed-property-rules.mdember-utils.mdindex.mdlegacy-configuration.mdmigration-rules.mdmodern-configuration.mdplugin-configuration.mdroute-rules.mdservice-rules.mdtest-rules.md
tile.json

ember-utils.mddocs/

Ember Utils

Comprehensive utility functions for AST analysis and Ember-specific pattern detection. These utilities are primarily used for developing custom ESLint rules and analyzing Ember.js code patterns.

Capabilities

Core Module Detection

Functions for detecting Ember core modules and framework components.

/**
 * Check if a node represents an Ember Data model
 * @param node - AST node to check
 * @param filePath - Optional file path for additional context
 * @returns {boolean} True if node is a DS.Model
 */
function isDSModel(node: ASTNode, filePath?: string): boolean;

/**
 * Check if a node represents a specific Ember module
 * @param node - AST node to check
 * @param element - Module element name (e.g., 'Component', 'Service')
 * @param moduleName - Module namespace (default: 'Ember')
 * @returns {boolean} True if node matches the module pattern
 */
function isModule(node: ASTNode, element: string, moduleName?: string): boolean;

/**
 * Check if a file path indicates a specific module type
 * @param filePath - File path to analyze
 * @param module - Module type to check for
 * @returns {boolean} True if file path matches module pattern
 */
function isModuleByFilePath(filePath: string, module: string): boolean;

/**
 * Check if a node is any Ember core module
 * @param context - ESLint context
 * @param node - AST node to check
 * @returns {boolean} True if node is any Ember core module
 */
function isAnyEmberCoreModule(context: ESLintContext, node: ASTNode): boolean;

Usage Examples:

const emberUtils = require('eslint-plugin-ember').utils.ember;

// Check if node is a DS.Model
if (emberUtils.isDSModel(node, context.getFilename())) {
  // Handle Ember Data model
}

// Check if node is an Ember Component
if (emberUtils.isModule(node, 'Component')) {
  // Handle component definition
}

// Check if file is a controller by path
if (emberUtils.isModuleByFilePath('/app/controllers/user.js', 'controller')) {
  // Handle controller file
}

Ember Core Module Detection

Specific functions for detecting different types of Ember core modules.

/**
 * Check if node is an Ember Component
 */
function isEmberComponent(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is a Glimmer Component
 */
function isGlimmerComponent(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an Ember Controller
 */
function isEmberController(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an Ember Mixin
 */
function isEmberMixin(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an Ember Route
 */
function isEmberRoute(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an Ember Service
 */
function isEmberService(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an ArrayProxy
 */
function isEmberArrayProxy(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an ObjectProxy
 */
function isEmberObjectProxy(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an EmberObject
 */
function isEmberObject(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is an Ember Helper
 */
function isEmberHelper(context: ESLintContext, node: ASTNode): boolean;

/**
 * Check if node is any Ember proxy type
 */
function isEmberProxy(context: ESLintContext, node: ASTNode): boolean;

Usage Examples:

// In a custom ESLint rule
create(context) {
  return {
    ClassDeclaration(node) {
      if (emberUtils.isEmberComponent(context, node)) {
        // Handle Ember component class
      }
      
      if (emberUtils.isGlimmerComponent(context, node)) {
        // Handle Glimmer component class
      }
    },
    
    CallExpression(node) {
      if (emberUtils.isEmberService(context, node)) {
        // Handle service definition
      }
    }
  };
}

Property Detection Functions

Functions for detecting different types of properties in Ember objects.

/**
 * Check if property is a service injection
 * @param node - Property node to check
 * @param importedEmberName - Name Ember is imported as
 * @param importedInjectName - Name inject is imported as
 */
function isInjectedServiceProp(node: ASTNode, importedEmberName: string, importedInjectName: string): boolean;

/**
 * Check if property is a controller injection
 */
function isInjectedControllerProp(node: ASTNode, importedEmberName: string, importedControllerName: string): boolean;

/**
 * Check if property is an observer
 */
function isObserverProp(node: ASTNode, importedEmberName: string, importedObserverName: string): boolean;

/**
 * Check if property is a computed property
 * @param options - Configuration options for computed property detection
 */
function isComputedProp(
  node: ASTNode, 
  importedEmberName: string, 
  importedComputedName: string, 
  options?: ComputedPropOptions
): boolean;

interface ComputedPropOptions {
  /** Include properties with suffixes like .volatile() */
  includeSuffix?: boolean;
  /** Include computed property macros like computed.and() */
  includeMacro?: boolean;
}

/**
 * Check if property is an object property
 */
function isObjectProp(node: ASTNode): boolean;

/**
 * Check if property is an array property
 */
function isArrayProp(node: ASTNode): boolean;

/**
 * Check if property is a custom property
 */
function isCustomProp(property: ASTNode): boolean;

/**
 * Check if property is an actions hash
 */
function isActionsProp(property: ASTNode): boolean;

/**
 * Check if property is an Ember Data relationship
 */
function isRelation(property: ASTNode): boolean;

Usage Examples:

// Detect service injections
if (emberUtils.isInjectedServiceProp(property, 'Ember', 'service')) {
  // Handle service injection
}

// Detect computed properties with options
if (emberUtils.isComputedProp(property, 'Ember', 'computed', { 
  includeSuffix: true, 
  includeMacro: true 
})) {
  // Handle computed property
}

// Detect actions hash
if (emberUtils.isActionsProp(property)) {
  // Report actions hash usage
}

Lifecycle Hook Detection

Functions for detecting various lifecycle hooks in Ember objects.

/**
 * Check if property is a route lifecycle hook
 */
function isRouteLifecycleHook(property: ASTNode): boolean;

/**
 * Check if property is a component lifecycle hook
 */
function isComponentLifecycleHook(property: ASTNode): boolean;

/**
 * Check if property is a Glimmer component lifecycle hook
 */
function isGlimmerComponentLifecycleHook(property: ASTNode): boolean;

Usage Examples:

// Check for lifecycle hooks in components
if (emberUtils.isComponentLifecycleHook(property)) {
  context.report({
    node: property,
    message: 'Component lifecycle hooks are deprecated'
  });
}

// Validate route lifecycle hooks
if (emberUtils.isRouteLifecycleHook(property)) {
  // Ensure proper super calls
}

Function Analysis Functions

Functions for analyzing function patterns and expressions.

/**
 * Check if property is a single-line function
 */
function isSingleLineFn(property: ASTNode, importedEmberName: string, importedObserverName: string): boolean;

/**
 * Check if property is a multi-line function
 */
function isMultiLineFn(property: ASTNode, importedEmberName: string, importedObserverName: string): boolean;

/**
 * Check if property is a function expression
 */
function isFunctionExpression(property: ASTNode): boolean;

Object Pattern Detection

Functions for detecting Ember object patterns and method calls.

/**
 * Check if node uses extend() pattern
 */
function isExtendObject(node: ASTNode): boolean;

/**
 * Check if node uses reopen() pattern
 */
function isReopenObject(node: ASTNode): boolean;

/**
 * Check if node uses reopenClass() pattern
 */
function isReopenClassObject(node: ASTNode): boolean;

/**
 * Check if node is a route() call
 */
function isRoute(node: ASTNode): boolean;

Computed Property Analysis

Functions for analyzing computed properties and their dependencies.

/**
 * Parse dependent keys from a computed property call
 * @param callExp - Call expression to analyze
 * @returns {string[]} Array of dependent key strings
 */
function parseDependentKeys(callExp: ASTNode): string[];

/**
 * Unwrap brace expressions in dependent keys
 * @param dependentKeys - Array of dependent key strings
 * @returns {string[]} Expanded dependent keys
 */
function unwrapBraceExpressions(dependentKeys: string[]): string[];

/**
 * Check if computed property has duplicate dependent keys
 */
function hasDuplicateDependentKeys(
  callExp: ASTNode, 
  importedEmberName: string, 
  importedComputedName: string
): boolean;

Usage Examples:

// Analyze computed property dependencies
const dependentKeys = emberUtils.parseDependentKeys(computedCall);
const expandedKeys = emberUtils.unwrapBraceExpressions(dependentKeys);

// Check for duplicates
if (emberUtils.hasDuplicateDependentKeys(computedCall, 'Ember', 'computed')) {
  context.report({
    node: computedCall,
    message: 'Computed property has duplicate dependent keys'
  });
}

File and Context Analysis

Functions for analyzing file context and detecting test files.

/**
 * Check if filename represents a test file
 * @param fileName - File name to check
 * @returns {boolean} True if file is a test file
 */
function isTestFile(fileName: string): boolean;

/**
 * Check if filename is in a Mirage directory
 */
function isMirageDirectory(fileName: string): boolean;

/**
 * Check if filename is a Mirage config file
 */
function isMirageConfig(fileName: string): boolean;

Module and Import Analysis

Functions for analyzing module structure and imports.

/**
 * Get properties from an Ember module definition
 * @param moduleNode - Module definition node
 * @param scopeManager - ESLint scope manager
 * @returns {ASTNode[]} Array of property nodes
 */
function getModuleProperties(moduleNode: ASTNode, scopeManager: ScopeManager): ASTNode[];

/**
 * Get alias name for default Ember import
 * @param importDeclaration - Import declaration node
 * @returns {string|null} Import alias name or null
 */
function getEmberImportAliasName(importDeclaration: ASTNode): string | null;

Advanced Pattern Detection

Advanced utility functions for complex pattern detection.

/**
 * Check if EmberObject implements unknownProperty
 */
function isEmberObjectImplementingUnknownProperty(node: ASTNode, scopeManager: ScopeManager): boolean;

/**
 * Check if decorator is an observer decorator
 */
function isObserverDecorator(node: ASTNode, importedObservesName: string): boolean;

/**
 * Convert service name to kebab-case
 * @param serviceName - Service name to convert
 * @returns {string} Kebab-cased service name
 */
function convertServiceNameToKebabCase(serviceName: string): string;

Usage Examples:

// Check for unknownProperty implementation
if (emberUtils.isEmberObjectImplementingUnknownProperty(classNode, scopeManager)) {
  // Handle unknownProperty usage
}

// Convert service names
const kebabName = emberUtils.convertServiceNameToKebabCase('currentUser');
// Returns: 'current-user'