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,
position0 = worst. Setvalenceonly when position misleads. - Local day first. Never derive
datefrom UTC. See dates and time. - Count what is lost with
countDropped. Photos go inmedia.photos. detectis cheap and never throws. Read names and the first bytes withfile.head(n), never whole files.- Errors throw
AdapterErrorwithmessage,whyand afixthe 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.