fellow-aiden
v1.0.0
Published
JavaScript/TypeScript client for the Fellow Aiden coffee brewer cloud API
Maintainers
Readme
fellow-aiden (JavaScript / TypeScript)
A TypeScript client for the Fellow Aiden coffee
brewer's cloud API. A faithful port of the Python library
9b/fellow-aiden.
Unofficial — not affiliated with or endorsed by Fellow.
Install
npm install fellow-aidenRequires Node 18+ (uses the built-in global fetch). Ships ESM + CommonJS
builds and TypeScript declarations.
Quick start
import { FellowAiden } from 'fellow-aiden';
// Authentication is async, so use the static factory:
const aiden = await FellowAiden.create({
email: process.env.FELLOW_EMAIL!,
password: process.env.FELLOW_PASSWORD!,
});
console.log(aiden.getDisplayName(), aiden.getBrewerId());
const profiles = await aiden.getProfiles();API
Construction & auth
FellowAiden.create(options)— construct, authenticate, and load the device.new FellowAiden(options)thenawait client.authenticate()— manual flow.authenticate()— (re)log in; also called automatically once on a401.
options: { email, password, baseUrl?, userAgent?, maxRetries?, fetch? }.
Device
getDisplayName(): string | nullgetBrewerId(): string | nullgetDeviceConfig({ refresh? }): Promise<DeviceConfig>adjustSetting(setting, value): Promise<unknown>
Profiles
getProfiles({ refresh? }): Promise<Profile[]>getProfileByTitle(title, { fuzzy? }): Promise<Profile | null>— exact (case-insensitive) by default;fuzzyuses a difflib-equivalent ratio > 0.65.createProfile(data): Promise<Profile>— validated againstCoffeeProfileSchema.updateProfile(profileId, data): Promise<Profile>deleteProfileById(profileId): Promise<void>generateShareLink(profileId): Promise<string>parseBrewLinkUrl(link): Promise<Record<string, unknown>>createProfileFromLink(link): Promise<Profile>
Schedules
getSchedules({ refresh? }): Promise<Schedule[]>createSchedule(data): Promise<Schedule>— validated againstCoffeeScheduleSchema.toggleSchedule(scheduleId, enabled): Promise<unknown>deleteScheduleById(scheduleId): Promise<void>
Validation
Profile and schedule inputs are validated with Zod schemas
that mirror the Python Pydantic models. Allowed ratio/temperature values are
exported (RATIO_VALUES, TEMPERATURE_VALUES, BLOOM_RATIO_VALUES). Invalid
input throws a ValidationError; API failures throw ApiError; auth failures
throw AuthError. All extend FellowAidenError.
Profile fields
{
profileType: number; // int
title: string; // ≤ 50 chars, restricted charset
ratio: number; // 14–20 step 0.5
bloomEnabled: boolean;
bloomRatio: number; // 1, 1.5, 2, 2.5, 3
bloomDuration: number; // 1–120
bloomTemperature: number; // 50–98.5 step 0.5 (°C)
ssPulsesEnabled: boolean;
ssPulsesNumber: number; // 1–10
ssPulsesInterval: number; // 5–60
ssPulseTemperatures: number[]; // each 50–98.5 step 0.5
batchPulsesEnabled: boolean;
batchPulsesNumber: number; // 1–10
batchPulsesInterval: number; // 5–60
batchPulseTemperatures: number[];
}Schedule fields
{
days: boolean[]; // exactly 7, Sunday → Saturday
secondFromStartOfTheDay: number;// 0–86399
enabled: boolean;
amountOfWater: number; // 150–1500 (ml)
profileId: string; // "p<n>" or "plocal<n>"
}Development
npm install
npm test # vitest (fully mocked, no network)
npm run typecheck # tsc --noEmit
npm run build # tsup → dist/ (ESM + CJS + .d.ts)See examples/basic-usage.ts for a runnable example.
Releasing
Releases are published to npm by CI via
trusted publishing (OIDC, no
token) when a vX.Y.Z tag is pushed. To cut one:
npm run release # patch: 0.1.1 → 0.1.2
npm run release -- minor # 0.1.1 → 0.2.0
npm run release -- major # 0.1.1 → 1.0.0This bumps the version, commits, tags vX.Y.Z, and pushes — which triggers
release.yml to build, test, and publish
with provenance.
License
MIT. Inspired by the GPL-3.0 Python project 9b/fellow-aiden; this is an
independent reimplementation written against the observed HTTP API.
