JIRA Magic Library - Main Class

Example

const jml = new JML({
baseUrl: 'https://jira.company.com',
auth: { token: 'your-pat-token' },
apiVersion: 'v2',
});

const result = await jml.issues.create({
Project: 'PROJ',
'Issue Type': 'Bug',
Summary: 'Example issue',
});

Constructors

Properties

issues: IssuesAPI

Issue operations entry point.

Provides high-level helpers such as IssueOperations.create which back the public API jml.issues.create(...). All bulk batching, manifest handling, and hierarchy routing flows live behind this property.

Methods

  • Disconnect and clean up resources

    Closes Redis connection and cleans up any other resources. Call this when you're done using the library.

    Returns Promise<void>

  • Get field schema for a specific project and issue type

    Returns all available fields with their types, whether they're required, and allowed values (for option/multi-option fields).

    Parameters

    • projectKey: string

      JIRA project key (e.g., "ENG")

    • issueTypeName: string

      Issue type name (e.g., "Bug", "Task")

    Returns Promise<ProjectSchema>

    Promise resolving to the project schema

    Throws

    if the project or issue type doesn't exist

    Example

    const schema = await jml.getFieldSchema('ENG', 'Bug');
    console.log(Object.keys(schema.fields)); // ["summary", "priority", "customfield_10024", ...]
  • Get issue type hierarchy configuration

    Returns the JPO (JIRA Portfolio) hierarchy structure if available, showing which issue types can be parents of other issue types. Returns null if JPO is not installed (use standard parent fields instead).

    Note: Hierarchy is global across all projects in the JIRA instance.

    Parameters

    • Optional options: {
          refresh?: boolean;
      }

      Optional settings (refresh: force cache refresh)

      • Optional refresh?: boolean

    Returns Promise<null | HierarchyLevel[]>

    Promise resolving to array of hierarchy levels or null if JPO not installed

    Example

    const hierarchy = await jml.getHierarchy();
    if (hierarchy) {
    // JPO installed - hierarchy is an array of levels
    console.log(hierarchy); // [{ id: 0, title: "Subtask", issueTypeIds: [...] }, ...]

    // Find issue types at each level
    const epicLevel = hierarchy.find(l => l.title === 'Epic');
    console.log(`Epic issue type IDs: ${epicLevel.issueTypeIds}`);
    } else {
    // Standard JIRA - use built-in parent field
    console.log('No JPO hierarchy - use Parent/Epic Link fields');
    } * ```
  • Get available issue types for a project

    Returns all issue types that can be created in the specified project, with their IDs and names. Useful for building UIs or validating parent-child relationships with the hierarchy structure.

    Delegates to SchemaDiscovery which already fetches this data.

    Parameters

    • projectKey: string

      JIRA project key (e.g., "ENG")

    Returns Promise<{
        id: string;
        name: string;
    }[]>

    Promise resolving to array of issue type metadata

    Throws

    if the project doesn't exist

    Example

    const issueTypes = await jml.getIssueTypes('ENG');
    console.log(issueTypes);
    // [
    // { id: "10000", name: "Epic" },
    // { id: "10001", name: "Story" },
    // { id: "10002", name: "Bug" },
    // { id: "10003", name: "Task" },
    // { id: "10004", name: "Sub-task" }
    // ]

    // Combine with hierarchy to validate parent-child relationships
    const hierarchy = await jml.getHierarchy();
    const storyType = issueTypes.find(t => t.name === 'Story');
    const epicLevel = hierarchy?.find(l => l.issueTypeIds.includes(storyType.id));
  • Discover the parent field for a specific project and issue type

    Returns information about the parent field used for linking issues in a hierarchy. The library uses this to determine which field name users can use for parent references (e.g., "Parent Link", "Epic Link").

    Detection priority:

    1. Plugin-based detection (most reliable) - JPO or GreenHopper plugins
    2. Name pattern matching - fields matching "parent" patterns
    3. Returns null if no parent field found

    Results are cached for 1 hour to minimize API calls.

    Parameters

    • projectKey: string

      JIRA project key (e.g., "ENG")

    • issueTypeName: string

      Issue type name (e.g., "Story", "Epic")

    Returns Promise<null | ParentFieldInfo>

    Promise resolving to parent field info or null if not found

    Example

    // Discover parent field for Stories
    const parentField = await jml.getParentField('ENG', 'Story');
    if (parentField) {
    console.log(`Parent field: ${parentField.name} (${parentField.key})`);
    // "Parent field: Parent Link (customfield_10014)"

    // Now you know you can use this in issue creation:
    await jml.issues.create({
    Project: 'ENG',
    'Issue Type': 'Story',
    Summary: 'My Story',
    [parentField.name]: 'EPIC-123', // Use discovered field name
    // OR
    Parent: 'EPIC-123', // "Parent" always works
    });
    }

    // Discover parent fields for all issue types
    const issueTypes = await jml.getIssueTypes('ENG');
    for (const type of issueTypes) {
    const parent = await jml.getParentField('ENG', type.name);
    console.log(`${type.name}: ${parent?.name ?? 'No parent field'}`);
    }
  • Validate issue data against JIRA schema without creating issues

    Performs fast, schema-only validation:

    • Required fields present
    • Field types match schema
    • Enum values valid

    Does NOT perform field name→ID lookups or value conversions. Performance target: <100ms for 100 rows.

    Parameters

    Returns Promise<ValidationResult>

    Validation result with errors array

    Example

    // Validate before creating
    const result = await jml.validate({
    data: [
    { Project: 'ENG', 'Issue Type': 'Bug', Summary: 'Test' }
    ]
    });

    if (!result.valid) {
    result.errors.forEach(err => {
    console.error(`Row ${err.rowIndex}: ${err.field} - ${err.message}`);
    });
    } else {
    // Validation passed, safe to create
    await jml.issues.create({ data: [...] });
    }

    // Validate from file
    const csvResult = await jml.validate({ from: 'issues.csv' });
  • Validate connection to JIRA

    Tests the connection by fetching server info. Useful for verifying credentials and connectivity before making requests.

    Returns Promise<ServerInfo>

    Server information from JIRA

    Throws

    if JIRA is unreachable

    Throws

    if credentials are invalid

    Example

    const jml = new JML(config);
    const serverInfo = await jml.validateConnection();
    console.log(`Connected to JIRA ${serverInfo.version}`);