@alvera-ai/platform-sdk 0.2.4 → 0.4.1
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 +82 -13
- package/dist/cli.js +424 -15
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +190 -3
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +169 -7
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +21 -4
- package/dist/config.js.map +1 -1
- package/dist/environments.generated.d.ts +21 -0
- package/dist/environments.generated.d.ts.map +1 -0
- package/dist/environments.generated.js +8 -0
- package/dist/environments.generated.js.map +1 -0
- package/dist/generated/client/client.gen.d.ts.map +1 -1
- package/dist/generated/client/client.gen.js +3 -3
- package/dist/generated/client/client.gen.js.map +1 -1
- package/dist/generated/client/types.gen.d.ts +1 -1
- package/dist/generated/client/utils.gen.js +1 -1
- package/dist/generated/client/utils.gen.js.map +1 -1
- package/dist/generated/core/pathSerializer.gen.d.ts +1 -1
- package/dist/generated/core/pathSerializer.gen.d.ts.map +1 -1
- package/dist/generated/core/serverSentEvents.gen.d.ts +1 -1
- package/dist/generated/core/serverSentEvents.gen.d.ts.map +1 -1
- package/dist/generated/core/serverSentEvents.gen.js +3 -4
- package/dist/generated/core/serverSentEvents.gen.js.map +1 -1
- package/dist/generated/core/types.gen.d.ts +1 -1
- package/dist/generated/core/utils.gen.js +1 -1
- package/dist/generated/core/utils.gen.js.map +1 -1
- package/dist/generated/index.d.ts +2 -2
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/generated/sdk.gen.d.ts +325 -121
- package/dist/generated/sdk.gen.d.ts.map +1 -1
- package/dist/generated/sdk.gen.js +1030 -263
- package/dist/generated/sdk.gen.js.map +1 -1
- package/dist/generated/types.gen.d.ts +8749 -3536
- package/dist/generated/types.gen.d.ts.map +1 -1
- package/dist/generated/valibot.gen.d.ts +31944 -11564
- package/dist/generated/valibot.gen.d.ts.map +1 -1
- package/dist/generated/valibot.gen.js +4888 -2247
- package/dist/generated/valibot.gen.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -16,9 +16,9 @@ pnpm add @alvera-ai/platform-sdk
|
|
|
16
16
|
## Quick start
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
|
-
import { createPlatformApi, createSession } from '@alvera-ai/platform-sdk';
|
|
19
|
+
import { createPlatformApi, createSession, ENVIRONMENTS } from '@alvera-ai/platform-sdk';
|
|
20
20
|
|
|
21
|
-
const baseUrl =
|
|
21
|
+
const baseUrl = ENVIRONMENTS.prod.base_url; // or ENVIRONMENTS.local / ENVIRONMENTS.demo
|
|
22
22
|
|
|
23
23
|
// 1. Exchange credentials for a session token
|
|
24
24
|
const session = await createSession({
|
|
@@ -79,6 +79,36 @@ await revokeSession();
|
|
|
79
79
|
`session.expiresAt` is an ISO-8601 timestamp — check it before long-running
|
|
80
80
|
work and re-authenticate if needed.
|
|
81
81
|
|
|
82
|
+
## Environments
|
|
83
|
+
|
|
84
|
+
The base URLs ship with the package, derived at build time from the
|
|
85
|
+
`servers[]` block of the committed OpenAPI spec (`spec/openapi.yaml`). The
|
|
86
|
+
generated map is exported as `ENVIRONMENTS`:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { ENVIRONMENTS, DEFAULT_ENVIRONMENT } from '@alvera-ai/platform-sdk';
|
|
90
|
+
|
|
91
|
+
ENVIRONMENTS.local.base_url; // http://localhost:4000
|
|
92
|
+
ENVIRONMENTS.demo.base_url; // https://platform-hh.alvera.ai
|
|
93
|
+
ENVIRONMENTS.prod.base_url; // https://app.alvera.ai
|
|
94
|
+
|
|
95
|
+
DEFAULT_ENVIRONMENT; // 'prod'
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The CLI resolves a base URL with this precedence (highest first):
|
|
99
|
+
|
|
100
|
+
1. `ALVERA_BASE_URL` env var (explicit URL override — useful for tunnels /
|
|
101
|
+
ephemeral servers)
|
|
102
|
+
2. `base_url` pinned in the profile (written when the user passes a custom URL
|
|
103
|
+
to `alvera configure` or `alvera login --base-url …`)
|
|
104
|
+
3. `ENVIRONMENTS[env].base_url` where `env` is the first of: `--env <name>`
|
|
105
|
+
flag, `ALVERA_ENV` env var, the profile's `environment` entry, or
|
|
106
|
+
`DEFAULT_ENVIRONMENT`
|
|
107
|
+
|
|
108
|
+
Adding, renaming, or removing environments happens in the platform repo (the
|
|
109
|
+
`servers/0` function in `lib/platform_api/api_spec.ex`); rerun
|
|
110
|
+
`pnpm regen` in the SDK to pick up the change.
|
|
111
|
+
|
|
82
112
|
## Resources
|
|
83
113
|
|
|
84
114
|
| Resource | Operations |
|
|
@@ -140,14 +170,16 @@ alvera --help
|
|
|
140
170
|
Both files are INI. The default profile is `[default]`; additional profiles
|
|
141
171
|
live under `[profile <name>]` in `config` and `[<name>]` in `credentials`.
|
|
142
172
|
|
|
143
|
-
Every command accepts `--profile <name>`. Environment
|
|
144
|
-
(`ALVERA_PROFILE`, `
|
|
145
|
-
`ALVERA_PASSWORD`, `ALVERA_SESSION_TOKEN`) take precedence
|
|
173
|
+
Every command accepts `--profile <name>` and `--env <name>`. Environment
|
|
174
|
+
variables (`ALVERA_PROFILE`, `ALVERA_ENV`, `ALVERA_BASE_URL`, `ALVERA_TENANT`,
|
|
175
|
+
`ALVERA_EMAIL`, `ALVERA_PASSWORD`, `ALVERA_SESSION_TOKEN`) take precedence
|
|
176
|
+
over file values.
|
|
146
177
|
|
|
147
178
|
### Getting started
|
|
148
179
|
|
|
149
180
|
```bash
|
|
150
|
-
alvera
|
|
181
|
+
alvera env list # show local / demo / prod
|
|
182
|
+
alvera configure # pick environment + default tenant
|
|
151
183
|
alvera login --email me@acme.com --tenant acme
|
|
152
184
|
alvera ping
|
|
153
185
|
alvera datalakes list
|
|
@@ -155,13 +187,26 @@ alvera tools create --body-file tool.json
|
|
|
155
187
|
alvera logout
|
|
156
188
|
```
|
|
157
189
|
|
|
158
|
-
|
|
190
|
+
Per-command env switch (no profile edit):
|
|
159
191
|
|
|
160
192
|
```bash
|
|
161
|
-
alvera --
|
|
193
|
+
alvera --env local ping
|
|
194
|
+
ALVERA_ENV=demo alvera datalakes list
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Pin an env into a profile:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
alvera --profile staging env use demo
|
|
162
201
|
alvera --profile staging datalakes list
|
|
163
202
|
```
|
|
164
203
|
|
|
204
|
+
Override the base URL for an ad-hoc host (tunnels, local branches):
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
ALVERA_BASE_URL=https://pr-123.preview.alvera.ai alvera ping
|
|
208
|
+
```
|
|
209
|
+
|
|
165
210
|
### Command surface
|
|
166
211
|
|
|
167
212
|
```
|
|
@@ -170,6 +215,7 @@ alvera login [--email] [--password] [--tenant] [--base-url] [--expires-in]
|
|
|
170
215
|
alvera logout
|
|
171
216
|
alvera whoami
|
|
172
217
|
alvera ping
|
|
218
|
+
alvera env list | use <name>
|
|
173
219
|
|
|
174
220
|
alvera datalakes list | get <id> | create
|
|
175
221
|
alvera data-sources list <datalake> | create <datalake> | update <datalake> <id>
|
|
@@ -196,16 +242,39 @@ status messages and prompts go to stderr so responses stay pipeable.
|
|
|
196
242
|
|
|
197
243
|
## Regenerating the typed client
|
|
198
244
|
|
|
199
|
-
The typed client is generated from
|
|
200
|
-
`https://
|
|
201
|
-
|
|
245
|
+
The typed client is generated from `spec/openapi.yaml` using
|
|
246
|
+
[`@hey-api/openapi-ts`](https://heyapi.dev/). The spec is produced by the
|
|
247
|
+
platform repo and committed here, so this repo is fully self-contained at CI
|
|
248
|
+
time.
|
|
249
|
+
|
|
250
|
+
To pull a newer spec from the sibling platform repo:
|
|
202
251
|
|
|
203
252
|
```bash
|
|
204
|
-
|
|
205
|
-
|
|
253
|
+
# in the platform repo
|
|
254
|
+
mix openapi.spec.yaml --spec PlatformApi.ApiSpec openapi.yaml
|
|
255
|
+
git commit -am "feat(api): …"
|
|
256
|
+
|
|
257
|
+
# in this repo
|
|
258
|
+
cp ../platform/openapi.yaml spec/openapi.yaml
|
|
259
|
+
pnpm regen # gen-environments + codegen + check-coverage
|
|
206
260
|
pnpm build # compile to dist/
|
|
261
|
+
git commit -am "chore: sync openapi spec"
|
|
207
262
|
```
|
|
208
263
|
|
|
264
|
+
`pnpm regen` runs `gen-environments` (rebuilds
|
|
265
|
+
`src/environments.generated.ts` from `servers[]`), then `codegen`, then
|
|
266
|
+
`check-coverage`.
|
|
267
|
+
|
|
268
|
+
## Releases
|
|
269
|
+
|
|
270
|
+
This package uses
|
|
271
|
+
[release-please](https://github.com/googleapis/release-please) plus
|
|
272
|
+
[Conventional Commits](https://www.conventionalcommits.org/). Commits on
|
|
273
|
+
`main` of the form `feat: …`, `fix: …`, `chore: …` feed into an automated
|
|
274
|
+
"chore(main): release X.Y.Z" PR that bumps `package.json` and updates
|
|
275
|
+
`CHANGELOG.md`. Merging that PR tags `vX.Y.Z`, which in turn triggers the
|
|
276
|
+
existing npm publish workflow.
|
|
277
|
+
|
|
209
278
|
## License
|
|
210
279
|
|
|
211
280
|
MIT
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,8 @@ import { ValiError } from 'valibot';
|
|
|
8
8
|
import { createPlatformApi, createSession, revokeSession } from './client.js';
|
|
9
9
|
const packageJsonPath = resolve(dirname(fileURLToPath(import.meta.url)), '..', 'package.json');
|
|
10
10
|
const { version: packageVersion } = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
11
|
-
import { CONFIG_PATHS, clearProfileCreds, getProfileName, resolveProfile, writeProfileConfig, writeProfileCreds, } from './config.js';
|
|
11
|
+
import { CONFIG_PATHS, DEFAULT_ENVIRONMENT, ENVIRONMENTS, clearProfileCreds, getProfileName, readProfileConfig, resolveProfile, writeProfileConfig, writeProfileCreds, } from './config.js';
|
|
12
|
+
const ENVIRONMENT_NAMES = Object.keys(ENVIRONMENTS);
|
|
12
13
|
// ---------------------------------------------------------------------------
|
|
13
14
|
// Helpers
|
|
14
15
|
// ---------------------------------------------------------------------------
|
|
@@ -123,18 +124,47 @@ program
|
|
|
123
124
|
.description('Alvera platform CLI')
|
|
124
125
|
.version(packageVersion, '-v, --version', 'print the installed version')
|
|
125
126
|
.addOption(new Option('--profile <name>', 'config profile to use').default('default'))
|
|
126
|
-
.
|
|
127
|
+
.addOption(new Option('--env <name>', `environment from spec/openapi.yaml (${ENVIRONMENT_NAMES.join(', ')})`))
|
|
128
|
+
.showHelpAfterError()
|
|
129
|
+
.hook('preAction', (thisCommand) => {
|
|
130
|
+
const env = thisCommand.optsWithGlobals().env;
|
|
131
|
+
if (env !== undefined)
|
|
132
|
+
process.env.ALVERA_ENV = env;
|
|
133
|
+
const candidate = process.env.ALVERA_ENV;
|
|
134
|
+
if (candidate !== undefined && !ENVIRONMENT_NAMES.includes(candidate)) {
|
|
135
|
+
die(`unknown environment "${candidate}". Valid: ${ENVIRONMENT_NAMES.join(', ')}`);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
127
138
|
// -- configure --------------------------------------------------------------
|
|
128
139
|
program
|
|
129
140
|
.command('configure')
|
|
130
|
-
.description('Interactively set defaults (
|
|
141
|
+
.description('Interactively set defaults (environment, tenant, email) for a profile')
|
|
131
142
|
.action(async () => {
|
|
132
143
|
const profile = getProfileName(program.opts().profile);
|
|
133
144
|
const current = resolveProfile(profile);
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
145
|
+
const currentCfg = readProfileConfig(profile);
|
|
146
|
+
const options = ENVIRONMENT_NAMES.map((name) => `${name} (${ENVIRONMENTS[name].base_url})`).join(', ');
|
|
147
|
+
const defaultChoice = currentCfg.environment ?? current.environment;
|
|
148
|
+
const envInput = (await prompt(`Environment [${defaultChoice}] — one of: ${options}, or a custom URL: `)) ||
|
|
149
|
+
defaultChoice;
|
|
150
|
+
const patch = {};
|
|
151
|
+
const unset = [];
|
|
152
|
+
if (ENVIRONMENT_NAMES.includes(envInput)) {
|
|
153
|
+
patch.environment = envInput;
|
|
154
|
+
unset.push('base_url');
|
|
155
|
+
}
|
|
156
|
+
else if (/^https?:\/\//.test(envInput)) {
|
|
157
|
+
patch.base_url = envInput;
|
|
158
|
+
unset.push('environment');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
die(`"${envInput}" is not a known environment or a URL. ` +
|
|
162
|
+
`Valid: ${ENVIRONMENT_NAMES.join(', ')} or http(s)://…`);
|
|
163
|
+
}
|
|
164
|
+
patch.tenant_slug =
|
|
165
|
+
(await prompt(`Default tenant slug [${current.tenantSlug ?? ''}]: `)) || current.tenantSlug || '';
|
|
166
|
+
patch.email = (await prompt(`Email [${current.email ?? ''}]: `)) || current.email || '';
|
|
167
|
+
writeProfileConfig(profile, patch, unset);
|
|
138
168
|
process.stderr.write(`Saved profile "${profile}" → ${CONFIG_PATHS.config}\n`);
|
|
139
169
|
});
|
|
140
170
|
// -- login ------------------------------------------------------------------
|
|
@@ -163,7 +193,13 @@ program
|
|
|
163
193
|
tenantSlug: tenant,
|
|
164
194
|
expiresIn: opts.expiresIn ? Number(opts.expiresIn) : undefined,
|
|
165
195
|
});
|
|
166
|
-
|
|
196
|
+
// Only pin base_url into the profile when the user explicitly overrode it.
|
|
197
|
+
// Otherwise the environment selection (profile.environment) keeps driving baseUrl.
|
|
198
|
+
writeProfileConfig(profile, {
|
|
199
|
+
...(opts.baseUrl ? { base_url: baseUrl } : {}),
|
|
200
|
+
tenant_slug: tenant,
|
|
201
|
+
email,
|
|
202
|
+
});
|
|
167
203
|
writeProfileCreds(profile, {
|
|
168
204
|
session_token: session.sessionToken,
|
|
169
205
|
expires_at: session.expiresAt ?? '',
|
|
@@ -202,6 +238,7 @@ program
|
|
|
202
238
|
const resolved = resolveProfile(profile);
|
|
203
239
|
out({
|
|
204
240
|
profile: resolved.profile,
|
|
241
|
+
environment: resolved.environment,
|
|
205
242
|
baseUrl: resolved.baseUrl,
|
|
206
243
|
tenantSlug: resolved.tenantSlug,
|
|
207
244
|
email: resolved.email,
|
|
@@ -220,6 +257,38 @@ program
|
|
|
220
257
|
return data;
|
|
221
258
|
});
|
|
222
259
|
});
|
|
260
|
+
// -- env --------------------------------------------------------------------
|
|
261
|
+
// Environments are baked from spec/openapi.yaml servers[] at build time.
|
|
262
|
+
// Default (prod / or last-in-list) is chosen in scripts/gen-environments.mjs.
|
|
263
|
+
const envCmd = program
|
|
264
|
+
.command('env')
|
|
265
|
+
.description('List and switch Alvera API environments');
|
|
266
|
+
envCmd
|
|
267
|
+
.command('list')
|
|
268
|
+
.description('List available environments (from spec/openapi.yaml)')
|
|
269
|
+
.action(() => {
|
|
270
|
+
const profile = getProfileName(program.opts().profile);
|
|
271
|
+
const resolved = resolveProfile(profile);
|
|
272
|
+
out(ENVIRONMENT_NAMES.map((name) => ({
|
|
273
|
+
name,
|
|
274
|
+
baseUrl: ENVIRONMENTS[name].base_url,
|
|
275
|
+
description: ENVIRONMENTS[name].description,
|
|
276
|
+
default: name === DEFAULT_ENVIRONMENT,
|
|
277
|
+
active: name === resolved.environment,
|
|
278
|
+
})));
|
|
279
|
+
});
|
|
280
|
+
envCmd
|
|
281
|
+
.command('use <name>')
|
|
282
|
+
.description('Persist the selected environment to the profile (clears any custom base_url)')
|
|
283
|
+
.action((name) => {
|
|
284
|
+
if (!ENVIRONMENT_NAMES.includes(name)) {
|
|
285
|
+
die(`unknown environment "${name}". Valid: ${ENVIRONMENT_NAMES.join(', ')}`);
|
|
286
|
+
}
|
|
287
|
+
const profile = getProfileName(program.opts().profile);
|
|
288
|
+
writeProfileConfig(profile, { environment: name }, ['base_url']);
|
|
289
|
+
process.stderr.write(`Profile "${profile}" now uses environment "${name}" ` +
|
|
290
|
+
`(${ENVIRONMENTS[name].base_url}).\n`);
|
|
291
|
+
});
|
|
223
292
|
// -- tenants ----------------------------------------------------------------
|
|
224
293
|
const tenants = program.command('tenants').description('Manage tenants');
|
|
225
294
|
tenants
|
|
@@ -540,22 +609,109 @@ bodyOption(connectedApps
|
|
|
540
609
|
});
|
|
541
610
|
});
|
|
542
611
|
// -- data-activation-clients -----------------------------------------------
|
|
543
|
-
const dac = program.command('data-activation-clients').description('
|
|
544
|
-
|
|
545
|
-
.
|
|
612
|
+
const dac = program.command('data-activation-clients').description('Manage data activation clients');
|
|
613
|
+
dac
|
|
614
|
+
.command('list <datalake> [tenant]')
|
|
615
|
+
.description('List data activation clients in a datalake')
|
|
616
|
+
.action(async (datalake, tenant) => {
|
|
617
|
+
await run(async () => {
|
|
618
|
+
const { api, resolved } = authedApi(program.opts());
|
|
619
|
+
const { data } = await api.dataActivationClients.list(resolveTenant(tenant, resolved.tenantSlug), datalake);
|
|
620
|
+
return data;
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
dac
|
|
624
|
+
.command('get <datalake> <slug> [tenant]')
|
|
625
|
+
.description('Get a data activation client by slug')
|
|
626
|
+
.action(async (datalake, slug, tenant) => {
|
|
627
|
+
await run(async () => {
|
|
628
|
+
const { api, resolved } = authedApi(program.opts());
|
|
629
|
+
const { data } = await api.dataActivationClients.get(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
630
|
+
return data;
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
bodyOption(dac.command('create <datalake> [tenant]').description('Create a data activation client'))
|
|
634
|
+
.action(async (datalake, tenant, opts) => {
|
|
635
|
+
await run(async () => {
|
|
636
|
+
const { api, resolved } = authedApi(program.opts());
|
|
637
|
+
const { data } = await api.dataActivationClients.create(resolveTenant(tenant, resolved.tenantSlug), datalake, readBody(opts.body, opts.bodyFile));
|
|
638
|
+
return data;
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
bodyOption(dac.command('update <datalake> <slug> [tenant]').description('Update a data activation client'))
|
|
642
|
+
.action(async (datalake, slug, tenant, opts) => {
|
|
643
|
+
await run(async () => {
|
|
644
|
+
const { api, resolved } = authedApi(program.opts());
|
|
645
|
+
const { data } = await api.dataActivationClients.update(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, readBody(opts.body, opts.bodyFile));
|
|
646
|
+
return data;
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
dac
|
|
650
|
+
.command('delete <datalake> <slug> [tenant]')
|
|
651
|
+
.description('Delete a data activation client')
|
|
652
|
+
.action(async (datalake, slug, tenant) => {
|
|
546
653
|
await run(async () => {
|
|
547
654
|
const { api, resolved } = authedApi(program.opts());
|
|
548
|
-
const { data } = await api.dataActivationClients.
|
|
655
|
+
const { data } = await api.dataActivationClients.delete(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
549
656
|
return data;
|
|
550
657
|
});
|
|
551
658
|
});
|
|
552
659
|
dac
|
|
553
|
-
.command('
|
|
660
|
+
.command('metadata <datalake> <slug> [tenant]')
|
|
661
|
+
.description('Get markdown metadata for a data activation client')
|
|
662
|
+
.action(async (datalake, slug, tenant) => {
|
|
663
|
+
await run(async () => {
|
|
664
|
+
const { api, resolved } = authedApi(program.opts());
|
|
665
|
+
const { data } = await api.dataActivationClients.metadata(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
666
|
+
return data;
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
bodyOption(dac
|
|
670
|
+
.command('run-manually <datalake> <slug> [tenant]')
|
|
671
|
+
.description('Trigger a manual run (optional --body for tool_call override)'))
|
|
672
|
+
.action(async (datalake, slug, tenant, opts) => {
|
|
673
|
+
await run(async () => {
|
|
674
|
+
const { api, resolved } = authedApi(program.opts());
|
|
675
|
+
const body = opts.body || opts.bodyFile ? readBody(opts.body, opts.bodyFile) : undefined;
|
|
676
|
+
const { data } = await api.dataActivationClients.runManually(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, body);
|
|
677
|
+
return data;
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
bodyOption(dac.command('ingest <datalake> <slug> [tenant]').description('Ingest a JSON payload'))
|
|
681
|
+
.action(async (datalake, slug, tenant, opts) => {
|
|
682
|
+
await run(async () => {
|
|
683
|
+
const { api, resolved } = authedApi(program.opts());
|
|
684
|
+
const { data } = await api.dataActivationClients.ingest(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, readBody(opts.body, opts.bodyFile));
|
|
685
|
+
return data;
|
|
686
|
+
});
|
|
687
|
+
});
|
|
688
|
+
dac
|
|
689
|
+
.command('ingest-file <datalake> <slug> <key> [tenant]')
|
|
554
690
|
.description('Ingest a previously uploaded file (key from upload-link)')
|
|
555
|
-
.action(async (slug, key, tenant) => {
|
|
691
|
+
.action(async (datalake, slug, key, tenant) => {
|
|
692
|
+
await run(async () => {
|
|
693
|
+
const { api, resolved } = authedApi(program.opts());
|
|
694
|
+
const { data } = await api.dataActivationClients.ingestFile(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, { key });
|
|
695
|
+
return data;
|
|
696
|
+
});
|
|
697
|
+
});
|
|
698
|
+
dac
|
|
699
|
+
.command('logs <datalake> <slug> [tenant]')
|
|
700
|
+
.description('List execution logs for a data activation client')
|
|
701
|
+
.action(async (datalake, slug, tenant) => {
|
|
556
702
|
await run(async () => {
|
|
557
703
|
const { api, resolved } = authedApi(program.opts());
|
|
558
|
-
const { data } = await api.dataActivationClients.
|
|
704
|
+
const { data } = await api.dataActivationClients.logs.list(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
705
|
+
return data;
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
dac
|
|
709
|
+
.command('log-get <datalake> <slug> <id> [tenant]')
|
|
710
|
+
.description('Get a single execution log by id')
|
|
711
|
+
.action(async (datalake, slug, id, tenant) => {
|
|
712
|
+
await run(async () => {
|
|
713
|
+
const { api, resolved } = authedApi(program.opts());
|
|
714
|
+
const { data } = await api.dataActivationClients.logs.get(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, id);
|
|
559
715
|
return data;
|
|
560
716
|
});
|
|
561
717
|
});
|
|
@@ -575,6 +731,16 @@ datalakes
|
|
|
575
731
|
return data;
|
|
576
732
|
});
|
|
577
733
|
});
|
|
734
|
+
datalakes
|
|
735
|
+
.command('download-link <datalake> <bucket> <key> [tenant]')
|
|
736
|
+
.description('Create a presigned download URL for a datalake object')
|
|
737
|
+
.action(async (datalake, bucket, key, tenant) => {
|
|
738
|
+
await run(async () => {
|
|
739
|
+
const { api, resolved } = authedApi(program.opts());
|
|
740
|
+
const { data } = await api.datalakes.createDownloadLink(resolveTenant(tenant, resolved.tenantSlug), datalake, { bucket, key });
|
|
741
|
+
return data;
|
|
742
|
+
});
|
|
743
|
+
});
|
|
578
744
|
// -- mdm --------------------------------------------------------------------
|
|
579
745
|
const mdm = program.command('mdm').description('Master data management');
|
|
580
746
|
bodyOption(mdm.command('verify <datalake> [tenant]').description('Fuzzy-verify an identity against MDM'))
|
|
@@ -585,8 +751,161 @@ bodyOption(mdm.command('verify <datalake> [tenant]').description('Fuzzy-verify a
|
|
|
585
751
|
return data;
|
|
586
752
|
});
|
|
587
753
|
});
|
|
754
|
+
// -- datalakes metadata + datasets metadata --------------------------------
|
|
755
|
+
datalakes
|
|
756
|
+
.command('metadata <datalake> [tenant]')
|
|
757
|
+
.description('Get markdown metadata for a datalake')
|
|
758
|
+
.action(async (datalake, tenant) => {
|
|
759
|
+
await run(async () => {
|
|
760
|
+
const { api, resolved } = authedApi(program.opts());
|
|
761
|
+
const { data } = await api.datalakes.metadata(resolveTenant(tenant, resolved.tenantSlug), datalake);
|
|
762
|
+
return data;
|
|
763
|
+
});
|
|
764
|
+
});
|
|
765
|
+
datasets
|
|
766
|
+
.command('metadata <dataset-type>')
|
|
767
|
+
.description('Get markdown schema metadata for a dataset type')
|
|
768
|
+
.option('--datalake-id <id>', 'restrict to a specific datalake')
|
|
769
|
+
.option('--generic-table-id <id>', 'required when dataset-type is generic_table')
|
|
770
|
+
.action(async (datasetType, opts) => {
|
|
771
|
+
await run(async () => {
|
|
772
|
+
const { api } = authedApi(program.opts());
|
|
773
|
+
const { data } = await api.datasets.metadata(datasetType, {
|
|
774
|
+
datalakeId: opts.datalakeId,
|
|
775
|
+
genericTableId: opts.genericTableId,
|
|
776
|
+
});
|
|
777
|
+
return data;
|
|
778
|
+
});
|
|
779
|
+
});
|
|
780
|
+
// -- interoperability-contracts --------------------------------------------
|
|
781
|
+
const interop = program
|
|
782
|
+
.command('interoperability-contracts')
|
|
783
|
+
.alias('interop')
|
|
784
|
+
.description('Manage interoperability contracts');
|
|
785
|
+
interop
|
|
786
|
+
.command('list <datalake> [tenant]')
|
|
787
|
+
.description('List interoperability contracts in a datalake')
|
|
788
|
+
.action(async (datalake, tenant) => {
|
|
789
|
+
await run(async () => {
|
|
790
|
+
const { api, resolved } = authedApi(program.opts());
|
|
791
|
+
const { data } = await api.interoperabilityContracts.list(resolveTenant(tenant, resolved.tenantSlug), datalake);
|
|
792
|
+
return data;
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
interop
|
|
796
|
+
.command('get <datalake> <slug> [tenant]')
|
|
797
|
+
.description('Get a contract by slug')
|
|
798
|
+
.action(async (datalake, slug, tenant) => {
|
|
799
|
+
await run(async () => {
|
|
800
|
+
const { api, resolved } = authedApi(program.opts());
|
|
801
|
+
const { data } = await api.interoperabilityContracts.get(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
802
|
+
return data;
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
bodyOption(interop.command('create <datalake> [tenant]').description('Create a contract'))
|
|
806
|
+
.action(async (datalake, tenant, opts) => {
|
|
807
|
+
await run(async () => {
|
|
808
|
+
const { api, resolved } = authedApi(program.opts());
|
|
809
|
+
const { data } = await api.interoperabilityContracts.create(resolveTenant(tenant, resolved.tenantSlug), datalake, readBody(opts.body, opts.bodyFile));
|
|
810
|
+
return data;
|
|
811
|
+
});
|
|
812
|
+
});
|
|
813
|
+
bodyOption(interop.command('update <datalake> <slug> [tenant]').description('Update a contract'))
|
|
814
|
+
.action(async (datalake, slug, tenant, opts) => {
|
|
815
|
+
await run(async () => {
|
|
816
|
+
const { api, resolved } = authedApi(program.opts());
|
|
817
|
+
const { data } = await api.interoperabilityContracts.update(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, readBody(opts.body, opts.bodyFile));
|
|
818
|
+
return data;
|
|
819
|
+
});
|
|
820
|
+
});
|
|
821
|
+
interop
|
|
822
|
+
.command('delete <datalake> <slug> [tenant]')
|
|
823
|
+
.description('Delete a contract')
|
|
824
|
+
.action(async (datalake, slug, tenant) => {
|
|
825
|
+
await run(async () => {
|
|
826
|
+
const { api, resolved } = authedApi(program.opts());
|
|
827
|
+
const { data } = await api.interoperabilityContracts.delete(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
828
|
+
return data;
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
interop
|
|
832
|
+
.command('metadata <datalake> <slug> [tenant]')
|
|
833
|
+
.description('Get markdown metadata for a contract')
|
|
834
|
+
.action(async (datalake, slug, tenant) => {
|
|
835
|
+
await run(async () => {
|
|
836
|
+
const { api, resolved } = authedApi(program.opts());
|
|
837
|
+
const { data } = await api.interoperabilityContracts.metadata(resolveTenant(tenant, resolved.tenantSlug), datalake, slug);
|
|
838
|
+
return data;
|
|
839
|
+
});
|
|
840
|
+
});
|
|
841
|
+
bodyOption(interop
|
|
842
|
+
.command('run <datalake> <slug> [tenant]')
|
|
843
|
+
.description('Execute a contract against a raw source row'))
|
|
844
|
+
.action(async (datalake, slug, tenant, opts) => {
|
|
845
|
+
await run(async () => {
|
|
846
|
+
const { api, resolved } = authedApi(program.opts());
|
|
847
|
+
const { data } = await api.interoperabilityContracts.run(resolveTenant(tenant, resolved.tenantSlug), datalake, slug, readBody(opts.body, opts.bodyFile));
|
|
848
|
+
return data;
|
|
849
|
+
});
|
|
850
|
+
});
|
|
588
851
|
// -- workflows --------------------------------------------------------------
|
|
589
852
|
const workflows = program.command('workflows').description('Agentic workflows');
|
|
853
|
+
workflows
|
|
854
|
+
.command('list <datalake> [tenant]')
|
|
855
|
+
.description('List workflow definitions in a datalake')
|
|
856
|
+
.action(async (datalake, tenant) => {
|
|
857
|
+
await run(async () => {
|
|
858
|
+
const { api, resolved } = authedApi(program.opts());
|
|
859
|
+
const { data } = await api.workflows.list(resolveTenant(tenant, resolved.tenantSlug), datalake);
|
|
860
|
+
return data;
|
|
861
|
+
});
|
|
862
|
+
});
|
|
863
|
+
workflows
|
|
864
|
+
.command('get <datalake> <id> [tenant]')
|
|
865
|
+
.description('Get a workflow by id')
|
|
866
|
+
.action(async (datalake, id, tenant) => {
|
|
867
|
+
await run(async () => {
|
|
868
|
+
const { api, resolved } = authedApi(program.opts());
|
|
869
|
+
const { data } = await api.workflows.get(resolveTenant(tenant, resolved.tenantSlug), datalake, id);
|
|
870
|
+
return data;
|
|
871
|
+
});
|
|
872
|
+
});
|
|
873
|
+
bodyOption(workflows.command('create <datalake> [tenant]').description('Create a workflow'))
|
|
874
|
+
.action(async (datalake, tenant, opts) => {
|
|
875
|
+
await run(async () => {
|
|
876
|
+
const { api, resolved } = authedApi(program.opts());
|
|
877
|
+
const { data } = await api.workflows.create(resolveTenant(tenant, resolved.tenantSlug), datalake, readBody(opts.body, opts.bodyFile));
|
|
878
|
+
return data;
|
|
879
|
+
});
|
|
880
|
+
});
|
|
881
|
+
bodyOption(workflows.command('update <datalake> <id> [tenant]').description('Update a workflow'))
|
|
882
|
+
.action(async (datalake, id, tenant, opts) => {
|
|
883
|
+
await run(async () => {
|
|
884
|
+
const { api, resolved } = authedApi(program.opts());
|
|
885
|
+
const { data } = await api.workflows.update(resolveTenant(tenant, resolved.tenantSlug), datalake, id, readBody(opts.body, opts.bodyFile));
|
|
886
|
+
return data;
|
|
887
|
+
});
|
|
888
|
+
});
|
|
889
|
+
workflows
|
|
890
|
+
.command('delete <datalake> <id> [tenant]')
|
|
891
|
+
.description('Delete a workflow')
|
|
892
|
+
.action(async (datalake, id, tenant) => {
|
|
893
|
+
await run(async () => {
|
|
894
|
+
const { api, resolved } = authedApi(program.opts());
|
|
895
|
+
const { data } = await api.workflows.delete(resolveTenant(tenant, resolved.tenantSlug), datalake, id);
|
|
896
|
+
return data;
|
|
897
|
+
});
|
|
898
|
+
});
|
|
899
|
+
workflows
|
|
900
|
+
.command('metadata <datalake> <id> [tenant]')
|
|
901
|
+
.description('Get markdown metadata for a workflow')
|
|
902
|
+
.action(async (datalake, id, tenant) => {
|
|
903
|
+
await run(async () => {
|
|
904
|
+
const { api, resolved } = authedApi(program.opts());
|
|
905
|
+
const { data } = await api.workflows.metadata(resolveTenant(tenant, resolved.tenantSlug), datalake, id);
|
|
906
|
+
return data;
|
|
907
|
+
});
|
|
908
|
+
});
|
|
590
909
|
bodyOption(workflows.command('execute <workflow-slug> [tenant]').description('Execute an agentic workflow'))
|
|
591
910
|
.action(async (workflowSlug, tenant, opts) => {
|
|
592
911
|
await run(async () => {
|
|
@@ -595,5 +914,95 @@ bodyOption(workflows.command('execute <workflow-slug> [tenant]').description('Ex
|
|
|
595
914
|
return data;
|
|
596
915
|
});
|
|
597
916
|
});
|
|
917
|
+
bodyOption(workflows
|
|
918
|
+
.command('run <workflow-slug> [tenant]')
|
|
919
|
+
.description('Run a workflow across records matched by a SQL WHERE clause'))
|
|
920
|
+
.action(async (workflowSlug, tenant, opts) => {
|
|
921
|
+
await run(async () => {
|
|
922
|
+
const { api, resolved } = authedApi(program.opts());
|
|
923
|
+
const { data } = await api.workflows.run(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, readBody(opts.body, opts.bodyFile));
|
|
924
|
+
return data;
|
|
925
|
+
});
|
|
926
|
+
});
|
|
927
|
+
workflows
|
|
928
|
+
.command('batch-logs <workflow-slug> [tenant]')
|
|
929
|
+
.description('List batch logs for a workflow')
|
|
930
|
+
.action(async (workflowSlug, tenant) => {
|
|
931
|
+
await run(async () => {
|
|
932
|
+
const { api, resolved } = authedApi(program.opts());
|
|
933
|
+
const { data } = await api.workflows.batchLogs.list(resolveTenant(tenant, resolved.tenantSlug), workflowSlug);
|
|
934
|
+
return data;
|
|
935
|
+
});
|
|
936
|
+
});
|
|
937
|
+
workflows
|
|
938
|
+
.command('batch-log <workflow-slug> <id> [tenant]')
|
|
939
|
+
.description('Get a single batch log by id')
|
|
940
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
941
|
+
await run(async () => {
|
|
942
|
+
const { api, resolved } = authedApi(program.opts());
|
|
943
|
+
const { data } = await api.workflows.batchLogs.get(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
944
|
+
return data;
|
|
945
|
+
});
|
|
946
|
+
});
|
|
947
|
+
workflows
|
|
948
|
+
.command('batch-log-start <workflow-slug> <id> [tenant]')
|
|
949
|
+
.description('Start polling a batch log')
|
|
950
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
951
|
+
await run(async () => {
|
|
952
|
+
const { api, resolved } = authedApi(program.opts());
|
|
953
|
+
const { data } = await api.workflows.batchLogs.start(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
954
|
+
return data;
|
|
955
|
+
});
|
|
956
|
+
});
|
|
957
|
+
workflows
|
|
958
|
+
.command('batch-log-stop <workflow-slug> <id> [tenant]')
|
|
959
|
+
.description('Stop polling a batch log')
|
|
960
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
961
|
+
await run(async () => {
|
|
962
|
+
const { api, resolved } = authedApi(program.opts());
|
|
963
|
+
const { data } = await api.workflows.batchLogs.stop(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
964
|
+
return data;
|
|
965
|
+
});
|
|
966
|
+
});
|
|
967
|
+
workflows
|
|
968
|
+
.command('batch-log-refresh <workflow-slug> <id> [tenant]')
|
|
969
|
+
.description('Force-refresh a batch log')
|
|
970
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
971
|
+
await run(async () => {
|
|
972
|
+
const { api, resolved } = authedApi(program.opts());
|
|
973
|
+
const { data } = await api.workflows.batchLogs.refresh(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
974
|
+
return data;
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
workflows
|
|
978
|
+
.command('workflow-logs <workflow-slug> [tenant]')
|
|
979
|
+
.description('List execution logs for a workflow')
|
|
980
|
+
.action(async (workflowSlug, tenant) => {
|
|
981
|
+
await run(async () => {
|
|
982
|
+
const { api, resolved } = authedApi(program.opts());
|
|
983
|
+
const { data } = await api.workflows.workflowLogs.list(resolveTenant(tenant, resolved.tenantSlug), workflowSlug);
|
|
984
|
+
return data;
|
|
985
|
+
});
|
|
986
|
+
});
|
|
987
|
+
workflows
|
|
988
|
+
.command('workflow-log <workflow-slug> <id> [tenant]')
|
|
989
|
+
.description('Get a single execution log by id')
|
|
990
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
991
|
+
await run(async () => {
|
|
992
|
+
const { api, resolved } = authedApi(program.opts());
|
|
993
|
+
const { data } = await api.workflows.workflowLogs.get(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
994
|
+
return data;
|
|
995
|
+
});
|
|
996
|
+
});
|
|
997
|
+
workflows
|
|
998
|
+
.command('workflow-log-download <workflow-slug> <id> [tenant]')
|
|
999
|
+
.description('Get a presigned download URL for an execution log')
|
|
1000
|
+
.action(async (workflowSlug, id, tenant) => {
|
|
1001
|
+
await run(async () => {
|
|
1002
|
+
const { api, resolved } = authedApi(program.opts());
|
|
1003
|
+
const { data } = await api.workflows.workflowLogs.download(resolveTenant(tenant, resolved.tenantSlug), workflowSlug, id);
|
|
1004
|
+
return data;
|
|
1005
|
+
});
|
|
1006
|
+
});
|
|
598
1007
|
program.parseAsync();
|
|
599
1008
|
//# sourceMappingURL=cli.js.map
|