npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@innobrain/onoffice-adapter-js

v0.2.0

Published

OnOffice API adapter for JavaScript projects

Readme

@innobrain/onoffice-adapter-js

A JavaScript/TypeScript client for the onOffice API, modeled after the Laravel adapter.

Installation

npm install @innobrain/onoffice-adapter-js

Usage

import {
  OnOfficeAction,
  OnOfficeClient,
  OnOfficeResourceType,
  createRepositories,
} from "@innobrain/onoffice-adapter-js";

const client = new OnOfficeClient({
  token: process.env.ON_OFFICE_TOKEN ?? "",
  secret: process.env.ON_OFFICE_SECRET ?? "",
  apiClaim: process.env.ON_OFFICE_API_CLAIM,
});

const { raw, estate, address, activity, fields, searchCriteria, file, marketplace, settings } =
  createRepositories(client);

const estates = await estate
  .query()
  .select(["Id", "kaufpreis"])
  .where("status", 1)
  .orderByField("kaufpreis")
  .get();

// Count records without fetching
const totalEstates = await estate.query().where("status", 1).count();

// Iterate over all records
await estate.query().select(["Id"]).each((record) => {
  console.log(record.id);
});

// Delete a record
await estate.query().delete(12345);

// Raw repository for custom resource types
const custom = await raw.query(OnOfficeResourceType.Estate).select(["Id"]).find(12345);

const uploaded = await file.upload().uploadInBlocks(20480).saveAndLink("base64EncodedFile", {
  module: "estate",
  relatedRecordId: 12345,
  file: "offer.pdf",
  Art: "Dokument",
});

const firstEstate = await estate.query().select(["Id"]).find(12345);

const rawResponse = await client.request(OnOfficeAction.Read, OnOfficeResourceType.Estate, {
  parameters: {
    data: ["Id"],
  },
});

const addresses = await address.query().select(["Name", "Vorname"]).get();

const activities = await activity
  .query()
  .estateId(123)
  .addressIds([456, 789])
  .select(["Nr", "Aktionsart", "Aktionstyp", "Datum", "Bemerkung"])
  .get();

const fieldDefinitions = await fields.query().withModules(["estate", "address"]).get();

const criteria = await searchCriteria.query().mode("searchcriteria").ids([29]).get();
const criteriaFields = await searchCriteria.fields().get();
const criteriaMatches = await searchCriteria
  .search()
  .searchData({ range_plz: "52074" })
  .outputAll()
  .get();

const estateFiles = await file.estateFiles(12345, { includeImageUrl: "small" });
const addressFiles = await file.addressFiles(6789);

const users = await settings.users().select(["Nr", "Vorname"]).get();
const regions = await settings.regions().get();
const imprint = await settings.imprint().select(["Id"]).first();
const actions = await settings.actions().get();

const invoiceRecipient = await marketplace.invoiceRecipient({
  transactionId: 1100135697,
  userId: 42,
});

Repository classes are exported (RawRepository, EstateRepository, AddressRepository, ActivityRepository, FieldRepository, SearchCriteriaRepository, FileRepository, MarketplaceRepository, SettingRepository) if you want to wire your own container.

Notes

  • Provide a fetcher in the client config if your runtime does not expose fetch (Node < 18).
  • Retries happen only on network errors by default; set retry.onlyOnNetworkError to false for all errors. Non-2xx HTTP responses throw OnOfficeError with status details.
  • Query builders are generic so you can type records (e.g. estate.query<MyEstate>()).
  • Query builders support Eloquent-style methods: where(), whereIn(), first(), get(), find(), create(), modify(), delete(), count(), each().
  • The where() method accepts typed operators: =, !=, <, >, <=, >=, in, not in, between, like, not like.
  • File access uses file.estateFiles/file.addressFiles and requires a record ID.
  • File uploads for the estate module require an Art value (e.g. Dokument, Foto).
  • Pagination defaults to MAX_PAGE_SIZE (500), which is also exported as a constant.

Tooling

npm run build
npm run test
npm run lint
npm run format

Local testing

Create a .env in onoffice-adapter-js with:

ON_OFFICE_TOKEN=...
ON_OFFICE_SECRET=...
ON_OFFICE_API_CLAIM=... # optional

Then run:

npm install
npm run dev