@truenorth-it/dataverse-client 1.0.0

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/README.md ADDED
@@ -0,0 +1,405 @@
1
+ <!-- This file is published to npmjs.com as the package README. Edit here, not the root README.md. -->
2
+
3
+ # @truenorth-it/dataverse-client
4
+
5
+ A type-safe JavaScript client for the Dataverse Contact API. Works with **any** deployment — generate TypeScript types specific to your Dataverse org, or use it untyped.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @truenorth-it/dataverse-client
11
+ ```
12
+
13
+ ## Quick start (no types)
14
+
15
+ The SDK works out of the box without any type generation. Response data is `Record<string, unknown>`:
16
+
17
+ ```typescript
18
+ import { createClient } from "@truenorth-it/dataverse-client";
19
+
20
+ const client = createClient({
21
+ baseUrl: "https://your-api.vercel.app",
22
+ getToken: () => getAccessTokenSilently(), // your Auth0 token provider
23
+ });
24
+
25
+ const result = await client.me.list("incident", {
26
+ select: ["title", "ticketnumber", "statuscode", "createdon"],
27
+ top: 20,
28
+ orderBy: "modifiedon:desc",
29
+ });
30
+
31
+ for (const record of result.data) {
32
+ console.log(record.ticketnumber, record.title);
33
+ }
34
+ ```
35
+
36
+ ## Generate types for your API
37
+
38
+ For full TypeScript autocomplete and type safety, generate interfaces from your own API deployment:
39
+
40
+ ```bash
41
+ npx dataverse-client generate --url https://your-api.vercel.app
42
+ ```
43
+
44
+ This fetches the schema and choice values from your API (public endpoints, no auth required) and creates `dataverse-tables.generated.ts` with:
45
+ - Typed interfaces for every table
46
+ - Const enum objects for every choice (picklist) field
47
+
48
+ ### CLI options
49
+
50
+ | Flag | Default | Description |
51
+ |------|---------|-------------|
52
+ | `--url`, `-u` | (required) | Base URL of your API deployment |
53
+ | `--output`, `-o` | `./dataverse-tables.generated.ts` | Output file path |
54
+ | `--api-base` | `/api/v2` | API base path |
55
+ | `--no-choices` | `false` | Skip fetching choice values (no enums generated) |
56
+
57
+ ### Using generated types
58
+
59
+ ```typescript
60
+ import { createClient } from "@truenorth-it/dataverse-client";
61
+ import type { Incident, Contact } from "./dataverse-tables.generated";
62
+
63
+ const client = createClient({
64
+ baseUrl: "https://your-api.vercel.app",
65
+ getToken: () => getAccessTokenSilently(),
66
+ });
67
+
68
+ // Fully typed — result.data is Incident[]
69
+ const result = await client.me.list<Incident>("incident", {
70
+ select: ["title", "ticketnumber", "statuscode", "createdon"],
71
+ top: 20,
72
+ });
73
+
74
+ for (const c of result.data) {
75
+ console.log(c.ticketnumber, c.title, c.statuscode_label);
76
+ // ^ string ^ string ^ "In Progress" etc.
77
+ }
78
+ ```
79
+
80
+ ### Using choice enums
81
+
82
+ The generated file also includes const objects for choice (picklist) fields, so you can compare values without magic numbers:
83
+
84
+ ```typescript
85
+ import { createClient } from "@truenorth-it/dataverse-client";
86
+ import type { Incident } from "./dataverse-tables.generated";
87
+ import { IncidentStatuscode, IncidentPrioritycode } from "./dataverse-tables.generated";
88
+
89
+ const cases = await client.me.list<Incident>("incident", {
90
+ filter: `statuscode eq ${IncidentStatuscode.InProgress}`,
91
+ });
92
+
93
+ for (const c of cases.data) {
94
+ if (c.statuscode === IncidentStatuscode.OnHold) {
95
+ console.log("Case is on hold:", c.title);
96
+ }
97
+ if (c.prioritycode === IncidentPrioritycode.High) {
98
+ console.log("High priority:", c.title);
99
+ }
100
+ }
101
+ ```
102
+
103
+ Each choice const is also a type — use it for function signatures:
104
+
105
+ ```typescript
106
+ function handleStatus(status: IncidentStatuscode) {
107
+ // status is narrowed to 1 | 2 | 3 | 5 etc.
108
+ }
109
+ ```
110
+
111
+ To skip choice generation (faster, interfaces only): `npx dataverse-client generate --url ... --no-choices`
112
+
113
+ ### CI / build integration
114
+
115
+ Add to your `package.json` to regenerate types when your schema changes:
116
+
117
+ ```json
118
+ {
119
+ "scripts": {
120
+ "generate:types": "dataverse-client generate --url $API_URL --output src/dataverse-types.ts",
121
+ "prebuild": "npm run generate:types"
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Programmatic usage
127
+
128
+ The codegen function is also exported for use in custom build scripts:
129
+
130
+ ```typescript
131
+ import { generateTableTypes } from "@truenorth-it/dataverse-client";
132
+
133
+ const response = await fetch("https://your-api.vercel.app/api/v2/schema");
134
+ const schema = await response.json();
135
+ const tsSource = generateTableTypes(schema);
136
+ // Write tsSource to a file, pipe it, etc.
137
+ ```
138
+
139
+ ## Usage with React + Auth0
140
+
141
+ ```tsx
142
+ import { useMemo } from "react";
143
+ import { useAuth0 } from "@auth0/auth0-react";
144
+ import { createClient } from "@truenorth-it/dataverse-client";
145
+
146
+ function useApiClient() {
147
+ const { getAccessTokenSilently } = useAuth0();
148
+
149
+ return useMemo(
150
+ () =>
151
+ createClient({
152
+ baseUrl: import.meta.env.VITE_API_BASE_URL,
153
+ getToken: () => getAccessTokenSilently(),
154
+ }),
155
+ [getAccessTokenSilently],
156
+ );
157
+ }
158
+ ```
159
+
160
+ ## Client configuration
161
+
162
+ ```typescript
163
+ createClient({
164
+ baseUrl: string; // API deployment URL
165
+ getToken: () => Promise<string>; // Returns a Bearer token
166
+ apiBase?: string; // Defaults to "/api/v2"
167
+ });
168
+ ```
169
+
170
+ ## Access scopes
171
+
172
+ The client exposes three scopes, each backed by server-side authorization:
173
+
174
+ | Scope | Description | Operations |
175
+ |-------|-------------|------------|
176
+ | `client.me` | Your own records (contact-scoped) | list, get, update, lookup, create, whoami |
177
+ | `client.team` | Records belonging to your team/account | list, get, update, lookup |
178
+ | `client.all` | All records (requires elevated permissions) | list, get, update, lookup |
179
+
180
+ ## Operations
181
+
182
+ ### List records
183
+
184
+ ```typescript
185
+ import type { Incident } from "./dataverse-tables.generated";
186
+
187
+ const result = await client.me.list<Incident>("incident", {
188
+ select: ["title", "ticketnumber", "statuscode", "prioritycode", "createdon"],
189
+ top: 50,
190
+ orderBy: "createdon:desc",
191
+ filter: "statuscode eq 1",
192
+ });
193
+
194
+ // result.data — Incident[] with full autocomplete
195
+ // result.page — { top, skip, next }
196
+
197
+ for (const c of result.data) {
198
+ console.log(c.ticketnumber, c.title);
199
+ console.log(c.statuscode, c.statuscode_label); // 1, "In Progress"
200
+ console.log(c.prioritycode, c.prioritycode_label); // 2, "Normal"
201
+ }
202
+ ```
203
+
204
+ ### Get a single record
205
+
206
+ ```typescript
207
+ const result = await client.me.get<Incident>("incident", caseId, {
208
+ select: ["title", "description", "statuscode", "customerid"],
209
+ });
210
+
211
+ const c = result.data;
212
+ console.log(c.title); // "Network outage in building 3"
213
+ console.log(c._customerid_value); // GUID of the linked customer
214
+ console.log(c.statuscode_label); // "In Progress"
215
+ ```
216
+
217
+ ### Create a record (me scope only)
218
+
219
+ ```typescript
220
+ import type { Casenotes } from "./dataverse-tables.generated";
221
+
222
+ const result = await client.me.create<Casenotes>("casenotes", {
223
+ subject: "Follow-up call",
224
+ notetext: "Spoke with customer — issue resolved.",
225
+ objectid_incident: incidentId, // link to parent case
226
+ });
227
+
228
+ console.log(result.data.annotationid); // new note GUID
229
+ ```
230
+
231
+ ### Update a record
232
+
233
+ Available on all scopes (`me`, `team`, `all`):
234
+
235
+ ```typescript
236
+ const result = await client.me.update<Incident>("incident", caseId, {
237
+ description: "Updated with latest findings",
238
+ });
239
+
240
+ console.log(result.data.modifiedon); // "2026-02-13T10:30:00Z"
241
+ ```
242
+
243
+ ### Lookup (type-ahead search)
244
+
245
+ ```typescript
246
+ import type { Contact } from "./dataverse-tables.generated";
247
+
248
+ const result = await client.me.lookup<Contact>("contact", {
249
+ search: "john",
250
+ select: ["fullname", "emailaddress1", "jobtitle"],
251
+ top: 10,
252
+ });
253
+
254
+ // Great for autocomplete dropdowns
255
+ for (const contact of result.data) {
256
+ console.log(contact.fullname, contact.emailaddress1);
257
+ }
258
+ ```
259
+
260
+ ### Who am I
261
+
262
+ ```typescript
263
+ const me = await client.me.whoami();
264
+ console.log(me.fullname); // "Jane Developer"
265
+ console.log(me.email); // "jane@example.com"
266
+ console.log(me.contactid); // Dataverse contact GUID
267
+ console.log(me.accountid); // Dataverse account GUID (if linked)
268
+ ```
269
+
270
+ ### Choices (option sets)
271
+
272
+ Choice fields (picklists) have their values managed in Dataverse. Fetch them for building dropdowns:
273
+
274
+ ```typescript
275
+ // All choice fields for a table
276
+ const allChoices = await client.choices("incident");
277
+ // allChoices.fields.statuscode → [{ value: 1, label: "In Progress" }, ...]
278
+ // allChoices.fields.prioritycode → [{ value: 1, label: "High" }, ...]
279
+
280
+ // Single field
281
+ const statusChoices = await client.choices("incident", "statuscode");
282
+ // statusChoices.choices → [{ value: 1, label: "In Progress" }, ...]
283
+ ```
284
+
285
+ ### Schema
286
+
287
+ ```typescript
288
+ // All table schemas
289
+ const schemas = await client.schema();
290
+
291
+ // Single table
292
+ const incidentSchema = await client.schema("incident");
293
+ console.log(incidentSchema.fields); // field definitions with types + descriptions
294
+ console.log(incidentSchema.defaultFields); // fields returned when no `select` is specified
295
+ ```
296
+
297
+ ## Query options
298
+
299
+ Used by `list()`:
300
+
301
+ | Option | Type | Description |
302
+ |--------|------|-------------|
303
+ | `select` | `string[]` | Fields to return |
304
+ | `top` | `number` | Page size (1-100) |
305
+ | `skip` | `number` | Records to skip |
306
+ | `orderBy` | `string` | Sort field and direction, e.g. `"createdon:desc"` |
307
+ | `filter` | `string \| string[]` | OData-style filter expressions |
308
+ | `filterLogic` | `"and" \| "or"` | How to combine multiple filters (default: `"and"`) |
309
+ | `expand` | `string` | Expand related lookups |
310
+
311
+ `lookup()` accepts the same options plus:
312
+
313
+ | Option | Type | Description |
314
+ |--------|------|-------------|
315
+ | `search` | `string` | Search term for type-ahead filtering |
316
+
317
+ `get()` accepts only `select` and `expand`.
318
+
319
+ ## Error handling
320
+
321
+ ```typescript
322
+ import { ApiError } from "@truenorth-it/dataverse-client";
323
+
324
+ try {
325
+ await client.me.list("incident");
326
+ } catch (err) {
327
+ if (err instanceof ApiError) {
328
+ console.error(err.status); // HTTP status code
329
+ console.error(err.body); // Error response body
330
+ }
331
+ }
332
+ ```
333
+
334
+ | Status | Meaning |
335
+ |--------|---------|
336
+ | 401 | Missing or invalid token |
337
+ | 403 | Insufficient permissions |
338
+ | 404 | Unknown table or contact not found |
339
+
340
+ ## Generated type patterns
341
+
342
+ ### Choice and lookup field siblings
343
+
344
+ Choice fields (picklists) include a `_label` sibling with the display text:
345
+ ```typescript
346
+ record.statuscode // 1 (numeric value)
347
+ record.statuscode_label // "In Progress" (display text from Dataverse)
348
+ ```
349
+
350
+ Lookup fields include a `_value` sibling with the referenced record's GUID:
351
+ ```typescript
352
+ record._customerid_value // "a1b2c3d4-..." (GUID of linked customer)
353
+ record._primarycontactid_value // "e5f6g7h8-..." (GUID of linked contact)
354
+ ```
355
+
356
+ ### TableName union
357
+
358
+ The generated file includes a `TableName` union of all valid table names and aliases:
359
+
360
+ ```typescript
361
+ import type { TableName } from "./dataverse-tables.generated";
362
+
363
+ // Type-safe table parameter — accepts "incident", "case", "contact", etc.
364
+ function fetchRecords(table: TableName) {
365
+ return client.me.list(table);
366
+ }
367
+ ```
368
+
369
+ ## Exported types
370
+
371
+ All types are importable from the main package:
372
+
373
+ ```typescript
374
+ import type {
375
+ // Client & scope interfaces
376
+ DataverseClient, ScopeClient, MeScopeClient, ClientConfig,
377
+ // Query types
378
+ QueryOptions, LookupOptions,
379
+ // Response types
380
+ PaginatedResponse, SingleResponse, WhoamiResponse,
381
+ // Schema & choices
382
+ TableSchema, SchemaField, ExpandSchema, Choice,
383
+ FieldChoicesResponse, TableChoicesResponse,
384
+ // Codegen types (for programmatic usage)
385
+ SchemaResponse, SchemaTableInput,
386
+ // Errors
387
+ ApiErrorBody,
388
+ } from "@truenorth-it/dataverse-client";
389
+ ```
390
+
391
+ Table-specific types come from your generated file:
392
+
393
+ ```typescript
394
+ import type { Incident, Contact, TableName } from "./dataverse-tables.generated";
395
+ ```
396
+
397
+ ## Requirements
398
+
399
+ - Node.js 18+
400
+ - An Auth0 token provider (or any async function that returns a Bearer token)
401
+ - Access to a deployed Dataverse Contact API instance
402
+
403
+ ## License
404
+
405
+ ISC
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@truenorth-it/dataverse-client",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./sdk/dist/index.js",
6
+ "types": "./sdk/dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./sdk/dist/index.js",
10
+ "types": "./sdk/dist/index.d.ts"
11
+ }
12
+ },
13
+ "bin": {
14
+ "dataverse-client": "./sdk/dist/cli.js"
15
+ },
16
+ "files": [
17
+ "sdk/dist"
18
+ ],
19
+ "scripts": {
20
+ "generate:sdk-types": "tsx scripts/generate-sdk-types.ts",
21
+ "build:sdk": "tsc -p sdk/tsconfig.json",
22
+ "prepare": "tsc -p sdk/tsconfig.json",
23
+ "dev": "vite",
24
+ "build": "tsc && vite build",
25
+ "preview": "vite preview",
26
+ "lint": "eslint . --ext .ts,.tsx",
27
+ "typecheck": "tsc --noEmit",
28
+ "generate-tables": "tsx scripts/generate-tables.ts",
29
+ "sync-auth0-perms": "tsx scripts/sync-auth0-permissions.ts",
30
+ "sync-auth0-perms:apply": "tsx scripts/sync-auth0-permissions.ts --apply",
31
+ "add-table": "tsx scripts/add-table.ts",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "test:coverage": "vitest run --coverage"
35
+ },
36
+ "dependencies": {
37
+ "@auth0/auth0-react": "^2.2.4",
38
+ "@azure/identity": "^4.2.0",
39
+ "@microsoft/applicationinsights-web": "^3.3.11",
40
+ "applicationinsights": "^2.9.8",
41
+ "jose": "^5.2.0",
42
+ "mermaid": "^11.12.2",
43
+ "react": "^18.2.0",
44
+ "react-dom": "^18.2.0",
45
+ "react-markdown": "^10.1.0",
46
+ "react-router-dom": "^7.13.0",
47
+ "remark-gfm": "^4.0.1"
48
+ },
49
+ "devDependencies": {
50
+ "@tailwindcss/vite": "^4.1.18",
51
+ "@testing-library/jest-dom": "^6.9.1",
52
+ "@testing-library/react": "^16.3.2",
53
+ "@testing-library/user-event": "^14.6.1",
54
+ "@types/node": "^20.11.0",
55
+ "@types/react": "^18.2.48",
56
+ "@types/react-dom": "^18.2.18",
57
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
58
+ "@typescript-eslint/parser": "^7.0.0",
59
+ "@vercel/node": "^3.0.0",
60
+ "@vitejs/plugin-react": "^4.2.1",
61
+ "eslint": "^8.56.0",
62
+ "happy-dom": "^20.6.1",
63
+ "tailwindcss": "^4.1.18",
64
+ "tsx": "^4.21.0",
65
+ "typescript": "^5.3.3",
66
+ "vercel": "^33.0.0",
67
+ "vite": "^5.0.12",
68
+ "vitest": "^4.0.18"
69
+ },
70
+ "engines": {
71
+ "node": ">=18"
72
+ }
73
+ }
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for generating TypeScript table types from a Dataverse Contact API deployment.
4
+ *
5
+ * Usage:
6
+ * npx dataverse-client generate --url https://your-api.vercel.app
7
+ * npx dataverse-client generate --url https://your-api.vercel.app --output src/types.ts
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI for generating TypeScript table types from a Dataverse Contact API deployment.
4
+ *
5
+ * Usage:
6
+ * npx dataverse-client generate --url https://your-api.vercel.app
7
+ * npx dataverse-client generate --url https://your-api.vercel.app --output src/types.ts
8
+ */
9
+ import { parseArgs } from "node:util";
10
+ import { writeFileSync } from "node:fs";
11
+ import { resolve } from "node:path";
12
+ import { generateTableTypes } from "./codegen.js";
13
+ const HELP = `
14
+ dataverse-client — TypeScript SDK for Dataverse Contact API
15
+
16
+ Commands:
17
+ generate Fetch schema from your API and generate TypeScript types
18
+
19
+ Options:
20
+ --url, -u Base URL of your API deployment (required)
21
+ --output, -o Output file path (default: ./dataverse-tables.generated.ts)
22
+ --api-base API base path (default: /api/v2)
23
+ --no-choices Skip fetching choice values (faster, no enums generated)
24
+ --help, -h Show this help message
25
+
26
+ Examples:
27
+ npx dataverse-client generate --url https://my-api.vercel.app
28
+ npx dataverse-client generate -u https://my-api.vercel.app -o src/tables.ts
29
+ npx dataverse-client generate --url https://my-api.vercel.app --no-choices
30
+ `.trim();
31
+ async function main() {
32
+ const { values, positionals } = parseArgs({
33
+ args: process.argv.slice(2),
34
+ options: {
35
+ url: { type: "string", short: "u" },
36
+ output: { type: "string", short: "o", default: "./dataverse-tables.generated.ts" },
37
+ "api-base": { type: "string", default: "/api/v2" },
38
+ "no-choices": { type: "boolean", default: false },
39
+ help: { type: "boolean", short: "h", default: false },
40
+ },
41
+ allowPositionals: true,
42
+ });
43
+ if (values.help || positionals.length === 0) {
44
+ console.log(HELP);
45
+ process.exit(0);
46
+ }
47
+ const command = positionals[0];
48
+ if (command !== "generate") {
49
+ console.error(`Unknown command: ${command}\n\nRun 'dataverse-client --help' for usage.`);
50
+ process.exit(1);
51
+ }
52
+ if (!values.url) {
53
+ console.error("Error: --url is required.\n\nExample: npx dataverse-client generate --url https://your-api.vercel.app");
54
+ process.exit(1);
55
+ }
56
+ const baseUrl = values.url.replace(/\/+$/, "");
57
+ const apiBase = values["api-base"] ?? "/api/v2";
58
+ const skipChoices = values["no-choices"] ?? false;
59
+ const schemaUrl = `${baseUrl}${apiBase}/schema`;
60
+ // 1. Fetch schema
61
+ console.log(`Fetching schema from ${schemaUrl} ...`);
62
+ let schemaResponse;
63
+ try {
64
+ schemaResponse = await fetch(schemaUrl);
65
+ }
66
+ catch (err) {
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ console.error(`Failed to fetch schema: ${message}`);
69
+ process.exit(1);
70
+ }
71
+ if (!schemaResponse.ok) {
72
+ console.error(`Schema endpoint returned ${schemaResponse.status} ${schemaResponse.statusText}`);
73
+ process.exit(1);
74
+ }
75
+ const schema = await schemaResponse.json();
76
+ if (!schema.tables || !Array.isArray(schema.tables)) {
77
+ console.error("Unexpected response shape — expected { tables: [...] }");
78
+ process.exit(1);
79
+ }
80
+ // 2. Fetch all public choices in a single request
81
+ let choices;
82
+ if (!skipChoices) {
83
+ const choicesUrl = `${baseUrl}${apiBase}/choices`;
84
+ console.log(`Fetching choices from ${choicesUrl} ...`);
85
+ try {
86
+ const choicesResponse = await fetch(choicesUrl);
87
+ if (choicesResponse.ok) {
88
+ const data = await choicesResponse.json();
89
+ if (data.tables && Array.isArray(data.tables)) {
90
+ choices = data.tables;
91
+ console.log(` Got choices for ${choices.length} table(s)`);
92
+ }
93
+ }
94
+ else {
95
+ console.warn(` Choices endpoint returned ${choicesResponse.status}, skipping enums`);
96
+ }
97
+ }
98
+ catch {
99
+ console.warn(" Failed to fetch choices, skipping enums");
100
+ }
101
+ }
102
+ // 3. Generate TypeScript
103
+ const source = generateTableTypes(schema, choices);
104
+ const outputPath = resolve(process.cwd(), values.output);
105
+ writeFileSync(outputPath, source, "utf-8");
106
+ const tableCount = schema.tables.length;
107
+ const fieldCount = schema.tables.reduce((sum, t) => sum + t.fields.length, 0);
108
+ console.log(`Generated ${tableCount} table(s) with ${fieldCount} total fields`);
109
+ if (choices && choices.length > 0) {
110
+ const enumCount = choices.reduce((sum, c) => sum + Object.keys(c.fields).length, 0);
111
+ console.log(`Generated ${enumCount} choice enum(s)`);
112
+ }
113
+ console.log(`Written to ${outputPath}`);
114
+ }
115
+ main().catch((err) => {
116
+ console.error(err);
117
+ process.exit(1);
118
+ });
119
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;CAiBZ,CAAC,IAAI,EAAE,CAAC;AAET,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;QACxC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,OAAO,EAAE;YACP,GAAG,EAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;YAC5C,MAAM,EAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,iCAAiC,EAAE;YACxF,UAAU,EAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE;YACpD,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;YACjD,IAAI,EAAU,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;SAC9D;QACD,gBAAgB,EAAE,IAAI;KACvB,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAE/B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,8CAA8C,CAAC,CAAC;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,uGAAuG,CAAC,CAAC;QACvH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC;IAChD,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,KAAK,CAAC;IAClD,MAAM,SAAS,GAAG,GAAG,OAAO,GAAG,OAAO,SAAS,CAAC;IAEhD,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,wBAAwB,SAAS,MAAM,CAAC,CAAC;IAErD,IAAI,cAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,2BAA2B,OAAO,EAAE,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,4BAA4B,cAAc,CAAC,MAAM,IAAI,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;QAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC;IAE3C,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kDAAkD;IAClD,IAAI,OAAwC,CAAC;IAE7C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,GAAG,OAAO,GAAG,OAAO,UAAU,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,yBAAyB,UAAU,MAAM,CAAC,CAAC;QAEvD,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,eAAe,CAAC,EAAE,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,CAAC;gBAC1C,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC9C,OAAO,GAAG,IAAI,CAAC,MAA6B,CAAC;oBAC7C,OAAO,CAAC,GAAG,CAAC,qBAAqB,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,+BAA+B,eAAe,CAAC,MAAM,kBAAkB,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,MAAO,CAAC,CAAC;IAE1D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAE3C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,MAAgB,CAAC;IAClD,MAAM,UAAU,GAAI,MAAM,CAAC,MAAkC,CAAC,MAAM,CAClE,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EACjC,CAAC,CACF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,kBAAkB,UAAU,eAAe,CAAC,CAAC;IAChF,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAC9B,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAC9C,CAAC,CACF,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,aAAa,SAAS,iBAAiB,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,cAAc,UAAU,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { ClientConfig, QueryOptions, LookupOptions, PaginatedResponse, SingleResponse, WhoamiResponse, TableSchema, FieldChoicesResponse, TableChoicesResponse, ApiErrorBody } from "./types.js";
2
+ /** Error thrown when the API returns a non-OK response */
3
+ export declare class ApiError extends Error {
4
+ readonly status: number;
5
+ readonly statusText: string;
6
+ readonly body: ApiErrorBody | null;
7
+ constructor(status: number, statusText: string, body: ApiErrorBody | null);
8
+ }
9
+ /** Scoped API operations (me, team, or all) */
10
+ export interface ScopeClient {
11
+ /** List records from a table */
12
+ list<T = Record<string, unknown>>(table: string, options?: QueryOptions): Promise<PaginatedResponse<T>>;
13
+ /** Get a single record by ID */
14
+ get<T = Record<string, unknown>>(table: string, id: string, options?: Pick<QueryOptions, "select" | "expand">): Promise<SingleResponse<T>>;
15
+ /** Update a record */
16
+ update<T = Record<string, unknown>>(table: string, id: string, data: Record<string, unknown>): Promise<SingleResponse<T>>;
17
+ /** Search lookup records (type-ahead) */
18
+ lookup<T = Record<string, unknown>>(table: string, options?: LookupOptions): Promise<PaginatedResponse<T>>;
19
+ }
20
+ /** Extended scope with create and whoami (only available on "me") */
21
+ export interface MeScopeClient extends ScopeClient {
22
+ /** Create a new record */
23
+ create<T = Record<string, unknown>>(table: string, data: Record<string, unknown>): Promise<SingleResponse<T>>;
24
+ /** Get authenticated identity + Dataverse contact info */
25
+ whoami(): Promise<WhoamiResponse>;
26
+ }
27
+ /** Dataverse Contact API client */
28
+ export interface DataverseClient {
29
+ /** Operations on the authenticated user's own records */
30
+ me: MeScopeClient;
31
+ /** Operations on records belonging to the user's account/team */
32
+ team: ScopeClient;
33
+ /** Operations on all records (admin) */
34
+ all: ScopeClient;
35
+ /** Fetch choice/option-set values for a table, or a specific field */
36
+ choices(table: string, field?: string): Promise<FieldChoicesResponse | TableChoicesResponse>;
37
+ /** Fetch table schema (single table or all tables) */
38
+ schema(table?: string): Promise<TableSchema | TableSchema[]>;
39
+ }
40
+ /** Create a configured API client instance */
41
+ export declare function createClient(config: ClientConfig): DataverseClient;
42
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,0DAA0D;AAC1D,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;gBAEvB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;CAO1E;AA+DD,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAEjC,gCAAgC;IAChC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,QAAQ,CAAC,GAChD,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9B,sBAAsB;IACtB,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9B,yCAAyC;IACzC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;CAClC;AAwDD,qEAAqE;AACrE,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,0BAA0B;IAC1B,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9B,0DAA0D;IAC1D,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;CACnC;AAoBD,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,EAAE,EAAE,aAAa,CAAC;IAClB,iEAAiE;IACjE,IAAI,EAAE,WAAW,CAAC;IAClB,wCAAwC;IACxC,GAAG,EAAE,WAAW,CAAC;IAEjB,sEAAsE;IACtE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,CAAC;IAE7F,sDAAsD;IACtD,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,CAAC;CAC9D;AAED,8CAA8C;AAC9C,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAsBlE"}