@permute/sdk 0.8.0 → 0.9.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 CHANGED
@@ -20,6 +20,10 @@ bunx @permute/sdk auth logout
20
20
 
21
21
  Choose an organization, optionally limit the connection to one workspace, then select resources and permissions to approve in Permute. The CLI stores renewable credentials in your operating system’s credential store (no plaintext fallback). Active logins have no fixed maximum lifetime and expire after 30 days without renewal; company sign-in rules can require earlier authentication. Logging out revokes access before removing the local credential. Signing in again revokes the previous stored CLI session.
22
22
 
23
+ The SDK reuses credentials in memory between requests and reloads the OS store before renewal or when another process changes the saved login. The local auth directory holds only a lock and a non-secret change marker; tokens stay out of ordinary files. Current server permissions and revocation still apply to every request.
24
+
25
+ The CLI prints the issuer and `permute-cli` entry name to stderr before accessing the OS store. macOS controls its own permission dialog, which may identify the Node or Bun process. SDK applications stay silent by default and can supply `onCredentialStoreAccess: (issuer) => { /* show a notice */ }` to `OAuthLogin`; the callback runs once before the default OS store is accessed and receives no credentials.
26
+
23
27
  ```ts
24
28
  import { OAuthLogin } from '@permute/sdk/auth';
25
29
 
@@ -321,10 +325,8 @@ const dataset = await client.datasets.create({
321
325
  context: [Context.QUICKBOOKS],
322
326
  });
323
327
 
324
- await dataset.replace({
325
- orders: [{ id: 1 }, { id: 2 }],
326
- customers: [{ id: 10 }],
327
- });
328
+ await dataset.replaceTable('orders', [{ id: 1 }, { id: 2 }]);
329
+ await dataset.replaceTable('customers', [{ id: 10 }]);
328
330
 
329
331
  console.log(dataset.sourceId, dataset.version, dataset.data.tables);
330
332
  ```
@@ -333,15 +335,30 @@ Dataset `context` accepts string identifiers, with `Context` providing named
333
335
  constants for known contexts (such as `Context.QUICKBOOKS`). It is not restricted
334
336
  to the connector provider list. Use `Providers` when selecting a connector.
335
337
 
336
- `replace()` sends the complete dataset snapshot. Tables omitted from the call
337
- are removed, while tables with the same name keep their stable identity for
338
- reports and dashboards. Retrying an identical replacement is a no-op.
338
+ ### Add or replace one table
339
339
 
340
- Use `replaceTable()` when the supplied rows are the complete current contents
341
- of one table. Existing rows not supplied are removed; other tables are unchanged:
340
+ Use `replaceTable()` to add a new named table or replace the complete contents
341
+ of an existing table. Existing rows not supplied are removed; other tables stay
342
+ in the dataset. Await each write before starting the next write to that dataset:
342
343
 
343
344
  ```ts
344
345
  await dataset.replaceTable('orders', allOrders);
346
+ await dataset.replaceTable('customers', allCustomers);
347
+ // Both tables now belong to the same dataset.
348
+ ```
349
+
350
+ ### Replace the complete snapshot or append new rows
351
+
352
+ `replace()` sends the complete dataset snapshot. Tables omitted from the call
353
+ are removed, while tables with the same name keep their stable identity for
354
+ reports and dashboards. Retrying an identical replacement is a no-op:
355
+
356
+ ```ts
357
+ await dataset.replace({
358
+ orders: [{ id: 1 }, { id: 2 }],
359
+ customers: [{ id: 10 }],
360
+ });
361
+ // Only orders and customers remain in this dataset.
345
362
  ```
346
363
 
347
364
  Use `appendTable()` only when every supplied row is new and previously written
@@ -359,14 +376,68 @@ and use a new value for a new append. It prevents a retried request from being
359
376
  applied twice; reusing it with different rows fails. It does not remove duplicate
360
377
  rows sent in different batches.
361
378
 
