Skip to main content

Package reference

The toolchain is a workspace monorepo of seven packages. The dependency direction is one-way: spec at the bottom, cli at the top, converters and writers in between and unaware of each other.

PackageRole
@oaf/specTypes and JSON Schemas. Depends on nothing
@oaf/coreRead, write, and validate packages
@oaf/converter-articulateStoryline .story to OAF
@oaf/output-markdownOAF to Markdown
@oaf/output-marpOAF to Marp slides
@oaf/output-marp-htmlMarp Markdown to interactive HTML
@oaf/cliThe oaf binary

All ship CommonJS and ESM builds with type declarations, except @oaf/cli, which is CommonJS only because it is an executable.


@oaf/spec​

Types and schemas, and the one package everything else depends on.

import type { OAFPackage, OAFSlide, OAFQuiz } from '@oaf/spec';
import { textContentToPlain, createEmptyPackage } from '@oaf/spec';

Two runtime helpers alongside the types:

function textContentToPlain(content: OAFTextContent): string;
function createEmptyPackage(): OAFPackage;

createEmptyPackage() returns a valid skeleton — spec version 1.0, language en, linear navigation, current timestamps, and a generated course id. It is the right starting point for a new converter.

Schemas are exported separately:

import courseSchema from '@oaf/spec/schemas/course.schema.json';

See the OAF format for what the types mean.


@oaf/core​

Reading, writing, and validating packages.

import {
OAFReader, readOAFPackage,
OAFWriter, writeOAFPackage,
OAFValidator, validateOAFPackage,
type ValidationError, type ValidationResult,
} from '@oaf/core';

Each capability comes as a class and a function; the function is the convenience wrapper.

@oaf/core re-exports everything from @oaf/spec, so importing both is unnecessary — take types from @oaf/core if you already depend on it.

Writing works, reading does not yet

writeOAFPackage is wired into the CLI's --format oaf path. Reading a stored package back is not: oaf convert on a .oaf input exits with OAF input not yet implemented.

The reader exists as an export. The CLI does not use it.


@oaf/converter-articulate​

Storyline .story files to OAF packages.

import { convertStoryToOAF, ArticulateConverter } from '@oaf/converter-articulate';
import { StoryParser, SlideXmlParser } from '@oaf/converter-articulate';
interface ConvertOptions {
includeMedia?: boolean;
includeNotes?: boolean;
sourcePath?: string;
}

interface ConvertResult {
package: OAFPackage;
warnings: string[];
mediaFiles?: Map<string, Buffer>;
}

.story is a ZIP container, which is why media comes back as a Map<string, Buffer> rather than as paths — the files are extracted from the archive, not read from disk.

Always check warnings. An empty array means nothing was dropped; entries name what could not be represented.

StoryParser and SlideXmlParser are exported for callers who need the underlying XML rather than the OAF package.


@oaf/output-markdown​

import { generateMarkdown, MarkdownGenerator, type MarkdownOptions } from '@oaf/output-markdown';
interface MarkdownOptions {
mode?: 'full' | 'summary' | 'outline';
includeFrontmatter?: boolean;
includeToc?: boolean;
includeNotes?: boolean;
includeQuizzes?: boolean;
includeMedia?: boolean;
quizFormat?: 'checklist' | 'table' | 'details';
notesFormat?: 'blockquote' | 'callout' | 'section';
headingOffset?: number;
}

interface MarkdownResult {
content: string;
warnings: string[];
}

headingOffset has no CLI flag. It shifts every heading down a level, so a course title becomes ## rather than # — what you want when the output is being embedded in a larger document.


@oaf/output-marp and @oaf/output-marp-html​

import { generateMarp, type MarpOptions } from '@oaf/output-marp';
import { generateMarpHtml, type MarpHtmlOptions } from '@oaf/output-marp-html';

output-marp takes an OAF package and produces Marp Markdown. output-marp-html takes Marp Markdown and produces a self-contained HTML presentation — so a --format marp-html conversion runs both in sequence.

See Convert a course to slides for the options, which mirror the CLI flags.


@oaf/cli​

The oaf binary, built on commander. It composes the packages above and adds no conversion logic of its own.

See the CLI reference.