@centia-io/sdk 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +288 -0
- package/dist/centia-io-sdk.cjs +588 -0
- package/dist/centia-io-sdk.d.cts +243 -0
- package/dist/centia-io-sdk.d.cts.map +1 -0
- package/dist/{index.d.ts → centia-io-sdk.d.ts} +1 -1
- package/dist/centia-io-sdk.d.ts.map +1 -0
- package/dist/{index.js → centia-io-sdk.js} +1 -1
- package/dist/centia-io-sdk.js.map +1 -0
- package/dist/centia-io-sdk.umd.js +594 -0
- package/package.json +12 -8
- package/build/gc2-js-client.js +0 -12
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 MapCentia ApS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# @centia-io/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript/JavaScript client SDK for Centia GC2. It provides:
|
|
4
|
+
|
|
5
|
+
- Authentication helpers:
|
|
6
|
+
- CodeFlow (OAuth 2.0 Authorization Code + PKCE) for browser apps
|
|
7
|
+
- PasswordFlow for trusted/CLI/server environments
|
|
8
|
+
- Data access:
|
|
9
|
+
- Sql: Execute parameterized SQL
|
|
10
|
+
- Rpc: Call JSON-RPC methods
|
|
11
|
+
- createApi: A tiny type-safe helper that maps TypeScript interfaces to JSON‑RPC calls
|
|
12
|
+
|
|
13
|
+
This README focuses on CodeFlow, PasswordFlow, Sql, Rpc and Api.ts (createApi).
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
- npm: `npm install @centia-io/sdk`
|
|
18
|
+
- pnpm: `pnpm add @centia-io/sdk`
|
|
19
|
+
- yarn: `yarn add @centia-io/sdk`
|
|
20
|
+
|
|
21
|
+
Requirements:
|
|
22
|
+
- Browser or Node.js 18+ (for global `fetch`).
|
|
23
|
+
- An accessible GC2 host URL and client credentials.
|
|
24
|
+
|
|
25
|
+
ESM import:
|
|
26
|
+
```ts
|
|
27
|
+
import { CodeFlow, PasswordFlow, Sql, Rpc, createApi } from "@centia-io/sdk";
|
|
28
|
+
import type { RpcRequest, RpcResponse, PgTypes } from "@centia-io/sdk";
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Authentication
|
|
34
|
+
|
|
35
|
+
The SDK handles token storage and refresh for you.
|
|
36
|
+
- Tokens and minimal options are saved to `localStorage` in browsers. In non‑browser environments, an in‑memory store is used for the lifetime of the process.
|
|
37
|
+
- Authorization headers are added automatically for Sql/Rpc requests.
|
|
38
|
+
|
|
39
|
+
### CodeFlow (Browser, OAuth 2.0 Authorization Code + PKCE)
|
|
40
|
+
|
|
41
|
+
Use this flow in browser applications where you can redirect the user to the GC2 login page.
|
|
42
|
+
|
|
43
|
+
Required options:
|
|
44
|
+
- `host`: Base URL of your GC2 instance, e.g. `https://your.gc2.host`
|
|
45
|
+
- `clientId`: OAuth client id configured in GC2
|
|
46
|
+
- `redirectUri`: The URL in your app that handles the redirect back from GC2 (must be whitelisted)
|
|
47
|
+
- `scope` (optional): space‑separated scopes, e.g. `"openid profile"`
|
|
48
|
+
|
|
49
|
+
Example (vanilla JS/TS + SPA):
|
|
50
|
+
```ts
|
|
51
|
+
import { CodeFlow } from "@centia-io/sdk";
|
|
52
|
+
|
|
53
|
+
const codeFlow = new CodeFlow({
|
|
54
|
+
host: "https://your.gc2.host",
|
|
55
|
+
clientId: "your-client-id",
|
|
56
|
+
redirectUri: window.location.origin + "/auth/callback",
|
|
57
|
+
scope: "openid"
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// On app startup, call redirectHandle() once to complete a login redirect (if any)
|
|
61
|
+
codeFlow.redirectHandle().then((signedIn) => {
|
|
62
|
+
if (signedIn) {
|
|
63
|
+
console.log("User signed in");
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Start sign-in when user clicks Login
|
|
68
|
+
function onLoginClick() {
|
|
69
|
+
codeFlow.signIn(); // Redirects to GC2 auth page
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Sign out (clears tokens/options and redirects to signout endpoint)
|
|
73
|
+
function onLogoutClick() {
|
|
74
|
+
codeFlow.signOut();
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Notes:
|
|
79
|
+
- `redirectHandle()` detects errors from the auth server, validates `state` (CSRF protection), exchanges the `code` for tokens, stores tokens and cleans up the URL.
|
|
80
|
+
- `signOut()` clears local tokens/options and redirects to the sign-out URL. If you only need to clear local state without redirect, call `codeFlow.clear()`.
|
|
81
|
+
|
|
82
|
+
### PasswordFlow (Trusted environments, CLI/Server)
|
|
83
|
+
|
|
84
|
+
Use only in trusted environments. The user’s database credentials are exchanged directly for tokens.
|
|
85
|
+
|
|
86
|
+
Required options:
|
|
87
|
+
- `host`
|
|
88
|
+
- `clientId`
|
|
89
|
+
- `username`
|
|
90
|
+
- `password`
|
|
91
|
+
- `database`
|
|
92
|
+
|
|
93
|
+
Example (Node.js):
|
|
94
|
+
```ts
|
|
95
|
+
import { PasswordFlow } from "@centia-io/sdk";
|
|
96
|
+
|
|
97
|
+
const flow = new PasswordFlow({
|
|
98
|
+
host: "http://localhost:8080",
|
|
99
|
+
clientId: "gc2-cli",
|
|
100
|
+
username: "mydb",
|
|
101
|
+
password: "secret",
|
|
102
|
+
database: "mydb"
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await flow.signIn();
|
|
106
|
+
// Tokens are now stored; subsequent Sql/Rpc calls will include Authorization header.
|
|
107
|
+
|
|
108
|
+
// ... your code ...
|
|
109
|
+
|
|
110
|
+
flow.signOut(); // Clears tokens/options in local storage (no redirect)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## SQL
|
|
116
|
+
|
|
117
|
+
Execute parameterized SQL against GC2.
|
|
118
|
+
|
|
119
|
+
- Class: `new Sql()`
|
|
120
|
+
- Method: `exec(request: SqlRequest): Promise<SQLResponse>`
|
|
121
|
+
- Endpoint: `POST {host}/api/v4/sql`
|
|
122
|
+
|
|
123
|
+
Types (simplified):
|
|
124
|
+
- `SqlRequest` has:
|
|
125
|
+
- `q`: SQL string, you can use named placeholders like `:a` (server-side feature)
|
|
126
|
+
- `params?`: object with values for placeholders
|
|
127
|
+
- `type_hints?`: optional explicit type hints
|
|
128
|
+
- `type_formats?`: optional per-column format strings
|
|
129
|
+
- `SQLResponse` has:
|
|
130
|
+
- `schema`: a map of column name -> `{ type: string, array: boolean }`
|
|
131
|
+
- `data`: an array of rows (records)
|
|
132
|
+
|
|
133
|
+
Example:
|
|
134
|
+
```ts
|
|
135
|
+
import { Sql } from "@centia-io/sdk";
|
|
136
|
+
|
|
137
|
+
const sql = new Sql();
|
|
138
|
+
|
|
139
|
+
const payload = {
|
|
140
|
+
a: 1,
|
|
141
|
+
b: "hello",
|
|
142
|
+
c: "3.14", // numeric/decimal values are strings
|
|
143
|
+
d: ["x", "y"], // arrays are supported
|
|
144
|
+
e: { nested: [1,2] } // JSON
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const res = await sql.exec({
|
|
148
|
+
q: "select :a::int as a, :b::varchar as b, :c::numeric as c, :d::varchar[] as d, :e::jsonb as e",
|
|
149
|
+
params: payload
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
console.log(res.schema); // { a: {type: 'int4', array: false}, ... }
|
|
153
|
+
console.log(res.data); // [{ a: 1, b: 'hello', c: '3.14', d: ['x','y'], e: {nested:[1,2]} }]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Typing the rows:
|
|
157
|
+
```ts
|
|
158
|
+
import type { PgTypes } from "@centia-io/sdk";
|
|
159
|
+
|
|
160
|
+
interface Row extends PgTypes.DataRow {
|
|
161
|
+
a: number;
|
|
162
|
+
b: string;
|
|
163
|
+
c: PgTypes.NumericString;
|
|
164
|
+
d: PgTypes.PgArray<string>;
|
|
165
|
+
e: PgTypes.JsonValue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// res: PgTypes.SQLResponse<Row>
|
|
169
|
+
const res = await sql.exec({ q: "...", params: payload }) as PgTypes.SQLResponse<Row>;
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## RPC
|
|
175
|
+
|
|
176
|
+
Call JSON‑RPC methods exposed by GC2.
|
|
177
|
+
|
|
178
|
+
- Class: `new Rpc()`
|
|
179
|
+
- Method: `call(request: RpcRequest): Promise<RpcResponse>`
|
|
180
|
+
- Endpoint: `POST {host}/api/v4/call`
|
|
181
|
+
|
|
182
|
+
Types (simplified):
|
|
183
|
+
- `RpcRequest` has `jsonrpc: "2.0"`, `method`, optional `params`, optional `id`
|
|
184
|
+
- `RpcResponse` has `jsonrpc: "2.0"`, `id`, and `result` with `{ schema, data }`
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
```ts
|
|
188
|
+
import { Rpc } from "@centia-io/sdk";
|
|
189
|
+
|
|
190
|
+
const rpc = new Rpc();
|
|
191
|
+
|
|
192
|
+
const payload = { a: 1, b: "hello" };
|
|
193
|
+
|
|
194
|
+
const res = await rpc.call({
|
|
195
|
+
jsonrpc: "2.0",
|
|
196
|
+
method: "typeTest",
|
|
197
|
+
params: payload,
|
|
198
|
+
id: 1
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
console.log(res.result.schema);
|
|
202
|
+
console.log(res.result.data); // array of rows
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Typing the rows:
|
|
206
|
+
```ts
|
|
207
|
+
import type { PgTypes } from "@centia-io/sdk";
|
|
208
|
+
|
|
209
|
+
interface Row extends PgTypes.DataRow {
|
|
210
|
+
a: number;
|
|
211
|
+
b: string;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const res = await rpc.call({ jsonrpc: "2.0", method: "typeTest", params: payload }) as PgTypes.RpcResponse<Row>;
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## createApi (Api.ts)
|
|
220
|
+
|
|
221
|
+
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.
|
|
222
|
+
|
|
223
|
+
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.
|
|
224
|
+
|
|
225
|
+
Example with typing:
|
|
226
|
+
```ts
|
|
227
|
+
import { createApi } from "@centia-io/sdk";
|
|
228
|
+
import type { PgTypes } from "@centia-io/sdk";
|
|
229
|
+
|
|
230
|
+
// Define the shape of your RPC methods and return types
|
|
231
|
+
interface MyApi {
|
|
232
|
+
typeTest(params: {
|
|
233
|
+
a: number;
|
|
234
|
+
b: string;
|
|
235
|
+
c: PgTypes.NumericString;
|
|
236
|
+
d: PgTypes.PgArray<string>;
|
|
237
|
+
e: PgTypes.JsonValue;
|
|
238
|
+
}): Promise<Array<{
|
|
239
|
+
a: number;
|
|
240
|
+
b: string;
|
|
241
|
+
c: PgTypes.NumericString;
|
|
242
|
+
d: PgTypes.PgArray<string>;
|
|
243
|
+
e: PgTypes.JsonValue;
|
|
244
|
+
}>>;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const api = createApi<MyApi>();
|
|
248
|
+
|
|
249
|
+
const rows = await api.typeTest({
|
|
250
|
+
a: 1,
|
|
251
|
+
b: "hej",
|
|
252
|
+
c: "3.4",
|
|
253
|
+
d: ["ds", "sdsd"],
|
|
254
|
+
e: { zdsd: [2,3,4,5,6,7,8,9,10] }
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
console.log(rows); // typed row array
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Notes:
|
|
261
|
+
- `createApi<T>()` relies on naming conventions: the property name is the JSON‑RPC `method` name.
|
|
262
|
+
- Each call returns `result.data` from the RPC response (array of rows).
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Error handling
|
|
267
|
+
|
|
268
|
+
- Network/HTTP errors: thrown as `Error` with the status/body text when available.
|
|
269
|
+
- 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.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Environment details
|
|
274
|
+
|
|
275
|
+
- Storage: tokens/options stored in `localStorage` when available; otherwise a global in‑memory store is used (`globalThis.__gc2_memory_storage`).
|
|
276
|
+
- Fetch: Node.js 18+ recommended (includes native `fetch`). For older Node versions, add a Fetch polyfill.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Examples
|
|
281
|
+
|
|
282
|
+
See the `examples/` folder for runnable snippets showing PasswordFlow + Sql/Rpc and browser CodeFlow usage.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
AGPL-3.0
|