@synthigy/sdk 0.2.1 → 0.2.2
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 +3 -1
- package/codegen/codegen.mjs +3 -12
- package/codegen/pull.mjs +4 -4
- package/package.json +1 -1
- package/src/index.d.ts +45 -1
- package/src/index.js +15 -0
package/README.md
CHANGED
|
@@ -60,7 +60,9 @@ Run it with `synthigy exec -- node hello.ts`.
|
|
|
60
60
|
`watchSqlTemplate` for live analytics, `watch` for raw record events.
|
|
61
61
|
|
|
62
62
|
- **`actingAs` per call.** Every read and write can run as a specific user, with
|
|
63
|
-
IAM / RBAC / row-level security enforced *server-side
|
|
63
|
+
IAM / RBAC / row-level security enforced *server-side*; `whoami({ actingAs })`
|
|
64
|
+
shows who a call runs as — roles, superuser, whether this client may act as
|
|
65
|
+
users. Tokens never have to
|
|
64
66
|
reach the browser. `client.login` runs the OIDC authorization-code + PKCE
|
|
65
67
|
exchange for your BFF and leaves sessions to you; `createBrowserLogin` does
|
|
66
68
|
the same for a browser app, as a public client with silent renew and tokens
|
package/codegen/codegen.mjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// Unified codegen tool:
|
|
3
3
|
// node codegen.mjs <xsql...> [outDir] — describe + gen TS (saves ops.ir.json)
|
|
4
4
|
// node codegen.mjs check <xsql...> — re-describe, diff, exit 1 on drift
|
|
5
|
-
// node codegen.mjs pull [endpoint] [out] — pull schema.json (wraps pull.mjs)
|
|
6
5
|
//
|
|
7
6
|
// Config via env: SYNTHIGY_ENDPOINT, SYNTHIGY_CLIENT_ID, SYNTHIGY_CLIENT_SECRET
|
|
8
7
|
|
|
@@ -29,10 +28,9 @@ synthigy-codegen — generate TypeScript types from XSQL operations
|
|
|
29
28
|
Usage:
|
|
30
29
|
codegen.mjs [flags] <a.xsql> [b.xsql ...] [outDir] generate TS from one or more xsql files
|
|
31
30
|
codegen.mjs check [flags] <a.xsql> [b.xsql ...] re-describe, diff IR, exit 1 on drift
|
|
32
|
-
codegen.mjs pull [endpoint] [out] pull schema.json only
|
|
33
31
|
|
|
34
32
|
Flags:
|
|
35
|
-
--pull
|
|
33
|
+
--pull refresh schema.json beside the .xsql before generating
|
|
36
34
|
--keys snake|camel field key casing in generated types (default: snake)
|
|
37
35
|
--no-writes omit sync / stack / delete methods
|
|
38
36
|
--schema <path> explicit schema.json path (skips auto-pull)
|
|
@@ -47,7 +45,6 @@ Examples:
|
|
|
47
45
|
node codegen.mjs movies.xsql src/generated/ first run auto-pulls schema
|
|
48
46
|
node codegen.mjs --pull movies.xsql src/generated/ force schema refresh + generate
|
|
49
47
|
node codegen.mjs check movies.xsql CI drift check
|
|
50
|
-
node codegen.mjs pull http://localhost:7887 pull schema only
|
|
51
48
|
`.trim())
|
|
52
49
|
process.exit(0)
|
|
53
50
|
}
|
|
@@ -71,13 +68,6 @@ if (!VALID_KEYS.has(flags.keys)) {
|
|
|
71
68
|
}
|
|
72
69
|
|
|
73
70
|
const checkMode = pos[0] === 'check'
|
|
74
|
-
const pullMode = pos[0] === 'pull'
|
|
75
|
-
|
|
76
|
-
if (pullMode) {
|
|
77
|
-
execFileSync(process.execPath, [path.join(here, 'pull.mjs'), ...pos.slice(1)],
|
|
78
|
-
{ stdio: 'inherit', env: process.env })
|
|
79
|
-
process.exit(0)
|
|
80
|
-
}
|
|
81
71
|
|
|
82
72
|
// Positionals: last non-.xsql arg is outDir; everything before it (files or dirs)
|
|
83
73
|
// is input. check mode has no outDir — every positional is input.
|
|
@@ -90,7 +80,6 @@ const xsqlArgs = hasExplicitOut ? rawPos.slice(0, -1) : rawPos
|
|
|
90
80
|
if (!xsqlArgs.length) {
|
|
91
81
|
console.error('usage: node codegen.mjs [flags] <file.xsql|dir> [...] [outDir] (dirs searched recursively)')
|
|
92
82
|
console.error(' node codegen.mjs check <file.xsql|dir> [...]')
|
|
93
|
-
console.error(' node codegen.mjs pull [endpoint] [schema.json]')
|
|
94
83
|
console.error('flags: --pull force schema refresh')
|
|
95
84
|
console.error(' --keys snake|camel field casing (default: snake)')
|
|
96
85
|
console.error(' --no-writes omit sync/stack/delete methods')
|
|
@@ -99,6 +88,8 @@ if (!xsqlArgs.length) {
|
|
|
99
88
|
}
|
|
100
89
|
|
|
101
90
|
const isDir = p => fs.existsSync(p) && fs.statSync(p).isDirectory()
|
|
91
|
+
const missing = xsqlArgs.filter(a => !fs.existsSync(path.resolve(a)))
|
|
92
|
+
if (missing.length) { console.error(`no such .xsql file or directory: ${missing.join(', ')}`); process.exit(1) }
|
|
102
93
|
const xsqlPaths = xsqlArgs.flatMap(a => {
|
|
103
94
|
const p = path.resolve(a)
|
|
104
95
|
if (isDir(p))
|
package/codegen/pull.mjs
CHANGED
|
@@ -21,8 +21,9 @@ import path from 'node:path'
|
|
|
21
21
|
import { createClient } from '../src/index.js'
|
|
22
22
|
|
|
23
23
|
const endpoint = process.argv[2] ?? process.env.SYNTHIGY_ENDPOINT
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
const out = process.argv[3]
|
|
25
|
+
if (!endpoint || !out) {
|
|
26
|
+
console.error('usage: node pull.mjs <endpoint> <schema.json>')
|
|
26
27
|
process.exit(1)
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -41,8 +42,7 @@ if (SYNTHIGY_CLIENT_ID && SYNTHIGY_CLIENT_SECRET) {
|
|
|
41
42
|
config.token = SYNTHIGY_TOKEN ?? '' // '' = authless (bare server)
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
const
|
|
45
|
-
const outPath = process.argv[3] ? path.resolve(process.argv[3]) : path.join(here, 'schema.json')
|
|
45
|
+
const outPath = path.resolve(out)
|
|
46
46
|
|
|
47
47
|
const client = createClient(config)
|
|
48
48
|
const schema = await client.schema()
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -324,11 +324,50 @@ export type SynthigyErrorCode =
|
|
|
324
324
|
| 'HTTP_ERROR' | 'OPERATION_ERROR' | 'INTERNAL_ERROR'
|
|
325
325
|
| (string & {})
|
|
326
326
|
|
|
327
|
+
/** `whoami()` — the identity a call runs as. `client` is null in-process (no OAuth client). */
|
|
328
|
+
export interface WhoAmI {
|
|
329
|
+
xid: string | null
|
|
330
|
+
name: string | null
|
|
331
|
+
active: boolean
|
|
332
|
+
superuser: boolean
|
|
333
|
+
roles: string[]
|
|
334
|
+
groups: string[]
|
|
335
|
+
/** `trusted`: this client may act as users (confidential, active, flagged trusted). */
|
|
336
|
+
client: { id: string; trusted: boolean } | null
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export type SynthigyErrorCategory =
|
|
340
|
+
| 'auth' | 'iam' | 'validation' | 'not_found'
|
|
341
|
+
| 'conflict' | 'rate_limit' | 'network' | 'internal'
|
|
342
|
+
|
|
343
|
+
/** 1-based source position (XSQL_PARSE_ERROR, TEMPLATE_*). */
|
|
344
|
+
export interface SourcePosition { line: number; col: number }
|
|
345
|
+
|
|
327
346
|
export class SynthigyError extends Error {
|
|
328
347
|
name: 'SynthigyError'
|
|
329
348
|
code: SynthigyErrorCode
|
|
349
|
+
category: SynthigyErrorCategory
|
|
350
|
+
/** True for known network/rate_limit/internal codes, or when the server marked the error retryable. */
|
|
351
|
+
retryable: boolean
|
|
330
352
|
details?: unknown
|
|
331
|
-
|
|
353
|
+
hint?: string
|
|
354
|
+
available?: string[]
|
|
355
|
+
path?: unknown
|
|
356
|
+
entity?: string
|
|
357
|
+
relation?: string
|
|
358
|
+
operator?: string
|
|
359
|
+
requestId?: string
|
|
360
|
+
status?: number
|
|
361
|
+
line?: number
|
|
362
|
+
col?: number
|
|
363
|
+
start?: SourcePosition
|
|
364
|
+
end?: SourcePosition
|
|
365
|
+
diagnostics?: unknown[]
|
|
366
|
+
constructor(message: string, code: string, details?: unknown, extras?: {
|
|
367
|
+
hint?: string; available?: string[]; path?: unknown; entity?: string; relation?: string
|
|
368
|
+
operator?: string; requestId?: string; status?: number; retryable?: boolean
|
|
369
|
+
line?: number; col?: number; start?: SourcePosition; end?: SourcePosition; diagnostics?: unknown[]
|
|
370
|
+
})
|
|
332
371
|
}
|
|
333
372
|
|
|
334
373
|
// ============================================================================
|
|
@@ -789,6 +828,9 @@ export class SynthigyClient {
|
|
|
789
828
|
*/
|
|
790
829
|
deployedModel(opts?: ExecOpts): Promise<Record<string, unknown>>
|
|
791
830
|
|
|
831
|
+
/** Who a call runs as, after `actingAs` — roles, superuser, and whether this client may act as users. */
|
|
832
|
+
whoami(opts?: ExecOpts): Promise<WhoAmI>
|
|
833
|
+
|
|
792
834
|
/**
|
|
793
835
|
* Deploy a dataset version from a modeler export — pass the export file's
|
|
794
836
|
* contents verbatim, the server decodes it. Requires `dataset:deploy`.
|
|
@@ -1210,6 +1252,7 @@ export const op: {
|
|
|
1210
1252
|
query(xsql: string, params?: Record<string, unknown>, verb?: string): Operation
|
|
1211
1253
|
deployedModel(): Operation
|
|
1212
1254
|
runtimeModel(): Operation
|
|
1255
|
+
whoami(): Operation
|
|
1213
1256
|
deploy(exportContents: string): Operation
|
|
1214
1257
|
destroy(datasetXid: string): Operation
|
|
1215
1258
|
}
|
|
@@ -1291,6 +1334,7 @@ export const onboardComplete: SynthigyClient['onboardComplete']
|
|
|
1291
1334
|
export const deploy: SynthigyClient['deploy']
|
|
1292
1335
|
export const destroy: SynthigyClient['destroy']
|
|
1293
1336
|
export const deployedModel: SynthigyClient['deployedModel']
|
|
1337
|
+
export const whoami: SynthigyClient['whoami']
|
|
1294
1338
|
export const runtimeModel: SynthigyClient['runtimeModel']
|
|
1295
1339
|
export const token: SynthigyClient['token']
|
|
1296
1340
|
export function history(): SynthigyClient['history']
|
package/src/index.js
CHANGED
|
@@ -2003,6 +2003,19 @@ class SynthigyClient {
|
|
|
2003
2003
|
return result.data
|
|
2004
2004
|
}
|
|
2005
2005
|
|
|
2006
|
+
/**
|
|
2007
|
+
* Who a call runs as, after `actingAs`: xid, name, active, superuser, roles,
|
|
2008
|
+
* groups, and `client` ({ id, trusted }) — trusted means it may act as users.
|
|
2009
|
+
*
|
|
2010
|
+
* @param {Object} [opts] - Options ({ actingAs })
|
|
2011
|
+
* @returns {Promise<Object>}
|
|
2012
|
+
*/
|
|
2013
|
+
async whoami(opts) {
|
|
2014
|
+
const [result] = await this.exec([{ op: 'whoami' }], opts)
|
|
2015
|
+
if (!result.ok) throw _errorFromServer(result.error, undefined, result._requestId)
|
|
2016
|
+
return result.data
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2006
2019
|
/**
|
|
2007
2020
|
* Deploy a dataset version from a modeler export. Pass the export file's
|
|
2008
2021
|
* contents verbatim — the server decodes it. Requires `dataset:deploy`.
|
|
@@ -2561,6 +2574,7 @@ export const op = {
|
|
|
2561
2574
|
query: (xsql, params, verb = 'search') => ({ op: 'xsql', xsql: xsqlDocument(xsql, verb), ...(params !== undefined && { params }) }),
|
|
2562
2575
|
deployedModel: () => ({ op: 'deployed-model' }),
|
|
2563
2576
|
runtimeModel: () => ({ op: 'runtime-model' }),
|
|
2577
|
+
whoami: () => ({ op: 'whoami' }),
|
|
2564
2578
|
deploy: (exportContents) => ({ op: 'deploy', data: exportContents }),
|
|
2565
2579
|
destroy: (datasetXid) => ({ op: 'delete', entity: 'dataset', data: { xid: datasetXid } }),
|
|
2566
2580
|
}
|
|
@@ -2692,6 +2706,7 @@ export const onboardComplete = (...a) => _dflt().onboardComplete(...a)
|
|
|
2692
2706
|
export const deploy = (...a) => _dflt().deploy(...a)
|
|
2693
2707
|
export const destroy = (...a) => _dflt().destroy(...a)
|
|
2694
2708
|
export const deployedModel = (...a) => _dflt().deployedModel(...a)
|
|
2709
|
+
export const whoami = (...a) => _dflt().whoami(...a)
|
|
2695
2710
|
export const runtimeModel = (...a) => _dflt().runtimeModel(...a)
|
|
2696
2711
|
export const token = (...a) => _dflt().token(...a)
|
|
2697
2712
|
export const history = () => _dflt().history
|