@scarif/scarif-js
v2.0.0
Published
A TypeScript SDK for Scarif API services
Readme
Scarif API SDK
Type-safe SDK for Scarif API services with chainable querying. Create a client with your API key (e.g. from your app's env), then use client.from() and client.health() — same pattern as Supabase.
Installation
npm install @scarif/scarif-jsQuick Start
Create a client with your API key (from your app's environment), then query via the client:
import { createClient } from '@scarif/scarif-js';
const client = createClient({
apiKey: process.env.API_KEY
});
const { data, error } = await client.from('countries').select('*');Optional options: baseUrl, timeout (default 30000ms).
Features
- Type-Safe - Full TypeScript support with automatic type inference
- Chainable API - Supabase-like query builder
- Lightweight - Minimal dependencies
- Relations - Eager loading via select syntax, including dual-FK alias embeds
Querying & Filtering
Basic Queries
const client = createClient({ apiKey: process.env.API_KEY });
const { data: all } = await client.from('countries').select('*');
const { data: names } = await client.from('countries').select('name, iso2');
const { data: elements } = await client.from('elements').select('Symbol, AtomicNumber, Type');Relations (Eager Loading)
const { data: withCities } = await client.from('countries').select('*, cities(*)');
const { data: custom } = await client.from('countries').select('name, iso2, cities(id, name)');Tables with multiple foreign keys to the same target require an alias and FK hint. Bare countries(*) on military_bases is invalid.
const { data: bases } = await client
.from('military_bases')
.select(`
name,
host_country:countries!military_bases_host_country_id_fkey(id, name, emoji),
operator_country:countries!military_bases_operator_country_id_fkey(id, name, emoji)
`);
const { data: plants } = await client
.from('power_plants')
.select('name, country:countries!power_plants_country_id_fkey(id, name, iso2)');Filtering
const { data: usa } = await client.from('countries').select('*').eq('iso2', 'US');
const { data: notUSA } = await client.from('countries').select('*').neq('iso2', 'US');
const { data: highIds } = await client.from('countries').select('*').gt('id', 100);
const { data: united } = await client.from('countries').select('*').ilike('name', '%united%');
const { data: specific } = await client.from('countries').select('*').in('iso2', ['US', 'CA', 'MX']);
const { data: withNull } = await client.from('countries').select('*').isNull('deleted_at');
const { data: withoutNull } = await client.from('countries').select('*').isNotNull('email');Sorting
const { data: sorted } = await client.from('countries').select('*').order('name');
const { data: desc } = await client.from('countries').select('*').order('name', 'desc');
const { data: multi } = await client.from('countries').select('*').order('name', 'asc').order('id', 'desc');Pagination
const { data: limited } = await client.from('countries').select('*').limit(10);
const { data: page2 } = await client.from('countries').select('*').limit(10).offset(10);Complex Queries
const { data, error } = await client
.from('countries')
.select('name, iso2, cities(id, name)')
.ilike('name', '%united%')
.order('name', 'asc')
.limit(10);Single Result
const { data: usa, error } = await client.from('countries').select('*').eq('iso2', 'US').single();TypeScript Support
import { createClient } from '@scarif/scarif-js';
const client = createClient({ apiKey: process.env.API_KEY! });
const { data, error } = await client.from('countries').select('*');
data?.forEach(country => {
console.log(country.name, country.iso2);
});
// Custom type for dynamic table
interface CustomRow { id: number; customField: string; }
const { data } = await client.from<CustomRow>('custom_table').select('*');Error Handling
const { data, error } = await client.from('countries').select('*').eq('iso2', 'US');
if (error) {
console.error(error.message, error.code);
} else {
console.log(data);
}API Reference
createClient(options)
Creates an API client. Required before any data calls.
options.apiKey(required): Your API key (e.g.process.env.API_KEY)options.baseUrl(optional): Base URL (default:https://stoorplek.onrender.com)options.timeout(optional): Request timeout in ms (default: 30000)
Returns: ApiClient instance.
client.from(table)
Starts a chainable query. Methods: .select(), .eq(), .neq(), .gt(), .gte(), .lt(), .lte(), .like(), .ilike(), .in(), .notIn(), .isNull(), .isNotNull(), .order(), .limit(), .offset(), .range(), .single().
Allowed tables: countries, cities, states, elements, military_bases, power_plants.
client.health()
Returns Promise<ApiResponse> for the API health endpoint.
Response Format
interface ApiResponse<T> {
data: T;
error: { message: string; code?: string; details?: any; } | null;
status: number;
}Environment
Create the client once (e.g. at app bootstrap) using your env, then pass the client around:
// e.g. in app entry or a shared module
import { createClient } from '@scarif/scarif-js';
export const client = createClient({
apiKey: process.env.API_KEY
});Use API_KEY_ENV_VAR from the package if you want the default env key name: createClient({ apiKey: process.env[API_KEY_ENV_VAR] }).
License
MIT
