SDK
TypeScript/JavaScript client SDK for Centia-io. It provides:
- Authentication helpers:
- CodeFlow (OAuth 2.0 Authorization Code + PKCE) for browser apps
- PasswordFlow for trusted/CLI/server environments
- Data access:
- Sql: Execute parameterized SQL
- Rpc: Call JSON-RPC methods
- createApi: A tiny type-safe helper that maps TypeScript interfaces to JSON‑RPC calls
Installation
- npm
- Yarn
- pnpm
npm install @centia-io/sdk
yarn add @centia-io/sdk
pnpm add @centia-io/sdk
Or from CDN:
<script src="https://cdn.jsdelivr.net/npm/@centia-io/sdk@latest/dist/centia-io-sdk.umd.js"></script>
Requirements:
- Browser or Node.js 18+ (for global
fetch). - An accessible Centia.io host URL and client credentials.
ESM import:
import { CodeFlow, PasswordFlow, Sql, Rpc, createApi } from "@centia-io/sdk";
import type { RpcRequest, RpcResponse, PgTypes } from "@centia-io/sdk";
Authentication
The SDK handles token storage and refresh for you.
- Tokens and minimal options are saved to
localStoragein browsers. In non‑browser environments, an in‑memory store is used for the lifetime of the process. - Authorization headers are added automatically for Sql/Rpc requests.
CodeFlow (Browser, OAuth 2.0 Authorization Code + PKCE)
Use this flow in browser applications where you can redirect the user to the Centia-io login page.
Required options:
host: Base URL of your Centia-io instance, e.g.https://api.centia.ioclientId: OAuth client id configured in Centia.ioredirectUri: The URL in your app that handles the redirect back from Centia.io (must be whitelisted)scope(optional): Not in use yet, but will be used to request additional permissions from the user.
Example (vanilla JS/TS + SPA):
import { CodeFlow } from "@centia-io/sdk";
const codeFlow = new CodeFlow({
host: "https://api.centia.io",
clientId: "your-client-id",
redirectUri: window.location.origin + "/auth/callback"
});
// On app startup, call redirectHandle() once to complete a login redirect (if any)
codeFlow.redirectHandle().then((signedIn) => {
if (signedIn) {
console.log("User signed in");
}
});
// Start sign-in when user clicks Login
function onLoginClick() {
codeFlow.signIn(); // Redirects to GC2 auth page
}
// Sign out (clears tokens/options and redirects to signout endpoint)
function onLogoutClick() {
codeFlow.signOut();
}
Notes:
redirectHandle()detects errors from the auth server, validatesstate(CSRF protection), exchanges thecodefor tokens, performsPKCE(Proof Key for Code Exchange), stores tokens and cleans up the URL.signOut()clears local tokens/options and redirects to the sign-out URL. If you only need to clear local state without redirect, callcodeFlow.clear().
PasswordFlow (Trusted environments, CLI/Server)
Use only in trusted environments. The user’s database credentials are exchanged directly for tokens.
Required options:
hostclientIdusernamepassworddatabase
Example (Node.js):
import { PasswordFlow } from "@centia-io/sdk";
const flow = new PasswordFlow({
host: "https://api.centia.io",
clientId: "your-client-id",
username: "your-username",
password: "your-password",
database: "parent-database" // The database to connect to. If superuser, this is the sam as username.
});
await flow.signIn();
// Tokens are now stored; subsequent Sql/Rpc calls will include Authorization header.
// ... your code ...
flow.signOut(); // Clears tokens/options in local storage (no redirect)
Signup (Browser – Create a new user)
Use this helper in browser applications to redirect the user to the Centia‑io sign‑up page. The user will create an account under a specified parent database/tenant and then be redirected back to your application.
Required options:
- host: Base URL of your Centia‑io instance, e.g.
https://api.centia.io - clientId: OAuth client id configured in Centia.io
- parentDb: The parent/tenant database under which the new user should be created
- redirectUri: URL in your app to return to after sign‑up
Example (vanilla JS/TS):
import { SignUp } from "@centia-io/sdk";
const signUp = new SignUp({
host: "https://api.centia.io",
clientId: "your-client-id",
parentDb: "your-parent-database",
redirectUri: "https://myapp.com/login"
});
// Start sign-up when the user clicks "Create account"
function onSignUpClick() {
signUp.signUp(); // Redirects to Centia.io sign-up page
}
Notes:
- After the user completes sign‑up and is redirected back to your app, start your normal sign‑in flow (e.g., CodeFlow. A session is started when the user signed up, so the user will be signed in automatically in the flow.)
- Client property
allow_signupmust be set totruefor the used OAuth client. - Client property
social_signupmust be set totruefor the user can sign up with social login.
SQL
Execute parameterized SQL against GC2.
- Class:
new Sql() - Method:
exec(request: SqlRequest): Promise<SQLResponse> - Endpoint:
POST https://api.centia.io/api/v4/sql
Types (simplified):
SqlRequesthas:q: SQL string, you can use named placeholders like:a(server-side feature)params?: object with values for placeholderstype_hints?: optional explicit type hintstype_formats?: optional per-column format strings
SQLResponsehas:schema: a map of column name ->{ type: string, array: boolean }data: an array of rows (records)
Example:
import { Sql } from "@centia-io/sdk";
const sql = new Sql();
const payload = {
a: 1,
b: "hello",
c: "3.14", // numeric/decimal values are strings
d: ["x", "y"], // arrays are supported
e: { nested: [1,2] } // JSON
};
const res = await sql.exec({
q: "select :a::int as a, :b::varchar as b, :c::numeric as c, :d::varchar[] as d, :e::jsonb as e",
params: payload,
type_hints: { d: "varchar[]" } // Arrays are not inferred by default, and must be specified explicitly
});
console.log(res.schema); // { a: {type: 'int4', array: false}, ... }
console.log(res.data); // [{ a: 1, b: 'hello', c: '3.14', d: ['x','y'], e: {nested:[1,2]} }]
Typing the rows:
import type { PgTypes } from "@centia-io/sdk";
interface Row extends PgTypes.DataRow {
a: number;
b: Pgtypes.Varchar;
c: PgTypes.NumericString;
d: PgTypes.PgArray<Pgtypes.Varchar>;
e: PgTypes.JsonValue;
}
// res: PgTypes.SQLResponse<Row>
const res = await sql.exec({ q: "...", params: payload }) as PgTypes.SQLResponse<Row>;
RPC
Call JSON‑RPC methods exposed by GC2.
- Class:
new Rpc() - Method:
call(request: RpcRequest): Promise<RpcResponse> - Endpoint:
POST {host}/api/v4/call
Types (simplified):
RpcRequesthasjsonrpc: "2.0",method, optionalparams, optionalidRpcResponsehasjsonrpc: "2.0",id, andresultwith{ schema, data }
Example:
import { Rpc } from "@centia-io/sdk";
const rpc = new Rpc();
const payload = { a: 1, b: "hello" };
const res = await rpc.call({
jsonrpc: "2.0",
method: "typeTest",
params: payload,
id: 1
});
console.log(res.result.schema);
console.log(res.result.data); // array of rows
Typing the rows:
import type { PgTypes } from "@centia-io/sdk";
interface Row extends PgTypes.DataRow {
a: number;
b: string;
}
const res = await rpc.call({ jsonrpc: "2.0", method: "typeTest", params: payload }) as PgTypes.RpcResponse<Row>;
createApi
A tiny helper that builds a Proxy around Rpc so you can call api.someMethod(params) directly, with TypeScript autocompletion and type‑checking based on your own interface.
Under the hood, each property access becomes a JSON‑RPC call with the property name as the method. The helper returns result.data (array of rows) from the RPC response.
Example with typing:
import { createApi } from "@centia-io/sdk";
import type { PgTypes } from "@centia-io/sdk";
// Define the shape of your RPC methods and return types
interface MyApi {
typeTest(params: {
a: number;
b: Pgtypes.Varchar;
c: PgTypes.NumericString;
d: PgTypes.PgArray<Pgtypes.Varchar>;
e: PgTypes.JsonValue;
}): Promise<Array<{
a: number;
b: Pgtypes.Varchar;
c: PgTypes.NumericString;
d: PgTypes.PgArray<Pgtypes.Varchar>;
e: PgTypes.JsonValue;
}>>;
}
const api = createApi<MyApi>();
const rows = await api.typeTest({
a: 1,
b: "Hello world",
c: "3.4",
d: ["Hello", "world"],
e: { "x": [1,2,3,4,5,6,7,8,9,10] }
});
console.log(rows); // typed row array
Notes:
createApi<T>()relies on naming conventions: the property name is the JSON‑RPCmethodname.- Each call returns
result.datafrom the RPC response (array of rows).
Error handling
- Network/HTTP errors: thrown as
Errorwith the status/body text when available. - Auth errors: the SDK auto‑refreshes access tokens when possible. If the refresh token is expired or missing, you’ll get an error and should re‑authenticate.
Environment details
- Storage: tokens/options stored in
localStoragewhen available; otherwise a global in‑memory store is used (globalThis.__gc2_memory_storage). - Fetch: Node.js 18+ recommended (includes native
fetch). For older Node versions, add a Fetch polyfill.
License
The SDK is licensed under The MIT License