362
- When source records can change or disappear, collect the source's current rows
363
- and use `replaceTable()` instead. The SDK serializes custom writes as chunked
364
- NDJSON, uploads them directly to a signed S3 target, and waits for processing;
365
- it does not build Parquet locally. The REST upload supports up to 1,000 tables and
366
- 1 GB, but the current SDK object helper encodes the supplied rows in memory, so
367
- callers should stay comfortably within their process memory. `appendTable()`
368
- accepts up to 10,000 rows per batch. Durable SDK operations stop polling after
369
- 20 minutes by default; pass `pollTimeoutMs` to set a different bound.
379
+ ### Upload a local CSV
380
+
381
+ With SDK 0.9.0 or later, pass a disk-backed Blob to the same `replaceTable()` method.
382
+ Use Node.js 24 or later with `openAsBlob`; the SDK hashes the file in small blocks,
383
+ uploads it to S3, and waits for processing without loading the whole file into
384
+ memory:
385
+
386
+ ```ts
387
+ import { openAsBlob } from 'node:fs';
388
+
389
+ await dataset.replaceTable('customers', await openAsBlob('./customers.csv'), {
390
+ format: 'csv',
391
+ });
392
+ ```
393
+
394
+ Supply comma-separated UTF-8 CSV with unique, nonempty column names in its first row.
395
+ Permute derives the row count and infers column types; an optional `rowCount`
396
+ checks an expected count. Keep the local file unchanged until its upload finishes.
397
+ Header-only CSV can create an empty table.
398
+
399
+ ### Upload a gzipped CSV
400
+
401
+ Pass an existing CSV.gz file with `compression: 'gzip'`. The SDK sends the file
402
+ as-is (it does not gzip a plain CSV when you set the option). Unpack ZIP archives
403
+ before importing individual table files:
404
+
405
+ ```ts
406
+ await dataset.replaceTable('order_history', await openAsBlob('./order_history.csv.gz'), {
407
+ format: 'csv',
408
+ compression: 'gzip',
409
+ });
410
+ ```
411
+
412
+ ### Import a large export
413
+
414
+ The row-array overload still serializes objects as NDJSON and holds both the
415
+ rows and encoded upload in memory. Use the Blob overload for large CSV exports.
416
+
417
+ Each uploaded file can be at most 5 GiB (5,368,709,120 bytes), with at most 10 GiB
418
+ (10,737,418,240 bytes) after decompression. The upload limit measures compressed
419
+ bytes when using gzip. Raw REST NDJSON writes also accept `compression: 'gzip'`;
420
+ `sizeBytes` and `contentHash` describe the exact uploaded bytes. Each complete
421
+ table replacement can contain at most 10,000,000 rows. A full `replace()` accepts
422
+ up to 1,000 tables within that same upload limit. The byte limit is per write,
423
+ so separate table writes can accumulate several GB in one dataset. Table-by-table
424
+ imports become visible as each write completes; they are not an atomic snapshot
425
+ of the whole export. New empty NDJSON tables require an existing schema.
426
+
427
+ For CSV exports with hundreds of tables, await each `replaceTable()` call while
428
+ reusing the same dataset key. Use a different key for each separate source export.
429
+ The guide includes [folder imports](https://permute.ai/docs/guides/custom-dataset#folder-of-tables),
430
+ [multiple datasets](https://permute.ai/docs/guides/custom-dataset#multiple-datasets), and
431
+ [signed REST uploads](https://permute.ai/docs/guides/custom-dataset#csv-export-to-s3).
432
+ Validate imported column names, counts, and types before loading the full export.
433
+ These limits apply to custom table writes; `type: 'file'` creates a separate file
434
+ dataset with its own upload limits.
435
+
436
+ `appendTable()` accepts up to 10,000 rows per batch. Repeated small appends are
437
+ inefficient for a large snapshot; upload its complete CSV with `replaceTable()`.
438
+ Durable SDK operations stop polling after 20 minutes by default; pass
439
+ `pollTimeoutMs` to change the client wait. A polling timeout does not prove the
440
+ server write failed; inspect its status before retrying.
370
441
 
371
442
  ## Recommended Flow
372
443
 
@@ -8,6 +8,8 @@ export interface OAuthOptions {
8
8
  apiUrl?: string;
9
9
  store?: CredentialStore;
10
10
  fetch?: typeof fetch;
11
+ /** Called once before the default OS credential store is accessed; no tokens are passed. */
12
+ onCredentialStoreAccess?: (issuer: string) => void;
11
13
  }
12
14
  export declare class OAuthLogin {
13
15
  readonly issuer: string;
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { createHash, randomBytes } from 'node:crypto';
3
3
  import { setTimeout } from 'node:timers/promises';
4
4
  import { PermuteClient } from '../client.js';
5
- import { SystemCredentialStore } from './store.js';
5
+ import { TOKEN_REFRESH_BUFFER_MS, SystemCredentialStore, } from './store.js';
6
6
  export { SystemCredentialStore } from './store.js';
7
7
  export const DEFAULT_ISSUER = 'https://auth.permute.ai';
8
8
  const CLIENT_ID = 'permute-cli';
@@ -30,7 +30,7 @@ export class OAuthLogin {
30
30
  constructor(options = {}) {
31
31
  this.issuer = this.endpoint(options.issuer ?? DEFAULT_ISSUER);
32
32
  this.apiUrl = this.endpoint(options.apiUrl ?? 'https://api.permute.ai');
33
- this.store = options.store ?? new SystemCredentialStore(this.issuer);
33
+ this.store = options.store ?? new SystemCredentialStore(this.issuer, options.onCredentialStoreAccess);
34
34
  this.fetchImpl = options.fetch ?? fetch;
35
35
  }
36
36
  endpoint(value) {
@@ -65,7 +65,7 @@ export class OAuthLogin {
65
65
  throw new Error('Invalid credential response');
66
66
  return parsed.data;
67
67
  }
68
- async persist(tokens) {
68
+ async persist(tokens, previous) {
69
69
  const credentials = {
70
70
  issuer: this.issuer,
71
71
  apiUrl: this.apiUrl,
@@ -77,9 +77,9 @@ export class OAuthLogin {
77
77
  expiresAt: Date.now() + tokens.expires_in * 1000,
78
78
  };
79
79
  try {
80
- const previous = await this.store.read();
81
- if (previous && previous.sessionId !== tokens.session_id)
82
- await this.revoke(previous.refresh);
80
+ const existing = previous ?? (await this.store.read());
81
+ if (existing && existing.sessionId !== tokens.session_id)
82
+ await this.revoke(existing.refresh);
83
83
  await this.store.write(credentials);
84
84
  }
85
85
  catch (error) {
@@ -172,14 +172,14 @@ export class OAuthLogin {
172
172
  const current = await this.store.read();
173
173
  if (!current || current.apiUrl !== this.apiUrl)
174
174
  throw new Error('No login for this server. Run permute auth login.');
175
- if (current.expiresAt > Date.now() + 60_000)
175
+ if (current.expiresAt > Date.now() + TOKEN_REFRESH_BUFFER_MS)
176
176
  return current;
177
177
  const tokens = this.tokens(await this.post('/token', {
178
178
  client_id: CLIENT_ID,
179
179
  grant_type: 'refresh_token',
180
180
  refresh_token: current.refresh,
181
181
  }));
182
- return this.persist(tokens);
182
+ return this.persist(tokens, current);
183
183
  });
184
184
  }
185
185
  async client() {
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ export declare const TOKEN_REFRESH_BUFFER_MS = 60000;
2
3
  declare const LoginCredentialsSchema: z.ZodObject<{
3
4
  issuer: z.ZodString;
4
5
  apiUrl: z.ZodString;
@@ -16,11 +17,16 @@ export interface CredentialStore {
16
17
  remove(): Promise<void>;
17
18
  exclusive<T>(run: () => Promise<T>): Promise<T>;
18
19
  }
19
- /** Tokens never fall back to a plaintext file. The disk lock contains no credentials. */
20
+ /** Credentials are cached in memory only; disk holds a lock and a non-secret change marker. */
20
21
  export declare class SystemCredentialStore implements CredentialStore {
21
22
  private readonly issuer;
23
+ private readonly onAccess?;
22
24
  private readonly account;
23
- constructor(issuer: string);
25
+ private readonly directory;
26
+ private readonly revisionPath;
27
+ private cached?;
28
+ private announced;
29
+ constructor(issuer: string, onAccess?: ((issuer: string) => void) | undefined);
24
30
  private entry;
25
31
  read(): Promise<{
26
32
  issuer: string;
@@ -32,8 +38,10 @@ export declare class SystemCredentialStore implements CredentialStore {
32
38
  refresh: string;
33
39
  expiresAt: number;
34
40
  } | null>;
41
+ private validate;
35
42
  write(value: LoginCredentials): Promise<void>;
36
43
  remove(): Promise<void>;
44
+ private markChanged;
37
45
  exclusive<T>(run: () => Promise<T>): Promise<T>;
38
46
  }
39
47
  export {};
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { createHash } from 'node:crypto';
2
+ import { createHash, randomUUID } from 'node:crypto';
3
3
  import { homedir } from 'node:os';
4
4
  import { join } from 'node:path';
5
- import { mkdir, rm } from 'node:fs/promises';
5
+ import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
6
6
  import { setTimeout } from 'node:timers/promises';
7
+ export const TOKEN_REFRESH_BUFFER_MS = 60_000;
7
8
  const LoginCredentialsSchema = z.object({
8
9
  issuer: z.string().url(),
9
10
  apiUrl: z.string().url(),
@@ -14,39 +15,74 @@ const LoginCredentialsSchema = z.object({
14
15
  refresh: z.string().min(1),
15
16
  expiresAt: z.number().finite(),
16
17
  });
17
- /** Tokens never fall back to a plaintext file. The disk lock contains no credentials. */
18
+ /** Credentials are cached in memory only; disk holds a lock and a non-secret change marker. */
18
19
  export class SystemCredentialStore {
19
20
  issuer;
21
+ onAccess;
20
22
  account;
21
- constructor(issuer) {
23
+ directory = join(homedir(), '.config', 'permute', 'auth');
24
+ revisionPath;
25
+ cached;
26
+ announced = false;
27
+ constructor(issuer, onAccess) {
22
28
  this.issuer = issuer;
29
+ this.onAccess = onAccess;
23
30
  this.account = createHash('sha256').update(issuer).digest('hex');
31
+ this.revisionPath = join(this.directory, `${this.account}.revision`);
24
32
  }
25
33
  async entry() {
26
34
  const { AsyncEntry } = await import('@napi-rs/keyring');
35
+ if (!this.announced) {
36
+ this.onAccess?.(this.issuer);
37
+ this.announced = true;
38
+ }
27
39
  return new AsyncEntry('permute-cli', this.account, { linux: { store: 'secret-service' } });
28
40
  }
29
41
  async read() {
42
+ const revision = await readFile(this.revisionPath, 'utf8').catch((error) => {
43
+ if (error.code === 'ENOENT')
44
+ return null;
45
+ throw error;
46
+ });
47
+ if (this.cached?.revision === revision && this.cached.value.expiresAt > Date.now() + TOKEN_REFRESH_BUFFER_MS)
48
+ return { ...this.cached.value };
49
+ this.cached = undefined;
30
50
  const value = await (await this.entry()).getPassword();
31
51
  if (!value)
32
52
  return null;
33
- const parsed = LoginCredentialsSchema.safeParse(JSON.parse(value));
53
+ const credentials = this.validate(JSON.parse(value));
54
+ this.cached = { revision, value: credentials };
55
+ return { ...credentials };
56
+ }
57
+ validate(value) {
58
+ const parsed = LoginCredentialsSchema.safeParse(value);
34
59
  if (!parsed.success || parsed.data.issuer !== this.issuer)
35
60
  throw new Error('Stored login is invalid. Run permute auth login again.');
36
61
  return parsed.data;
37
62
  }
38
63
  async write(value) {
39
- await (await this.entry()).setPassword(JSON.stringify(value));
64
+ const credentials = this.validate(value);
65
+ this.cached = undefined;
66
+ await (await this.entry()).setPassword(JSON.stringify(credentials));
67
+ const revision = await this.markChanged();
68
+ this.cached = { revision, value: credentials };
40
69
  }
41
70
  async remove() {
71
+ this.cached = undefined;
42
72
  const entry = await this.entry();
43
73
  if (await entry.getPassword())
44
74
  await entry.deletePassword();
75
+ await this.markChanged();
76
+ }
77
+ async markChanged() {
78
+ await mkdir(this.directory, { recursive: true, mode: 0o700 });
79
+ const revision = randomUUID();
80
+ await writeFile(this.revisionPath, revision, { mode: 0o600 });
81
+ return revision;
45
82
  }
46
83
  async exclusive(run) {
47
- const directory = join(homedir(), '.config', 'permute', 'auth');
48
- await mkdir(directory, { recursive: true, mode: 0o700 });
49
- const lock = join(directory, `${this.account}.lock`);
84
+ await mkdir(this.directory, { recursive: true, mode: 0o700 });
85
+ const lock = join(this.directory, `${this.account}.lock`);
50
86
  const deadline = Date.now() + 30_000;
51
87
  while (true) {
52
88
  const acquired = await mkdir(lock, { mode: 0o700 }).then(() => true, (error) => {
package/dist/cli.js CHANGED
@@ -90,7 +90,14 @@ export async function runCli(args = process.argv.slice(2)) {
90
90
  }
91
91
  if (!!values.issuer !== !!values['api-url'])
92
92
  throw new Error('Provide both --issuer and --api-url for another environment.');
93
- const login = new OAuthLogin({ issuer: values.issuer, apiUrl: values['api-url'] });
93
+ const login = new OAuthLogin({
94
+ issuer: values.issuer,
95
+ apiUrl: values['api-url'],
96
+ onCredentialStoreAccess: (issuer) => {
97
+ const store = process.platform === 'darwin' ? 'macOS Keychain' : 'your OS credential store';
98
+ console.error(`Permute CLI is accessing ${store} for ${issuer} (entry: permute-cli).`);
99
+ },
100
+ });
94
101
  if (command === 'logout') {
95
102
  await login.logout();
96
103
  console.log('CLI login revoked and removed from this device.');
package/dist/client.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { EmailSender, EmailSendRequest, EmailReceipt, PermissionGrant, PermissionGrantInput, PermissionGrantUpdate, PermissionGrantQuery, PermissionGrantList, PermissionGrantRevoked, PermissionInspectionInput, PermissionInspection, AccessRequest, AccessRequestInput, AccessRequestQuery, AccessRequestList, AccessRequestDecision } from './types.js';
2
2
  export { PermuteApiError } from './errors.js';
3
3
  import type { BusinessAction, BusinessActionDetail, BusinessActionList, ActionCreateRequest, ActionDefinition, ActionDefinitionSaveRequest, ActionDefinitionSaved, ActionRequest, ActionReceipt, ActionPublicationRequest, ActionPublicationRequestInput, ActionPublicationRequestList, ActionPublicationDecision } from './types.js';
4
- import type { ConnectorSession, ConnectorSessionCreated, ConnectorSessionCreateRequest, Database, AppPublicationRequest, AppPublicationRequestInput, AppPublicationRequestList, AppPublicationDecision, AppDraft, AppAccess, AppAddressSettings, AppAddressSetRequest, AppAccessSetRequest, AppDraftList, AppCreateRequest, AppUpdateRequest, AppDeleted, AppUploadsRequest, AppUploads, AppSiteSaveRequest, AppSourceFileQuery, AppSourceFileContent, AppGrants, AppGrantSetRequest, AppUploadFile, DatabaseList, DatabaseCreateRequest, DatabaseDefinition, DatabaseDefinitionSaveRequest, DatabaseDefinitionSaved, DatabaseTables, DatabaseTableCreateRequest, DatabaseTableCreated, DatabaseRecords, DatabaseRecordsQuery, DatabaseTransactionRequest, DatabaseTransactionReceipt, WriteSync, WriteSyncCreateRequest, WriteSyncUpdateRequest, WriteSyncDetail, WriteSyncList, WriteSyncDeleted, WriteSyncDestinations, WriteSyncRun, WriteSyncRunList, WriteSyncRunQuery, WriteSyncExecution, ResourceVersionState, ResourceRevisionList, ResourceRevision, ResourceVersionRequest, ResourcePublishRequest, Fact, FactList, FactWriteRequest, SkillList, SkillContent, SkillWriteRequest, KnowledgeWriteResponse, OperationRunGroup, OperationRunQuery, Operation, OperationList, OperationListQuery, OperationSource, OperationSourceUpdateRequest, OperationUpdateRequest, OperationRunRequest, OperationRunStarted, OperationRunList, OperationRunOutput, DataFlow, DataFlowCreateRequest, DataFlowCommandRequest, DataFlowCommandResponse, Workspace, WorkspaceCreateRequest, WorkspaceDeleteResponse, WorkspaceList, WorkspaceUpdateRequest, AnswerRequest, AnswerResponse, PermuteClientOptions, PermuteRequestOptions, QueryRequest, SearchRequest, SourceDetail, CatalogTable, SourceList, CustomDatasetCreateRequest, DatasetDeleteResponse, DatasetResponse, FileDatasetCreateRequest, FileDatasetMetadataCreateRequest, FileDatasetResponse, DatasetRows, CustomDatasetResponse, DashboardSource, DashboardSourceUpdateRequest } from './types.js';
4
+ import type { ConnectorSession, ConnectorSessionCreated, ConnectorSessionCreateRequest, Database, AppPublicationRequest, AppPublicationRequestInput, AppPublicationRequestList, AppPublicationDecision, AppDraft, AppAccess, AppAddressSettings, AppAddressSetRequest, AppAccessSetRequest, AppDraftList, AppCreateRequest, AppUpdateRequest, AppDeleted, AppUploadsRequest, AppUploads, AppSiteSaveRequest, AppSourceFileQuery, AppSourceFileContent, AppGrants, AppGrantSetRequest, AppUploadFile, DatabaseList, DatabaseCreateRequest, DatabaseDefinition, DatabaseDefinitionSaveRequest, DatabaseDefinitionSaved, DatabaseTables, DatabaseTableCreateRequest, DatabaseTableCreated, DatabaseRecords, DatabaseRecordsQuery, DatabaseTransactionRequest, DatabaseTransactionReceipt, WriteSync, WriteSyncCreateRequest, WriteSyncUpdateRequest, WriteSyncDetail, WriteSyncList, WriteSyncDeleted, WriteSyncDestinations, WriteSyncRun, WriteSyncRunList, WriteSyncRunQuery, WriteSyncExecution, ResourceVersionState, ResourceRevisionList, ResourceRevision, ResourceVersionRequest, ResourcePublishRequest, Fact, FactList, FactWriteRequest, SkillList, SkillContent, SkillWriteRequest, KnowledgeWriteResponse, OperationRunGroup, OperationRunQuery, Operation, OperationList, OperationListQuery, OperationSource, OperationSourceUpdateRequest, OperationUpdateRequest, OperationRunRequest, OperationRunStarted, OperationRunList, OperationRunOutput, DataFlow, DataFlowCreateRequest, DataFlowCommandRequest, DataFlowCommandResponse, Workspace, WorkspaceCreateRequest, WorkspaceDeleteResponse, WorkspaceList, WorkspaceUpdateRequest, AnswerRequest, AnswerResponse, PermuteClientOptions, PermuteRequestOptions, QueryRequest, SearchRequest, SourceDetail, CatalogTable, SourceList, CustomDatasetCreateRequest, DatasetDeleteResponse, DatasetResponse, FileDatasetCreateRequest, FileDatasetMetadataCreateRequest, FileDatasetResponse, DatasetRows, DatasetCsvUploadOptions, CustomDatasetResponse, DashboardSource, DashboardSourceUpdateRequest } from './types.js';
5
5
  type DatasetWriteInput = {
6
6
  tables: Record<string, DatasetRows>;
7
7
  mode: 'replace';
@@ -14,7 +14,11 @@ type DatasetWriteInput = {
14
14
  rows: DatasetRows;
15
15
  batchId: string;
16
16
  mode: 'appendTable';
17
- };
17
+ } | ({
18
+ tableName: string;
19
+ file: Blob;
20
+ mode: 'replaceTable';
21
+ } & DatasetCsvUploadOptions);
18
22
  type DatasetWriter = (id: string, request: DatasetWriteInput, options?: PermuteRequestOptions) => Promise<CustomDatasetResponse>;
19
23
  type DatasetReader = (id: string, options?: PermuteRequestOptions) => Promise<DatasetResponse>;
20
24
  export declare class PermuteDataset {
@@ -33,6 +37,7 @@ export declare class PermuteDataset {
33
37
  get version(): number;
34
38
  replace(tables: Record<string, DatasetRows>, options?: PermuteRequestOptions): Promise<this>;
35
39
  replaceTable(tableName: string, rows: DatasetRows, options?: PermuteRequestOptions): Promise<this>;
40
+ replaceTable(tableName: string, file: Blob, options: DatasetCsvUploadOptions & PermuteRequestOptions): Promise<this>;
36
41
  appendTable(tableName: string, rows: DatasetRows, options: {
37
42
  batchId: string;
38
43
  } & PermuteRequestOptions): Promise<this>;
package/dist/client.js CHANGED
@@ -93,12 +93,45 @@ function inferUploadSize(data) {
93
93
  return undefined;
94
94
  }
95
95
  const DATASET_WRITE_CHUNK_ROWS = 500;
96
+ const DATASET_WRITE_CHUNK_BYTES = 16 * 1024 * 1024;
97
+ async function hashDatasetFile(file, signal) {
98
+ const hash = createHash('sha256');
99
+ const reader = file.stream().getReader();
100
+ try {
101
+ while (true) {
102
+ if (signal?.aborted) {
103
+ await reader.cancel();
104
+ throw new PermuteApiError({ status: 0, code: 'request_aborted', message: 'Request was aborted' });
105
+ }
106
+ const { done, value } = await reader.read();
107
+ if (done)
108
+ return hash.digest('hex');
109
+ hash.update(value);
110
+ }
111
+ }
112
+ finally {
113
+ reader.releaseLock();
114
+ }
115
+ }
96
116
  function encodeDatasetWrite(request) {
97
117
  const entries = request.mode === 'replace' ? Object.entries(request.tables) : [[request.tableName, request.rows]];
98
118
  const parts = [];
99
119
  const hash = createHash('sha256');
100
120
  const addChunk = (tableName, rows) => {
101
121
  const line = `${JSON.stringify({ tableName, rows })}\n`;
122
+ if (new TextEncoder().encode(line).byteLength > DATASET_WRITE_CHUNK_BYTES) {
123
+ if (rows.length <= 1) {
124
+ throw new PermuteApiError({
125
+ status: 0,
126
+ code: 'dataset_row_too_large',
127
+ message: 'A dataset row exceeds the 16 MiB upload chunk limit',
128
+ });
129
+ }
130
+ const middle = Math.floor(rows.length / 2);
131
+ addChunk(tableName, rows.slice(0, middle));
132
+ addChunk(tableName, rows.slice(middle));
133
+ return;
134
+ }
102
135
  parts.push(line);
103
136
  hash.update(line);
104
137
  };
@@ -113,7 +146,6 @@ function encodeDatasetWrite(request) {
113
146
  return {
114
147
  data,
115
148
  contentHash: hash.digest('hex'),
116
- tables: entries.map(([name, rows]) => ({ name, rowCount: rows.length })),
117
149
  };
118
150
  }
119
151
  function pollingDeadline(options) {
@@ -208,8 +240,20 @@ export class PermuteDataset {
208
240
  this.snapshot = await this.writeTables(this.id, { tables, mode: 'replace' }, options);
209
241
  return this;
210
242
  }
211
- async replaceTable(tableName, rows, options) {
212
- this.snapshot = await this.writeTables(this.id, { tableName, rows, mode: 'replaceTable' }, options);
243
+ async replaceTable(tableName, data, options) {
244
+ if (data instanceof Blob) {
245
+ if (!options || !('format' in options)) {
246
+ throw new PermuteApiError({
247
+ status: 0,
248
+ code: 'invalid_upload_format',
249
+ message: 'CSV file uploads require format: csv',
250
+ });
251
+ }
252
+ const { format, compression, rowCount, ...requestOptions } = options;
253
+ this.snapshot = await this.writeTables(this.id, { tableName, file: data, mode: 'replaceTable', format, compression, rowCount }, requestOptions);
254
+ return this;
255
+ }
256
+ this.snapshot = await this.writeTables(this.id, { tableName, rows: data, mode: 'replaceTable' }, options);
213
257
  return this;
214
258
  }
215
259
  async appendTable(tableName, rows, options) {
@@ -475,30 +519,39 @@ export class PermuteClient {
475
519
  };
476
520
  const readDataset = this.bindMethod('datasetsGet', (apiRequest) => (datasetId, requestOptions) => apiRequest({ pathParams: { datasetId } }, requestOptions));
477
521
  const writeDatasetTables = async (datasetId, request, requestOptions) => {
478
- const encoded = encodeDatasetWrite(request);
479
- const body = request.mode === 'replace'
522
+ const encoded = 'file' in request
523
+ ? { data: request.file, contentHash: await hashDatasetFile(request.file, requestOptions?.signal) }
524
+ : encodeDatasetWrite(request);
525
+ const uploadMetadata = { sizeBytes: encoded.data.size, contentHash: encoded.contentHash };
526
+ const body = 'file' in request
480
527
  ? {
481
- mode: request.mode,
482
- tables: encoded.tables,
483
- sizeBytes: encoded.data.size,
484
- contentHash: encoded.contentHash,
528
+ mode: 'replaceTable',
529
+ tableName: request.tableName,
530
+ format: request.format,
531
+ compression: request.compression,
532
+ rowCount: request.rowCount,
533
+ ...uploadMetadata,
485
534
  }
486
- : request.mode === 'replaceTable'
535
+ : request.mode === 'replace'
487
536
  ? {
488
537
  mode: request.mode,
489
- tableName: request.tableName,
490
- rowCount: request.rows.length,
491
- sizeBytes: encoded.data.size,
492
- contentHash: encoded.contentHash,
538
+ tables: Object.entries(request.tables).map(([name, rows]) => ({ name, rowCount: rows.length })),
539
+ ...uploadMetadata,
493
540
  }
494
- : {
495
- mode: request.mode,
496
- tableName: request.tableName,
497
- rowCount: request.rows.length,
498
- sizeBytes: encoded.data.size,
499
- contentHash: encoded.contentHash,
500
- batchId: request.batchId,
501
- };
541
+ : request.mode === 'replaceTable'
542
+ ? {
543
+ mode: request.mode,
544
+ tableName: request.tableName,
545
+ rowCount: request.rows.length,
546
+ ...uploadMetadata,
547
+ }
548
+ : {
549
+ mode: request.mode,
550
+ tableName: request.tableName,
551
+ rowCount: request.rows.length,
552
+ ...uploadMetadata,
553
+ batchId: request.batchId,
554
+ };
502
555
  const initialized = await this.request('datasetsWriteTables', { pathParams: { datasetId }, body }, requestOptions);
503
556
  if (initialized.write.status === 'completed')
504
557
  return initialized.dataset;
@@ -1404,8 +1404,12 @@ export interface components {
1404
1404
  status: 'pending' | 'processing' | 'completed' | 'failed';
1405
1405
  };
1406
1406
  DatasetWriteTablesRequest: {
1407
+ /** @enum {string} */
1408
+ compression?: 'gzip';
1407
1409
  contentHash: string;
1408
1410
  /** @enum {string} */
1411
+ format?: 'ndjson';
1412
+ /** @enum {string} */
1409
1413
  mode: 'replace';
1410
1414
  sizeBytes: number;
1411
1415
  tables: {
@@ -1413,16 +1417,35 @@ export interface components {
1413
1417
  rowCount: number;
1414
1418
  }[];
1415
1419
  } | {
1420
+ /** @enum {string} */
1421
+ compression?: 'gzip';
1416
1422
  contentHash: string;
1417
1423
  /** @enum {string} */
1424
+ format?: 'ndjson';
1425
+ /** @enum {string} */
1418
1426
  mode: 'replaceTable';
1419
1427
  rowCount: number;
1420
1428
  sizeBytes: number;
1421
1429
  tableName: string;
1430
+ } | {
1431
+ /** @enum {string} */
1432
+ compression?: 'gzip';
1433
+ contentHash: string;
1434
+ /** @enum {string} */
1435
+ format: 'csv';
1436
+ /** @enum {string} */
1437
+ mode: 'replaceTable';
1438
+ rowCount?: number;
1439
+ sizeBytes: number;
1440
+ tableName: string;
1422
1441
  } | {
1423
1442
  batchId: string;
1443
+ /** @enum {string} */
1444
+ compression?: 'gzip';
1424
1445
  contentHash: string;
1425
1446
  /** @enum {string} */
1447
+ format?: 'ndjson';
1448
+ /** @enum {string} */
1426
1449
  mode: 'appendTable';
1427
1450
  rowCount: number;
1428
1451
  sizeBytes: number;
@@ -1783,6 +1806,12 @@ export interface components {
1783
1806
  dataFlowRevision: number | null;
1784
1807
  dataSourceIds: string[];
1785
1808
  dependencyOperationIds: string[];
1809
+ incremental: {
1810
+ inputColumns: string[];
1811
+ keyColumns: string[];
1812
+ sourceId: string;
1813
+ table: string;
1814
+ } | null;
1786
1815
  instructions: string;
1787
1816
  operationId: string;
1788
1817
  revision: {
@@ -1801,6 +1830,12 @@ export interface components {
1801
1830
  } | null;
1802
1831
  /** Format: date-time */
1803
1832
  expectedUpdatedAt: string;
1833
+ incremental?: {
1834
+ inputColumns: string[];
1835
+ keyColumns: string[];
1836
+ sourceId: string;
1837
+ table: string;
1838
+ } | null;
1804
1839
  source: string;
1805
1840
  };
1806
1841
  OperationUpdateRequest: {
@@ -48,7 +48,7 @@ export const publicApiRoutes = {
48
48
  "datasetsGet": { "operationId": "datasetsGet", "method": "GET", "path": "/v1/datasets/{datasetId}", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "oneOf": [{ "type": "object", "properties": { "type": { "type": "string", "enum": ["custom"] }, "id": { "type": "string" }, "sourceId": { "type": "string" }, "key": { "type": "string" }, "name": { "type": "string" }, "context": { "type": "array", "items": { "type": "string" } }, "status": { "type": "string", "enum": ["pending", "uploaded", "processing", "completed", "failed"] }, "version": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "tables": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "columnCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["name", "rowCount", "columnCount"], "additionalProperties": false } }, "write": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "processing", "completed", "failed"] }, "error": { "type": "string" } }, "required": ["id", "status"], "additionalProperties": false }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["type", "id", "sourceId", "key", "name", "context", "status", "version", "tables", "createdAt", "updatedAt"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["file"] }, "id": { "type": "string" }, "sourceId": { "type": "string" }, "name": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "uploaded", "processing", "completed", "failed"] }, "contentType": { "type": "string" }, "sizeBytes": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "progress": { "type": "object", "properties": { "percent": { "type": "number", "minimum": 0, "maximum": 100 }, "step": { "type": "string" }, "stepLabel": { "type": "string" }, "details": { "type": "string" } }, "required": ["percent"], "additionalProperties": false }, "error": { "type": "string" }, "upload": { "type": "object", "properties": { "method": { "type": "string", "enum": ["PUT"] }, "url": { "type": "string", "format": "uri" }, "headers": { "type": "object", "additionalProperties": { "type": "string" } }, "expiresAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["method", "url", "headers", "expiresAt"], "additionalProperties": false } }, "required": ["type", "id", "sourceId", "name", "status", "contentType", "sizeBytes", "createdAt", "updatedAt"], "additionalProperties": false }] } },
49
49
  "datasetsDelete": { "operationId": "datasetsDelete", "method": "DELETE", "path": "/v1/datasets/{datasetId}", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "id": { "type": "string" }, "deleted": { "type": "boolean", "enum": [true] } }, "required": ["id", "deleted"], "additionalProperties": false } },
50
50
  "datasetsDownload": { "operationId": "datasetsDownload", "method": "GET", "path": "/v1/datasets/{datasetId}/download", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "url": { "type": "string", "format": "uri" } }, "required": ["url"], "additionalProperties": false } },
51
- "datasetsWriteTables": { "operationId": "datasetsWriteTables", "method": "POST", "path": "/v1/datasets/{datasetId}/tables", "scope": "workspace", "bodySchema": { "oneOf": [{ "type": "object", "properties": { "tables": { "maxItems": 1000, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 10000000 } }, "required": ["name", "rowCount"], "additionalProperties": false } }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 1073741824 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "mode": { "type": "string", "enum": ["replace"] } }, "required": ["tables", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }, { "type": "object", "properties": { "tableName": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 10000000 }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 1073741824 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "mode": { "type": "string", "enum": ["replaceTable"] } }, "required": ["tableName", "rowCount", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }, { "type": "object", "properties": { "tableName": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 1, "maximum": 10000 }, "batchId": { "type": "string", "minLength": 1, "maxLength": 128 }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 1073741824 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "mode": { "type": "string", "enum": ["appendTable"] } }, "required": ["tableName", "rowCount", "batchId", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }] }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "dataset": { "type": "object", "properties": { "type": { "type": "string", "enum": ["custom"] }, "id": { "type": "string" }, "sourceId": { "type": "string" }, "key": { "type": "string" }, "name": { "type": "string" }, "context": { "type": "array", "items": { "type": "string" } }, "status": { "type": "string", "enum": ["pending", "uploaded", "processing", "completed", "failed"] }, "version": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "tables": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "columnCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["name", "rowCount", "columnCount"], "additionalProperties": false } }, "write": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "processing", "completed", "failed"] }, "error": { "type": "string" } }, "required": ["id", "status"], "additionalProperties": false }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["type", "id", "sourceId", "key", "name", "context", "status", "version", "tables", "createdAt", "updatedAt"], "additionalProperties": false }, "write": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "processing", "completed", "failed"] }, "error": { "type": "string" } }, "required": ["id", "status"], "additionalProperties": false }, "upload": { "type": "object", "properties": { "method": { "type": "string", "enum": ["PUT"] }, "url": { "type": "string", "format": "uri" }, "headers": { "type": "object", "additionalProperties": { "type": "string" } }, "expiresAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["method", "url", "headers", "expiresAt"], "additionalProperties": false }, "pollAfterMs": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["dataset", "write", "pollAfterMs"], "additionalProperties": false } },
51
+ "datasetsWriteTables": { "operationId": "datasetsWriteTables", "method": "POST", "path": "/v1/datasets/{datasetId}/tables", "scope": "workspace", "bodySchema": { "anyOf": [{ "type": "object", "properties": { "tables": { "maxItems": 1000, "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 10000000 } }, "required": ["name", "rowCount"], "additionalProperties": false } }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 5368709120 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "format": { "type": "string", "enum": ["ndjson"] }, "compression": { "type": "string", "enum": ["gzip"] }, "mode": { "type": "string", "enum": ["replace"] } }, "required": ["tables", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }, { "type": "object", "properties": { "tableName": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 10000000 }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 5368709120 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "format": { "type": "string", "enum": ["ndjson"] }, "compression": { "type": "string", "enum": ["gzip"] }, "mode": { "type": "string", "enum": ["replaceTable"] } }, "required": ["tableName", "rowCount", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }, { "type": "object", "properties": { "tableName": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 10000000 }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 5368709120 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "format": { "type": "string", "enum": ["csv"] }, "compression": { "type": "string", "enum": ["gzip"] }, "mode": { "type": "string", "enum": ["replaceTable"] } }, "required": ["tableName", "sizeBytes", "contentHash", "format", "mode"], "additionalProperties": false }, { "type": "object", "properties": { "tableName": { "type": "string", "minLength": 1, "maxLength": 128 }, "rowCount": { "type": "integer", "minimum": 1, "maximum": 10000 }, "batchId": { "type": "string", "minLength": 1, "maxLength": 128 }, "sizeBytes": { "type": "integer", "minimum": 0, "maximum": 5368709120 }, "contentHash": { "type": "string", "pattern": "^[a-f0-9]{64}$" }, "format": { "type": "string", "enum": ["ndjson"] }, "compression": { "type": "string", "enum": ["gzip"] }, "mode": { "type": "string", "enum": ["appendTable"] } }, "required": ["tableName", "rowCount", "batchId", "sizeBytes", "contentHash", "mode"], "additionalProperties": false }] }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "dataset": { "type": "object", "properties": { "type": { "type": "string", "enum": ["custom"] }, "id": { "type": "string" }, "sourceId": { "type": "string" }, "key": { "type": "string" }, "name": { "type": "string" }, "context": { "type": "array", "items": { "type": "string" } }, "status": { "type": "string", "enum": ["pending", "uploaded", "processing", "completed", "failed"] }, "version": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "tables": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "rowCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "columnCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 } }, "required": ["name", "rowCount", "columnCount"], "additionalProperties": false } }, "write": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "processing", "completed", "failed"] }, "error": { "type": "string" } }, "required": ["id", "status"], "additionalProperties": false }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["type", "id", "sourceId", "key", "name", "context", "status", "version", "tables", "createdAt", "updatedAt"], "additionalProperties": false }, "write": { "type": "object", "properties": { "id": { "type": "string" }, "status": { "type": "string", "enum": ["pending", "processing", "completed", "failed"] }, "error": { "type": "string" } }, "required": ["id", "status"], "additionalProperties": false }, "upload": { "type": "object", "properties": { "method": { "type": "string", "enum": ["PUT"] }, "url": { "type": "string", "format": "uri" }, "headers": { "type": "object", "additionalProperties": { "type": "string" } }, "expiresAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["method", "url", "headers", "expiresAt"], "additionalProperties": false }, "pollAfterMs": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["dataset", "write", "pollAfterMs"], "additionalProperties": false } },
52
52
  "searchCreate": { "operationId": "searchCreate", "method": "POST", "path": "/v1/search", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "query": { "type": "string", "minLength": 1 }, "sourceIds": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } }, "types": { "type": "array", "items": { "type": "string", "enum": ["records", "documents", "tables", "text_blocks"] } }, "limit": { "type": "integer", "minimum": 1, "maximum": 50 }, "rerank": { "type": "boolean" } }, "required": ["query"], "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["record", "document", "table", "text_block", "unknown"] }, "sourceId": { "type": "string" }, "title": { "type": "string" }, "content": { "type": "string" }, "score": { "type": "number" }, "citation": { "type": "object", "additionalProperties": {} }, "metadata": { "type": "object", "additionalProperties": {} } }, "required": ["type", "content"], "additionalProperties": false } }, "meta": { "type": "object", "properties": { "strategy": { "type": "string", "enum": ["semantic"] }, "reranked": { "type": "boolean" }, "candidateCount": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "totalMs": { "type": "number", "minimum": 0 } }, "required": ["strategy", "reranked"], "additionalProperties": false } }, "required": ["items", "meta"], "additionalProperties": false } },
53
53
  "answerJobsCreate": { "operationId": "answerJobsCreate", "method": "POST", "path": "/v1/answer-jobs", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "question": { "type": "string", "minLength": 1 }, "sourceIds": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": ["question"], "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "answerJobId": { "type": "string" }, "status": { "type": "string", "enum": ["queued", "running", "completed", "failed", "cancelled"] }, "result": { "type": "object", "properties": { "answer": { "type": "string" }, "citations": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["text", "table", "web", "fact"] }, "sourceId": { "type": "string" }, "ref": { "type": "string" }, "title": { "type": "string" }, "url": { "type": "string" }, "metadata": { "type": "object", "additionalProperties": {} } }, "required": ["type"], "additionalProperties": false } }, "assumptions": { "type": "array", "items": { "type": "object", "additionalProperties": {} } }, "charts": { "type": "array", "items": { "type": "object", "additionalProperties": {} } }, "followUps": { "type": "array", "items": { "type": "string" } }, "confidence": { "type": "object", "properties": { "score": { "type": "number", "minimum": 0, "maximum": 100 }, "queryComplexity": { "type": "string", "enum": ["high", "medium", "low"] }, "reason": { "type": "string" } }, "required": ["score", "queryComplexity", "reason"], "additionalProperties": false } }, "required": ["answer", "citations"], "additionalProperties": false }, "error": { "type": "string" }, "pollAfterMs": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "startedAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "completedAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["answerJobId", "status"], "additionalProperties": false } },
54
54
  "answerJobsGet": { "operationId": "answerJobsGet", "method": "GET", "path": "/v1/answer-jobs/{answerJobId}", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "answerJobId": { "type": "string" }, "status": { "type": "string", "enum": ["queued", "running", "completed", "failed", "cancelled"] }, "result": { "type": "object", "properties": { "answer": { "type": "string" }, "citations": { "type": "array", "items": { "type": "object", "properties": { "type": { "type": "string", "enum": ["text", "table", "web", "fact"] }, "sourceId": { "type": "string" }, "ref": { "type": "string" }, "title": { "type": "string" }, "url": { "type": "string" }, "metadata": { "type": "object", "additionalProperties": {} } }, "required": ["type"], "additionalProperties": false } }, "assumptions": { "type": "array", "items": { "type": "object", "additionalProperties": {} } }, "charts": { "type": "array", "items": { "type": "object", "additionalProperties": {} } }, "followUps": { "type": "array", "items": { "type": "string" } }, "confidence": { "type": "object", "properties": { "score": { "type": "number", "minimum": 0, "maximum": 100 }, "queryComplexity": { "type": "string", "enum": ["high", "medium", "low"] }, "reason": { "type": "string" } }, "required": ["score", "queryComplexity", "reason"], "additionalProperties": false } }, "required": ["answer", "citations"], "additionalProperties": false }, "error": { "type": "string" }, "pollAfterMs": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "startedAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "completedAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["answerJobId", "status"], "additionalProperties": false } },
@@ -57,8 +57,8 @@ export const publicApiRoutes = {
57
57
  "operationsList": { "operationId": "operationsList", "method": "GET", "path": "/v1/operations", "scope": "workspace", "bodySchema": null, "querySchema": { "type": "object", "properties": { "kind": { "type": "string", "enum": ["dataFlow", "dataTable", "report", "dashboard"] }, "dataFlowId": { "type": "string", "minLength": 1 } }, "required": [], "additionalProperties": false }, "responseSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "kind": { "type": "string" }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "parentDataFlowId": { "nullable": true, "type": "string" }, "status": { "type": "string" }, "codeStale": { "type": "boolean" }, "schedule": { "anyOf": [{ "oneOf": [{ "type": "object", "properties": { "type": { "type": "string", "enum": ["manual"] } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["hourly"] }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["daily"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "hour", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["weekly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfWeek": { "type": "number", "minimum": 0, "maximum": 6 } }, "required": ["type", "hour", "minute", "dayOfWeek"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["monthly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfMonth": { "type": "number", "minimum": 1, "maximum": 31 } }, "required": ["type", "hour", "minute", "dayOfMonth"], "additionalProperties": false }] }, { "type": "object", "nullable": true, "enum": [null] }] }, "isEnabled": { "type": "boolean" }, "nextRunAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "draft": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "published": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false } }, "required": ["id", "name", "kind", "instructions", "dataSourceIds", "parentDataFlowId", "status", "codeStale", "schedule", "isEnabled", "nextRunAt", "draft", "published"], "additionalProperties": false } } }, "required": ["items"], "additionalProperties": false } },
58
58
  "operationsGet": { "operationId": "operationsGet", "method": "GET", "path": "/v1/operations/{operationId}", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "kind": { "type": "string" }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "parentDataFlowId": { "nullable": true, "type": "string" }, "status": { "type": "string" }, "codeStale": { "type": "boolean" }, "schedule": { "anyOf": [{ "oneOf": [{ "type": "object", "properties": { "type": { "type": "string", "enum": ["manual"] } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["hourly"] }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["daily"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "hour", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["weekly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfWeek": { "type": "number", "minimum": 0, "maximum": 6 } }, "required": ["type", "hour", "minute", "dayOfWeek"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["monthly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfMonth": { "type": "number", "minimum": 1, "maximum": 31 } }, "required": ["type", "hour", "minute", "dayOfMonth"], "additionalProperties": false }] }, { "type": "object", "nullable": true, "enum": [null] }] }, "isEnabled": { "type": "boolean" }, "nextRunAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "draft": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "published": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false } }, "required": ["id", "name", "kind", "instructions", "dataSourceIds", "parentDataFlowId", "status", "codeStale", "schedule", "isEnabled", "nextRunAt", "draft", "published"], "additionalProperties": false } },
59
59
  "operationsUpdate": { "operationId": "operationsUpdate", "method": "PATCH", "path": "/v1/operations/{operationId}", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "schedule": { "anyOf": [{ "oneOf": [{ "type": "object", "properties": { "type": { "type": "string", "enum": ["manual"] } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["hourly"] }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["daily"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "hour", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["weekly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfWeek": { "type": "number", "minimum": 0, "maximum": 6 } }, "required": ["type", "hour", "minute", "dayOfWeek"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["monthly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfMonth": { "type": "number", "minimum": 1, "maximum": 31 } }, "required": ["type", "hour", "minute", "dayOfMonth"], "additionalProperties": false }] }, { "type": "object", "nullable": true, "enum": [null] }] }, "isEnabled": { "type": "boolean" } }, "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "kind": { "type": "string" }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "parentDataFlowId": { "nullable": true, "type": "string" }, "status": { "type": "string" }, "codeStale": { "type": "boolean" }, "schedule": { "anyOf": [{ "oneOf": [{ "type": "object", "properties": { "type": { "type": "string", "enum": ["manual"] } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["hourly"] }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["daily"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 } }, "required": ["type", "hour", "minute"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["weekly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfWeek": { "type": "number", "minimum": 0, "maximum": 6 } }, "required": ["type", "hour", "minute", "dayOfWeek"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "enum": ["monthly"] }, "hour": { "type": "number", "minimum": 0, "maximum": 23 }, "minute": { "type": "number", "minimum": 0, "maximum": 59 }, "dayOfMonth": { "type": "number", "minimum": 1, "maximum": 31 } }, "required": ["type", "hour", "minute", "dayOfMonth"], "additionalProperties": false }] }, { "type": "object", "nullable": true, "enum": [null] }] }, "isEnabled": { "type": "boolean" }, "nextRunAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "draft": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "published": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false } }, "required": ["id", "name", "kind", "instructions", "dataSourceIds", "parentDataFlowId", "status", "codeStale", "schedule", "isEnabled", "nextRunAt", "draft", "published"], "additionalProperties": false } },
60
- "operationsSourceGet": { "operationId": "operationsSourceGet", "method": "GET", "path": "/v1/operations/{operationId}/source", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "operationId": { "type": "string" }, "source": { "type": "string" }, "revision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "dependencyOperationIds": { "type": "array", "items": { "type": "string" } }, "dataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["operationId", "source", "revision", "instructions", "dataSourceIds", "dependencyOperationIds", "dataFlowRevision", "updatedAt"], "additionalProperties": false } },
61
- "operationsSourceUpdate": { "operationId": "operationsSourceUpdate", "method": "PUT", "path": "/v1/operations/{operationId}/source", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "source": { "type": "string", "minLength": 1, "maxLength": 1000000 }, "expectedRevision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "expectedDataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "expectedUpdatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["source", "expectedRevision", "expectedDataFlowRevision", "expectedUpdatedAt"], "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "operationId": { "type": "string" }, "source": { "type": "string" }, "revision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "dependencyOperationIds": { "type": "array", "items": { "type": "string" } }, "dataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["operationId", "source", "revision", "instructions", "dataSourceIds", "dependencyOperationIds", "dataFlowRevision", "updatedAt"], "additionalProperties": false } },
60
+ "operationsSourceGet": { "operationId": "operationsSourceGet", "method": "GET", "path": "/v1/operations/{operationId}/source", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "operationId": { "type": "string" }, "source": { "type": "string" }, "incremental": { "nullable": true, "type": "object", "properties": { "sourceId": { "type": "string", "minLength": 1 }, "table": { "type": "string", "minLength": 1 }, "keyColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } }, "inputColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": ["sourceId", "table", "keyColumns", "inputColumns"], "additionalProperties": false }, "revision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "dependencyOperationIds": { "type": "array", "items": { "type": "string" } }, "dataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["operationId", "source", "incremental", "revision", "instructions", "dataSourceIds", "dependencyOperationIds", "dataFlowRevision", "updatedAt"], "additionalProperties": false } },
61
+ "operationsSourceUpdate": { "operationId": "operationsSourceUpdate", "method": "PUT", "path": "/v1/operations/{operationId}/source", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "source": { "type": "string", "minLength": 1, "maxLength": 1000000 }, "incremental": { "nullable": true, "type": "object", "properties": { "sourceId": { "type": "string", "minLength": 1 }, "table": { "type": "string", "minLength": 1 }, "keyColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } }, "inputColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": ["sourceId", "table", "keyColumns", "inputColumns"], "additionalProperties": false }, "expectedRevision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "expectedDataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "expectedUpdatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["source", "expectedRevision", "expectedDataFlowRevision", "expectedUpdatedAt"], "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "operationId": { "type": "string" }, "source": { "type": "string" }, "incremental": { "nullable": true, "type": "object", "properties": { "sourceId": { "type": "string", "minLength": 1 }, "table": { "type": "string", "minLength": 1 }, "keyColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } }, "inputColumns": { "minItems": 1, "type": "array", "items": { "type": "string", "minLength": 1 } } }, "required": ["sourceId", "table", "keyColumns", "inputColumns"], "additionalProperties": false }, "revision": { "nullable": true, "type": "object", "properties": { "revisionId": { "type": "string", "minLength": 1 }, "sequence": { "type": "integer", "exclusiveMinimum": 0, "maximum": 9007199254740991 } }, "required": ["revisionId", "sequence"], "additionalProperties": false }, "instructions": { "type": "string" }, "dataSourceIds": { "type": "array", "items": { "type": "string" } }, "dependencyOperationIds": { "type": "array", "items": { "type": "string" } }, "dataFlowRevision": { "nullable": true, "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "updatedAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" } }, "required": ["operationId", "source", "incremental", "revision", "instructions", "dataSourceIds", "dependencyOperationIds", "dataFlowRevision", "updatedAt"], "additionalProperties": false } },
62
62
  "operationsRunsList": { "operationId": "operationsRunsList", "method": "GET", "path": "/v1/operations/{operationId}/runs", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "workflowId": { "type": "string" }, "revisionId": { "nullable": true, "type": "string" }, "status": { "type": "string" }, "createdAt": { "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "completedAt": { "nullable": true, "type": "string", "format": "date-time", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$" }, "error": { "nullable": true, "type": "string" }, "outputDocId": { "nullable": true, "type": "string" } }, "required": ["id", "workflowId", "revisionId", "status", "createdAt", "completedAt", "error", "outputDocId"], "additionalProperties": false } } }, "required": ["items"], "additionalProperties": false } },
63
63
  "operationsRun": { "operationId": "operationsRun", "method": "POST", "path": "/v1/operations/{operationId}/runs", "scope": "workspace", "bodySchema": { "type": "object", "properties": { "version": { "type": "string", "enum": ["draft", "published"] } }, "required": ["version"], "additionalProperties": false }, "querySchema": null, "responseSchema": { "type": "object", "properties": { "workflowId": { "type": "string" }, "runId": { "type": "string" } }, "required": ["workflowId"], "additionalProperties": false } },
64
64
  "operationsRunOutput": { "operationId": "operationsRunOutput", "method": "GET", "path": "/v1/operations/{operationId}/runs/{runId}/output", "scope": "workspace", "bodySchema": null, "querySchema": null, "responseSchema": { "type": "object", "properties": { "runId": { "type": "string" }, "revisionId": { "nullable": true, "type": "string" }, "rowLimitPerTable": { "type": "number", "enum": [1000] }, "tables": { "type": "object", "additionalProperties": { "type": "array", "items": {} } }, "names": { "type": "object", "additionalProperties": { "type": "string" } }, "schemas": { "type": "object", "additionalProperties": {} } }, "required": ["runId", "revisionId", "rowLimitPerTable", "tables", "names", "schemas"], "additionalProperties": false } },
package/dist/types.d.ts CHANGED
@@ -66,6 +66,9 @@ export type DatasetCreateRequest = CustomDatasetCreateRequest | FileDatasetCreat
66
66
  export type DatasetWriteTablesRequest = PublicApiSchema<'DatasetWriteTablesRequest'>;
67
67
  export type DatasetWriteTablesResponse = PublicApiSchema<'DatasetWriteTablesResponse'>;
68
68
  export type DatasetRows = Record<string, unknown>[];
69
+ export type DatasetCsvUploadOptions = Pick<Extract<DatasetWriteTablesRequest, {
70
+ format: 'csv';
71
+ }>, 'format' | 'compression' | 'rowCount'>;
69
72
  export type SearchRequest = PublicApiSchema<'SearchRequest'>;
70
73
  export type SearchResult = PublicApiSchema<'SearchResult'>;
71
74
  export type SearchResponse = PublicApiSchema<'SearchResponse'>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@permute/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "TypeScript client for the Permute public API",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",