Skip to content
OWLF
Esc
↑↓navigate↵open⌘Jpreview
On this page

Build an adapter

Turn one app's export into an OWLF document, as an npm package.

An adapter reads one app’s export files and returns an OWLF document. It implements the Adapter contract from @owlf/core.

import type { Adapter } from "@owlf/core";

export const myApp: Adapter = {
  id: "my-app",
  name: "My App",
  platforms: ["ios", "android"],
  exportSteps: ["Open Settings > Export", "Save the ZIP and add it here"],
  accept: [".zip", "application/zip"],
  status: "verified",
  detect: async (files) => 0, // 0 = not this app, 1 = certain
  parse: async (files) => {
    /* return createDocument(myApp, { mood, sleep, entries, warnings }) */
  },
};

Rules

  • Keep source values. Raw mood, raw emotion names, tag groups. Consumers decide the mapping.
  • No target app. An adapter never names or imports another app.
  • Mood scale worst to best, position 0 = worst. Set valence only when position misleads.
  • Local day first. Never derive date from UTC. See dates and time.
  • Count what is lost with countDropped. Photos go in media.photos.
  • detect is cheap and never throws. Read names and the first bytes with file.head(n), never whole files.
  • Errors throw AdapterError with message, why and a fix the person can act on.

Helpers for ZIP (iOS ZIP64 safe, ranged reads), CSV, dates, scales and PDF text live in @owlf/adapter-utils.

Package layout

packages/adapters/my-app/
  package.json        # @owlf/adapter-my-app
  README.md           # export steps, format notes
  src/index.ts        # exports `myApp`
  src/index.test.ts   # conformance + app-specific behavior
  fixtures/           # synthetic export, same bytes-level format as the real one

Real exports never enter the repository. Fixtures use made-up content in the exact format of the real file. The full guide lives in the repository: adding an adapter.

Was this page helpful?