@loxtep/sdk 0.7.7 → 0.7.10
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/CHANGELOG.md +38 -0
- package/README.md +119 -116
- package/dist/auth/browser-login.d.ts +6 -0
- package/dist/auth/browser-login.d.ts.map +1 -1
- package/dist/auth/browser-login.js +54 -26
- package/dist/auth/browser-login.js.map +1 -1
- package/dist/cli/commands/deploy-cmd.d.ts +2 -0
- package/dist/cli/commands/deploy-cmd.d.ts.map +1 -1
- package/dist/cli/commands/deploy-cmd.js +1 -1
- package/dist/cli/commands/deploy-cmd.js.map +1 -1
- package/dist/cli/commands/generate-cmd.d.ts +7 -1
- package/dist/cli/commands/generate-cmd.d.ts.map +1 -1
- package/dist/cli/commands/generate-cmd.js +4 -3
- package/dist/cli/commands/generate-cmd.js.map +1 -1
- package/dist/cli/commands/test-cmd.d.ts +2 -0
- package/dist/cli/commands/test-cmd.d.ts.map +1 -1
- package/dist/cli/commands/test-cmd.js +1 -1
- package/dist/cli/commands/test-cmd.js.map +1 -1
- package/dist/cli/commands/whoami.d.ts +10 -12
- package/dist/cli/commands/whoami.d.ts.map +1 -1
- package/dist/cli/commands/whoami.js +6 -2
- package/dist/cli/commands/whoami.js.map +1 -1
- package/dist/cli/create-cli-client.d.ts +2 -0
- package/dist/cli/create-cli-client.d.ts.map +1 -1
- package/dist/cli/create-cli-client.js +5 -1
- package/dist/cli/create-cli-client.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +1 -6
- package/dist/cli/version.js.map +1 -1
- package/dist/client/current-user-response.d.ts +18 -0
- package/dist/client/current-user-response.d.ts.map +1 -0
- package/dist/client/current-user-response.js +50 -0
- package/dist/client/current-user-response.js.map +1 -0
- package/dist/client/session.d.ts.map +1 -1
- package/dist/client/session.js +4 -2
- package/dist/client/session.js.map +1 -1
- package/docs/code-first-cli.md +10 -8
- package/docs/event-replay-cookbook.md +3 -4
- package/docs/getting-started.md +152 -201
- package/docs/quick-reference.md +10 -11
- package/package.json +1 -1
- package/dist/cli/commands/connections-cmd.d.ts +0 -19
- package/dist/cli/commands/connections-cmd.d.ts.map +0 -1
- package/dist/cli/commands/connections-cmd.js +0 -39
- package/dist/cli/commands/connections-cmd.js.map +0 -1
- package/dist/cli/commands/data-assets-cmd.d.ts +0 -12
- package/dist/cli/commands/data-assets-cmd.d.ts.map +0 -1
- package/dist/cli/commands/data-assets-cmd.js +0 -75
- package/dist/cli/commands/data-assets-cmd.js.map +0 -1
- package/dist/cli/commands/flows-cmd.d.ts +0 -19
- package/dist/cli/commands/flows-cmd.d.ts.map +0 -1
- package/dist/cli/commands/flows-cmd.js +0 -37
- package/dist/cli/commands/flows-cmd.js.map +0 -1
- package/dist/cli/commands/pipelines-cmd.d.ts +0 -17
- package/dist/cli/commands/pipelines-cmd.d.ts.map +0 -1
- package/dist/cli/commands/pipelines-cmd.js +0 -52
- package/dist/cli/commands/pipelines-cmd.js.map +0 -1
- package/dist/cli/commands/promises-cmd.d.ts +0 -11
- package/dist/cli/commands/promises-cmd.d.ts.map +0 -1
- package/dist/cli/commands/promises-cmd.js +0 -53
- package/dist/cli/commands/promises-cmd.js.map +0 -1
- package/dist/client/connection-types.d.ts +0 -98
- package/dist/client/connection-types.d.ts.map +0 -1
- package/dist/client/connection-types.js +0 -18
- package/dist/client/connection-types.js.map +0 -1
- package/dist/client/connections.d.ts +0 -18
- package/dist/client/connections.d.ts.map +0 -1
- package/dist/client/connections.js +0 -66
- package/dist/client/connections.js.map +0 -1
- package/dist/client/consumptions-types.d.ts +0 -80
- package/dist/client/consumptions-types.d.ts.map +0 -1
- package/dist/client/consumptions-types.js +0 -5
- package/dist/client/consumptions-types.js.map +0 -1
- package/dist/client/consumptions.d.ts +0 -14
- package/dist/client/consumptions.d.ts.map +0 -1
- package/dist/client/consumptions.js +0 -47
- package/dist/client/consumptions.js.map +0 -1
- package/dist/client/data-assets-types.d.ts +0 -150
- package/dist/client/data-assets-types.d.ts.map +0 -1
- package/dist/client/data-assets-types.js +0 -5
- package/dist/client/data-assets-types.js.map +0 -1
- package/dist/client/data-assets.d.ts +0 -31
- package/dist/client/data-assets.d.ts.map +0 -1
- package/dist/client/data-assets.js +0 -182
- package/dist/client/data-assets.js.map +0 -1
- package/dist/client/delivery-types.d.ts +0 -97
- package/dist/client/delivery-types.d.ts.map +0 -1
- package/dist/client/delivery-types.js +0 -10
- package/dist/client/delivery-types.js.map +0 -1
- package/dist/client/delivery.d.ts +0 -23
- package/dist/client/delivery.d.ts.map +0 -1
- package/dist/client/delivery.js +0 -105
- package/dist/client/delivery.js.map +0 -1
- package/dist/client/flows.d.ts +0 -33
- package/dist/client/flows.d.ts.map +0 -1
- package/dist/client/flows.js +0 -218
- package/dist/client/flows.js.map +0 -1
package/dist/client/delivery.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delivery API — the primary namespace for managing delivery interfaces
|
|
3
|
-
* on data products.
|
|
4
|
-
*
|
|
5
|
-
* Delivery interfaces define how a data product makes its data available to
|
|
6
|
-
* external systems (webhooks, API endpoints, exports, database syncs, BI
|
|
7
|
-
* connections, event streams).
|
|
8
|
-
*
|
|
9
|
-
* This module calls the same underlying HTTP endpoints as the legacy
|
|
10
|
-
* `consumptions` namespace (`/dataproducts/:data_product_id/consumptions`)
|
|
11
|
-
* but uses the canonical "delivery" terminology.
|
|
12
|
-
*/
|
|
13
|
-
function buildQueryString(params) {
|
|
14
|
-
const search = new URLSearchParams();
|
|
15
|
-
for (const [k, v] of Object.entries(params)) {
|
|
16
|
-
if (v === undefined || v === null)
|
|
17
|
-
continue;
|
|
18
|
-
search.set(k, String(v));
|
|
19
|
-
}
|
|
20
|
-
const qs = search.toString();
|
|
21
|
-
return qs ? `?${qs}` : '';
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Map a raw API response (Consumption shape) to a DeliveryInterface by adding
|
|
25
|
-
* the `deliveryType` discriminator. Infers the delivery type from
|
|
26
|
-
* `delivery_method` when the field isn't already present.
|
|
27
|
-
*/
|
|
28
|
-
function toDeliveryInterface(raw) {
|
|
29
|
-
const result = raw;
|
|
30
|
-
if (!result.deliveryType) {
|
|
31
|
-
// Infer deliveryType from delivery_method if not explicitly set
|
|
32
|
-
const method = raw['delivery_method'] ?? 'webhook';
|
|
33
|
-
result.deliveryType = inferDeliveryType(method);
|
|
34
|
-
}
|
|
35
|
-
return result;
|
|
36
|
-
}
|
|
37
|
-
function inferDeliveryType(deliveryMethod) {
|
|
38
|
-
switch (deliveryMethod) {
|
|
39
|
-
case 'webhook':
|
|
40
|
-
case 'http':
|
|
41
|
-
return 'webhook';
|
|
42
|
-
case 'api_endpoint':
|
|
43
|
-
case 'api':
|
|
44
|
-
return 'api_endpoint';
|
|
45
|
-
case 'export':
|
|
46
|
-
case 'bulk':
|
|
47
|
-
return 'export';
|
|
48
|
-
case 'database_sync':
|
|
49
|
-
case 'warehouse':
|
|
50
|
-
return 'database_sync';
|
|
51
|
-
case 'bi_connect':
|
|
52
|
-
case 'bi':
|
|
53
|
-
return 'bi_connect';
|
|
54
|
-
case 'event_stream':
|
|
55
|
-
case 'stream':
|
|
56
|
-
return 'event_stream';
|
|
57
|
-
default:
|
|
58
|
-
return 'webhook';
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
export function createDeliveryApi(http) {
|
|
62
|
-
const base = (data_product_id) => `/dataproducts/${encodeURIComponent(data_product_id)}/consumptions`;
|
|
63
|
-
return {
|
|
64
|
-
async list(data_product_id, params) {
|
|
65
|
-
const qs = params
|
|
66
|
-
? buildQueryString({
|
|
67
|
-
page: params.page ?? 1,
|
|
68
|
-
page_size: params.page_size ?? 20,
|
|
69
|
-
status: params.status,
|
|
70
|
-
is_active: params.is_active,
|
|
71
|
-
})
|
|
72
|
-
: '';
|
|
73
|
-
const res = await http.get(`${base(data_product_id)}${qs}`);
|
|
74
|
-
return {
|
|
75
|
-
items: res.data.items.map(toDeliveryInterface),
|
|
76
|
-
pagination: res.data.pagination,
|
|
77
|
-
};
|
|
78
|
-
},
|
|
79
|
-
async get(data_product_id, delivery_id) {
|
|
80
|
-
const res = await http.get(`${base(data_product_id)}/${encodeURIComponent(delivery_id)}`);
|
|
81
|
-
return toDeliveryInterface(res.data);
|
|
82
|
-
},
|
|
83
|
-
async create(data_product_id, body) {
|
|
84
|
-
// Map deliveryType to delivery_method for the API if provided
|
|
85
|
-
const apiBody = { ...body };
|
|
86
|
-
if (body.deliveryType && !body.delivery_method) {
|
|
87
|
-
apiBody['delivery_method'] = body.deliveryType;
|
|
88
|
-
}
|
|
89
|
-
const res = await http.post(base(data_product_id), apiBody);
|
|
90
|
-
return toDeliveryInterface(res.data);
|
|
91
|
-
},
|
|
92
|
-
async update(data_product_id, delivery_id, body) {
|
|
93
|
-
const apiBody = { ...body };
|
|
94
|
-
if (body.deliveryType && !body.delivery_method) {
|
|
95
|
-
apiBody['delivery_method'] = body.deliveryType;
|
|
96
|
-
}
|
|
97
|
-
const res = await http.put(`${base(data_product_id)}/${encodeURIComponent(delivery_id)}`, apiBody);
|
|
98
|
-
return toDeliveryInterface(res.data);
|
|
99
|
-
},
|
|
100
|
-
async delete(data_product_id, delivery_id) {
|
|
101
|
-
await http.delete(`${base(data_product_id)}/${encodeURIComponent(delivery_id)}`);
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=delivery.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"delivery.js","sourceRoot":"","sources":["../../src/client/delivery.ts"],"names":[],"mappings":"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"}
|
package/dist/client/flows.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flows API (backend: workflows). list, get (with nodes), create, get_writer.
|
|
3
|
-
* Flow writes for live events use the Loxtep stream data plane — not HTTP POST to /workflows/.../events.
|
|
4
|
-
*/
|
|
5
|
-
import type { RStreamsSdk } from '../rstreams/leo-runtime.js';
|
|
6
|
-
import type { LoxtepHttpClient } from '../http/client.js';
|
|
7
|
-
import type { Flow, FlowWithNodes, FlowsListFilters, FlowsListResponse, FlowCreateInput, FlowWriter, GetWriterOptions } from './flow-types.js';
|
|
8
|
-
export interface FlowsApiDeps {
|
|
9
|
-
/** Stream runtime; required for get_writer().close() */
|
|
10
|
-
rsdk?: RStreamsSdk;
|
|
11
|
-
/** Lazy stream runtime resolver (attempts observe.stream_config() when rsdk is not set). */
|
|
12
|
-
get_rsdk?: () => Promise<RStreamsSdk | undefined>;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Determine whether an error is transient and should be retried.
|
|
16
|
-
* Transient: network errors, timeouts, throttling (429), 5xx responses.
|
|
17
|
-
* Non-transient: 4xx (except 429), auth failures — fail immediately.
|
|
18
|
-
*/
|
|
19
|
-
export declare function isTransientError(err: unknown): boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Sleep for the given number of milliseconds. Extracted for testability.
|
|
22
|
-
*/
|
|
23
|
-
export declare function sleep(ms: number): Promise<void>;
|
|
24
|
-
/**
|
|
25
|
-
* Create the flows API surface (list, get with nodes, create, get_writer).
|
|
26
|
-
*/
|
|
27
|
-
export declare function createFlowsApi(http: LoxtepHttpClient, deps?: FlowsApiDeps): {
|
|
28
|
-
list: (filters: FlowsListFilters) => Promise<FlowsListResponse['data']>;
|
|
29
|
-
get: (id: string) => Promise<FlowWithNodes>;
|
|
30
|
-
create: (input: FlowCreateInput) => Promise<Flow>;
|
|
31
|
-
get_writer: (flow_id: string, options?: GetWriterOptions) => Promise<FlowWriter>;
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=flows.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/client/flows.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,IAAI,EACJ,aAAa,EAEb,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,UAAU,EACV,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AAUzB,MAAM,WAAW,YAAY;IAC3B,wDAAwD;IACxD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC;CACnD;AAkCD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAwEtD;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,gBAAgB,EACtB,IAAI,CAAC,EAAE,YAAY,GAClB;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IACxE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5C,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAClF,CAmIA"}
|
package/dist/client/flows.js
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Flows API (backend: workflows). list, get (with nodes), create, get_writer.
|
|
3
|
-
* Flow writes for live events use the Loxtep stream data plane — not HTTP POST to /workflows/.../events.
|
|
4
|
-
*/
|
|
5
|
-
import { DefinitionValidationError } from '../errors/validation.js';
|
|
6
|
-
import { StreamingError } from '../errors/streaming.js';
|
|
7
|
-
import { createQueueWriter } from '../rstreams/event-bridge.js';
|
|
8
|
-
import { resolveIngestionQueueName } from './flow-queue-resolve.js';
|
|
9
|
-
const WORKFLOWS_API_BASE = '/workflows/workflows';
|
|
10
|
-
function buildQueryString(params) {
|
|
11
|
-
const search = new URLSearchParams();
|
|
12
|
-
for (const [k, v] of Object.entries(params)) {
|
|
13
|
-
if (v === undefined || v === null)
|
|
14
|
-
continue;
|
|
15
|
-
search.set(k, String(v));
|
|
16
|
-
}
|
|
17
|
-
const qs = search.toString();
|
|
18
|
-
return qs ? `?${qs}` : '';
|
|
19
|
-
}
|
|
20
|
-
function validateEventAgainstDefinition(event, definition) {
|
|
21
|
-
const errors = [];
|
|
22
|
-
const required = definition.required;
|
|
23
|
-
if (Array.isArray(required) &&
|
|
24
|
-
required.length > 0 &&
|
|
25
|
-
event !== null &&
|
|
26
|
-
typeof event === 'object') {
|
|
27
|
-
const obj = event;
|
|
28
|
-
for (const key of required) {
|
|
29
|
-
if (!(key in obj) || obj[key] === undefined) {
|
|
30
|
-
errors.push({ path: key, message: `Missing required field: ${key}` });
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return errors;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Determine whether an error is transient and should be retried.
|
|
38
|
-
* Transient: network errors, timeouts, throttling (429), 5xx responses.
|
|
39
|
-
* Non-transient: 4xx (except 429), auth failures — fail immediately.
|
|
40
|
-
*/
|
|
41
|
-
export function isTransientError(err) {
|
|
42
|
-
if (err === null || err === undefined)
|
|
43
|
-
return false;
|
|
44
|
-
// Check for status code on the error object (HTTP response errors)
|
|
45
|
-
const statusCode = typeof err.status_code === 'number'
|
|
46
|
-
? err.status_code
|
|
47
|
-
: typeof err.statusCode === 'number'
|
|
48
|
-
? err.statusCode
|
|
49
|
-
: typeof err.status === 'number'
|
|
50
|
-
? err.status
|
|
51
|
-
: undefined;
|
|
52
|
-
if (statusCode !== undefined) {
|
|
53
|
-
// 429 (throttling) is transient
|
|
54
|
-
if (statusCode === 429)
|
|
55
|
-
return true;
|
|
56
|
-
// 5xx responses are transient
|
|
57
|
-
if (statusCode >= 500 && statusCode < 600)
|
|
58
|
-
return true;
|
|
59
|
-
// Other 4xx are non-transient (auth failures, validation errors, etc.)
|
|
60
|
-
if (statusCode >= 400 && statusCode < 500)
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
// Check error code strings
|
|
64
|
-
const code = typeof err.code === 'string'
|
|
65
|
-
? err.code
|
|
66
|
-
: undefined;
|
|
67
|
-
if (code) {
|
|
68
|
-
const transientCodes = new Set([
|
|
69
|
-
'ECONNRESET',
|
|
70
|
-
'ECONNREFUSED',
|
|
71
|
-
'ENOTFOUND',
|
|
72
|
-
'ETIMEDOUT',
|
|
73
|
-
'EPIPE',
|
|
74
|
-
'EAI_AGAIN',
|
|
75
|
-
'RATE_LIMIT_EXCEEDED',
|
|
76
|
-
'RATE_LIMIT_ERROR',
|
|
77
|
-
'SERVICE_UNAVAILABLE',
|
|
78
|
-
'GATEWAY_TIMEOUT',
|
|
79
|
-
'INTERNAL_SERVER_ERROR',
|
|
80
|
-
]);
|
|
81
|
-
if (transientCodes.has(code))
|
|
82
|
-
return true;
|
|
83
|
-
// Auth-related codes are non-transient
|
|
84
|
-
const nonTransientCodes = new Set([
|
|
85
|
-
'AUTHENTICATION_ERROR',
|
|
86
|
-
'AUTHORIZATION_ERROR',
|
|
87
|
-
'VALIDATION_ERROR',
|
|
88
|
-
'NOT_FOUND',
|
|
89
|
-
]);
|
|
90
|
-
if (nonTransientCodes.has(code))
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
// Check error message for network-related keywords
|
|
94
|
-
const message = typeof err.message === 'string'
|
|
95
|
-
? err.message.toLowerCase()
|
|
96
|
-
: '';
|
|
97
|
-
if (message.includes('timeout') ||
|
|
98
|
-
message.includes('econnreset') ||
|
|
99
|
-
message.includes('econnrefused') ||
|
|
100
|
-
message.includes('network') ||
|
|
101
|
-
message.includes('socket hang up')) {
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
// Default: treat unknown errors as transient to allow retry
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Sleep for the given number of milliseconds. Extracted for testability.
|
|
109
|
-
*/
|
|
110
|
-
export function sleep(ms) {
|
|
111
|
-
if (ms <= 0)
|
|
112
|
-
return Promise.resolve();
|
|
113
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Create the flows API surface (list, get with nodes, create, get_writer).
|
|
117
|
-
*/
|
|
118
|
-
export function createFlowsApi(http, deps) {
|
|
119
|
-
return {
|
|
120
|
-
async list(filters) {
|
|
121
|
-
const params = {
|
|
122
|
-
project_id: filters.project_id,
|
|
123
|
-
page: filters.page ?? 1,
|
|
124
|
-
page_size: filters.page_size ?? 100,
|
|
125
|
-
};
|
|
126
|
-
if (filters.status)
|
|
127
|
-
params.status = filters.status;
|
|
128
|
-
if (filters.search)
|
|
129
|
-
params.search = filters.search;
|
|
130
|
-
const qs = buildQueryString(params);
|
|
131
|
-
const res = await http.get(`${WORKFLOWS_API_BASE}${qs}`);
|
|
132
|
-
return res.data;
|
|
133
|
-
},
|
|
134
|
-
async get(id) {
|
|
135
|
-
const flowRes = await http.get(`${WORKFLOWS_API_BASE}/${encodeURIComponent(id)}`);
|
|
136
|
-
const flow = flowRes.data;
|
|
137
|
-
let nodes = [];
|
|
138
|
-
try {
|
|
139
|
-
const nodesRes = await http.get(`${WORKFLOWS_API_BASE}/${encodeURIComponent(id)}/nodes`);
|
|
140
|
-
const payload = nodesRes.data ?? nodesRes;
|
|
141
|
-
nodes = payload.items ?? [];
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
// Nodes endpoint may not exist or may 404; flow still has node_count
|
|
145
|
-
}
|
|
146
|
-
return { ...flow, nodes };
|
|
147
|
-
},
|
|
148
|
-
async create(input) {
|
|
149
|
-
const res = await http.post(WORKFLOWS_API_BASE, input);
|
|
150
|
-
return res.data;
|
|
151
|
-
},
|
|
152
|
-
async get_writer(flow_id, options) {
|
|
153
|
-
// Resolve the stream runtime, source bot, and destination queue up front; the rstreams `load`
|
|
154
|
-
// stream (created inside createQueueWriter) owns buffering, batching, backoff, and checkpointing.
|
|
155
|
-
const rsdk = deps?.rsdk ?? (await deps?.get_rsdk?.());
|
|
156
|
-
if (!rsdk) {
|
|
157
|
-
throw new StreamingError('Stream bus configuration missing. Set LEO_* environment variables or add `streams` to ~/.loxtep/config.json. ' +
|
|
158
|
-
'Pass `streams` in LoxtepClientOptions, or ensure your instance stream environment is configured.', {
|
|
159
|
-
details: {
|
|
160
|
-
flow_id,
|
|
161
|
-
hint: 'Run `loxtep init` to configure stream bus, or set LEO_* env vars from your instance.',
|
|
162
|
-
},
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
const botId = options?.bot_id;
|
|
166
|
-
if (!botId) {
|
|
167
|
-
throw new StreamingError('flows.get_writer requires bot_id in options (stream writer identity on the bus).', { details: { flow_id } });
|
|
168
|
-
}
|
|
169
|
-
let queueName = options?.output_queue_name;
|
|
170
|
-
if (!queueName && options?.environment_prefix && options?.project_id) {
|
|
171
|
-
const flowRes = await http.get(`${WORKFLOWS_API_BASE}/${encodeURIComponent(flow_id)}`);
|
|
172
|
-
const flowData = flowRes && typeof flowRes === 'object' && 'data' in flowRes
|
|
173
|
-
? flowRes.data
|
|
174
|
-
: flowRes;
|
|
175
|
-
let nodes = [];
|
|
176
|
-
try {
|
|
177
|
-
const nodesRes = await http.get(`${WORKFLOWS_API_BASE}/${encodeURIComponent(flow_id)}/nodes`);
|
|
178
|
-
const payload = nodesRes.data ?? nodesRes;
|
|
179
|
-
nodes = payload.items ?? [];
|
|
180
|
-
}
|
|
181
|
-
catch {
|
|
182
|
-
/* ignore */
|
|
183
|
-
}
|
|
184
|
-
const flowWithNodes = { ...flowData, nodes };
|
|
185
|
-
queueName = resolveIngestionQueueName(flowWithNodes, options.environment_prefix);
|
|
186
|
-
}
|
|
187
|
-
if (!queueName) {
|
|
188
|
-
throw new StreamingError('flows.get_writer requires output_queue_name, or environment_prefix + project_id so the SDK can resolve the ingestion queue from the flow.', { details: { flow_id } });
|
|
189
|
-
}
|
|
190
|
-
const writer = createQueueWriter(rsdk, botId, queueName, () => new StreamingError('Cannot write to a closed FlowWriter. Create a new writer via flows.get_writer().', { details: { flow_id } }));
|
|
191
|
-
// Optional per-event definition validation wraps the passthrough writer.
|
|
192
|
-
const validate = options?.validate_definition === true && !!options?.definition;
|
|
193
|
-
if (!validate)
|
|
194
|
-
return writer;
|
|
195
|
-
const onError = options?.on_validation_error ?? 'reject';
|
|
196
|
-
return {
|
|
197
|
-
write(event, writeOptions) {
|
|
198
|
-
if (options?.definition) {
|
|
199
|
-
const errors = validateEventAgainstDefinition(event, options.definition);
|
|
200
|
-
if (errors.length > 0) {
|
|
201
|
-
if (onError === 'reject') {
|
|
202
|
-
throw new DefinitionValidationError('Event failed definition validation', options.definition_version ?? '', errors);
|
|
203
|
-
}
|
|
204
|
-
if (onError === 'warn') {
|
|
205
|
-
console.warn('[FlowWriter] Definition validation failed:', errors);
|
|
206
|
-
}
|
|
207
|
-
if (onError === 'skip')
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
writer.write(event, writeOptions);
|
|
212
|
-
},
|
|
213
|
-
close: () => writer.close(),
|
|
214
|
-
};
|
|
215
|
-
},
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
//# sourceMappingURL=flows.js.map
|
package/dist/client/flows.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"flows.js","sourceRoot":"","sources":["../../src/client/flows.ts"],"names":[],"mappings":"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"}
|