A more powerful airtable client
npm install @qualifyze/airtableA more powerful JS/TS client for the Airtable API that can be used with Airtable's API
directly or through proxy-endpoints that provide a different Auth mechanism.
In comparison to the official client, @qualifyze/airtable brings these advantages:
- You can use this client to connect multiple API endpoints.
- You can use this client to connect to Airtable API endpoints with an alternative auth-mechanism.
- Allows type-annotations and run-time validations for table-fields.
- Pagination when listing records is much easier through Async Iterators.
- Allows the use of Array Notation when filtering queries through @qualifyze/airtable-formulator.
The API of this client for the most part is identical to the official clients API.
``javascript
import Airtable from "airtable";
import { Base } from "@qualifyze/airtable";
Airtable.configure({ apiKey: "YOUR_SECRET_API_KEY" });
const officialClient = new Airtable();
const base = Base.fromOfficialClient(officialClient, myBaseId);
`
`typescript
type Person = {
name?: string;
age?: number;
};
const persons = base.table
const record = persons.create({
name: "Eve",
age: "not a number", // Type Error
});
`
With the Validator interface you can wrap any validation library to validate your data at runtime.
`typescript
import { Validator } from "./validator";
const validator: Validator
createValidator(reference?: string) {
return {
isValid(data: unknown): data is Person {
// Return true if data is a person.
},
getValidationError(): Error | null {
// Return validation errors that were encountered in the last call to isValid().
// Include reference to easily identify the invalid record.
},
};
},
};
const persons = base.table("persons", validator);
`
`javascript
const query = {
filterByFormula: [">", { field: "age" }, 35],
};
for await (const person of persons.select(query)) {
console.log(person.data);
}
`
As with any Async iterators it has to be warned that an iterator can only be used once at a time:
`javascript
async function runIteration(query) {
for await(const record of query) {
// Do something.
}
}
// BAD: Use same same query in parallel iterators.
const query = table.query({});
Promise.all(runIteration(query), runIteration(query)); // <- BAD
// GOOD: For parallel iterations use separate query obejcts.
const queryA = table.query({});
const queryB = table.query({});
Promise.all(runIteration(queryA), runIteration(queryB)); // <- GOOD
`
`typescript
import { Base, Endpoint, ActionPayload, RestMethod } from "@qualifyze/airtable";
const myClient: Endpoint = {
async runAction(
method: RestMethod,
{ path, payload: { query, body } }: ActionPayload
): Promise
// Implement your own Endpoint interface that
// Throw any API-level errors.
// Return the response payload as is.
},
};
const base = new Base(myClient);
`
#### No Callback APIs
It's 2022. Why would you need callback APIs?
Use Promises or async/await.
#### Record objects are Immutable:
So it won't drive you insane.
`javascript
const record = persons.find("my-id");
const updatedRecord = await record.update({ age: record.data.age + 1 });
console.log({
before: record.data.age,
after: updatedRecord.data.age
});
`
There are no .set() or .get() methods on the Record API.
In addition to usual lint and test scripts, there is an integration test to check
the client against the real airtable base.
- create the file .env based on .env.examplenpm run integration
- pick a table with at least two string fields where it's ok to create new records
- bash
All the created records are deleted in case of the successful execution.
Add the changeset description using the interactive command npx changeset..changeset` folder which defines how the change
This will create a new file in
should affect the package version (major, minor, patch) and contains a small
description for the release notes. The file should be part of the same pull requests
it describes.
Each PR with changeset files merged into the main branch will open/update PR
to release the package with the proper version. Merging that PR will bump the version,
create a GitHub release and publish the new version to the npm registry.
Unfortunately, the test workflow required to merge a PR is not triggered by
the version PR. The workaround is assigning PR to yourself which is added as
an additional trigger for the test workflow.