Skip to content

Lists and Schedules

IFClite can turn model data into configurable property tables, the BIM equivalent of door schedules and wall schedules. The @ifc-lite/lists package evaluates a list definition against parsed model data and produces rows you can display, group, summarise, or export as CSV.

How It Works

A list definition describes what to tabulate:

  • Entity types - Which IFC classes to include (e.g. all IfcDoor)
  • Columns - Which values to pull for each entity (attributes, properties, quantities, ...)
  • Conditions - Optional filters on property values

executeList runs the definition against a data provider (an adapter over your parsed model) and returns a ListResult with one row per matching entity.

Quick Start

import { executeList, listResultToCSV, LIST_PRESETS } from '@ifc-lite/lists';
import type { ListDataProvider } from '@ifc-lite/lists';

// LIST_PRESETS[0] is the Wall Schedule
const result = executeList(LIST_PRESETS[0], provider);

console.log(`${result.rows.length} walls`);

// Export as CSV
const csv = listResultToCSV(result);

executeList(definition, provider, modelId?) takes an optional third argument tagging rows with a model id (defaults to 'default'), useful when running the same list across multiple loaded models.

Column Sources

Each ColumnDefinition has a source that says where the value comes from:

Source Description Example
attribute Direct IFC attribute Name, GlobalId, ObjectType, Class
property Property from a pset Pset_WallCommon.FireRating
quantity Quantity from a qset Qto_WallBaseQuantities.NetArea
material Associated material names (joined with ", ") Concrete, Insulation
classification Classification references (joined with ", ") Uniclass Ss_25_10
spatial Containing spatial element name; propertyName picks the level (Storey (default), Building, Site, Project) Level 2
model Source file name office.ifc

A column looks like:

import type { ColumnDefinition } from '@ifc-lite/lists';

const fireRating: ColumnDefinition = {
  id: 'prop-pset_doorcommon-firerating',
  source: 'property',
  psetName: 'Pset_DoorCommon',
  propertyName: 'FireRating',
  label: 'FireRating',
};

For quantity columns, psetName holds the quantity set name (e.g. Qto_DoorBaseQuantities).

Built-in Presets

LIST_PRESETS is an array of ready-made ListDefinitions:

Preset Entity types Columns
Wall Schedule IfcWall, IfcWallStandardCase Common properties and base quantities
Door Schedule IfcDoor FireRating, IsExternal, AcousticRating, Width, Height, Area
Window Schedule IfcWindow Dimensions
Space Areas IfcSpace Areas and volumes
Zones & Systems IfcSpatialZone, IfcZone, IfcSystem, IfcDistributionSystem Names
All Elements Walls, doors, windows, slabs, columns, beams, stairs, roofs, coverings, curtain walls, railings Overview columns

Worked Example: Door Schedule to CSV

import { executeList, listResultToCSV, LIST_PRESETS } from '@ifc-lite/lists';

// LIST_PRESETS[1] is the Door Schedule:
//   Name, Class, ObjectType,
//   Pset_DoorCommon.FireRating / IsExternal / AcousticRating,
//   Qto_DoorBaseQuantities.Width / Height / Area
const doorSchedule = LIST_PRESETS[1];

const result = executeList(doorSchedule, provider, 'office.ifc');

for (const row of result.rows) {
  console.log(row.values);
}

const csv = listResultToCSV(result);
// listResultToCSV(result, delimiter?) - default delimiter is ','

CSV Safety

listResultToCSV guards against spreadsheet formula injection (CWE-1236): any cell that starts with =, +, -, @, tab, or carriage return is prefixed with a single quote so Excel and Google Sheets treat it as text rather than a formula. Standard CSV quoting (double quotes, "" escaping) is applied on top.

The Data Provider

executeList reads model data through the ListDataProvider interface, so the package has no hard dependency on how you parsed the model. Required methods include getEntitiesByType, getEntityName, getEntityGlobalId, getPropertySets, and getQuantitySets; optional methods (getMaterialNames, getClassifications, getStoreyName, getProjectName, ...) unlock the material, classification, spatial, and model column sources, and the engine degrades gracefully when they are absent.

Discovering Columns

To build a column picker UI (or just see what a model contains), use discoverColumns:

import { discoverColumns } from '@ifc-lite/lists';
import { IfcTypeEnum } from '@ifc-lite/data';

// Accepts one provider or an array of providers
const discovered = discoverColumns(provider, [IfcTypeEnum.IfcDoor]);

discovered.attributes;  // available entity attributes
discovered.properties;  // Map<psetName, propertyNames[]>
discovered.quantities;  // Map<qsetName, quantityNames[]>

It samples up to 50 entities per type per provider, so it stays fast on large models.

Name Patterns

Conditions and lookups that match by name accept either an exact string or a regex literal. compileNameMatcher(pattern) returns a (name: string) => boolean:

  • /fire.*rating/i - a /body/flags string compiles to a regular expression
  • anything else - exact, case-sensitive match

isNamePattern(pattern) tells you whether a string will be treated as a regex.

Key Exports

Export Description
executeList(definition, provider, modelId?) Run a list definition, returns ListResult
listResultToCSV(result, delimiter?) CSV export with formula-injection guard
summariseListRows Aggregate rows into group summaries
discoverColumns(providers, entityTypes) Sample available attributes/properties/quantities
compileNameMatcher(pattern) / isNamePattern(pattern) Exact-or-regex name matching
LIST_PRESETS Built-in schedule definitions
ENTITY_ATTRIBUTES The attribute names available to attribute columns

See the package README and the type definitions (ListDefinition, ColumnDefinition, PropertyCondition, ListDataProvider) for the full API.