@pylo/node 0.0.10 → 0.0.12
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/dist/index.d.ts +71 -1
- package/dist/index.js +165 -0
- package/package.json +15 -4
package/dist/index.d.ts
CHANGED
|
@@ -38,10 +38,71 @@ interface SearchValueInput {
|
|
|
38
38
|
multiple_results_allowed?: boolean;
|
|
39
39
|
multiple_results_use_latest?: boolean;
|
|
40
40
|
}
|
|
41
|
+
interface PyloEventInput {
|
|
42
|
+
event_name: string;
|
|
43
|
+
properties: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface PyloEvent {
|
|
46
|
+
event_name: string;
|
|
47
|
+
ts: string;
|
|
48
|
+
properties: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
type AggregateFunction = "count" | "sum" | "avg" | "min" | "max";
|
|
51
|
+
interface AggregateInput {
|
|
52
|
+
field: string;
|
|
53
|
+
function: AggregateFunction;
|
|
54
|
+
alias?: string;
|
|
55
|
+
}
|
|
56
|
+
interface TimeBucketInput {
|
|
57
|
+
field?: string;
|
|
58
|
+
interval: string;
|
|
59
|
+
timezone?: string;
|
|
60
|
+
}
|
|
61
|
+
interface DimensionInput {
|
|
62
|
+
field?: string;
|
|
63
|
+
timeBucket?: TimeBucketInput;
|
|
64
|
+
}
|
|
65
|
+
interface EventListFilterInput {
|
|
66
|
+
query?: QueryInput[];
|
|
67
|
+
sortby?: SortInput[];
|
|
68
|
+
aggregate?: AggregateInput[];
|
|
69
|
+
dimensions?: DimensionInput[];
|
|
70
|
+
limit?: number;
|
|
71
|
+
}
|
|
72
|
+
interface EventListOptions {
|
|
73
|
+
filter?: EventListFilterInput;
|
|
74
|
+
pagination?: PaginationInput;
|
|
75
|
+
select_fields?: string[];
|
|
76
|
+
interval?: string;
|
|
77
|
+
timezone?: string;
|
|
78
|
+
group_by?: string[];
|
|
79
|
+
startTime?: string;
|
|
80
|
+
}
|
|
81
|
+
interface PyloEventListResult {
|
|
82
|
+
data: Array<Record<string, unknown>>;
|
|
83
|
+
pagination: PaginationData;
|
|
84
|
+
aggregations: Record<string, unknown> | null;
|
|
85
|
+
}
|
|
86
|
+
interface PyloEventProperty {
|
|
87
|
+
path: string;
|
|
88
|
+
type: string;
|
|
89
|
+
}
|
|
90
|
+
interface PyloEventFieldValue {
|
|
91
|
+
value: string;
|
|
92
|
+
count: number;
|
|
93
|
+
}
|
|
94
|
+
interface PyloEventPropertyKeysOptions {
|
|
95
|
+
filter?: FilterInput;
|
|
96
|
+
}
|
|
97
|
+
interface PyloEventFieldValuesOptions {
|
|
98
|
+
startTime?: string;
|
|
99
|
+
limit?: number;
|
|
100
|
+
}
|
|
41
101
|
interface EntityMetadata {
|
|
42
102
|
pascalName: string;
|
|
43
103
|
scalarFieldNames: string[];
|
|
44
104
|
variantFieldNames?: string[];
|
|
105
|
+
jsonFieldNames?: string[];
|
|
45
106
|
enumFields?: Record<string, string[]>;
|
|
46
107
|
relations: Record<string, {
|
|
47
108
|
type: "hasOne" | "hasMany";
|
|
@@ -164,8 +225,17 @@ interface EntityClient<S, E extends EntityName<S>> {
|
|
|
164
225
|
success: boolean;
|
|
165
226
|
}>;
|
|
166
227
|
}
|
|
228
|
+
type IngestEvents = (events: PyloEventInput[], options?: MutationRequestOptions) => Promise<PyloEvent[]>;
|
|
229
|
+
interface EventsClient {
|
|
230
|
+
list(options?: EventListOptions & RequestOptions): Promise<PyloEventListResult>;
|
|
231
|
+
propertyKeys(options?: PyloEventPropertyKeysOptions & RequestOptions): Promise<PyloEventProperty[]>;
|
|
232
|
+
fieldValues(field: string, options?: PyloEventFieldValuesOptions & RequestOptions): Promise<PyloEventFieldValue[]>;
|
|
233
|
+
}
|
|
167
234
|
type PyloClient<S> = {
|
|
168
235
|
[E in EntityName<S>]: EntityClient<S, E>;
|
|
236
|
+
} & {
|
|
237
|
+
ingestEvents: IngestEvents;
|
|
238
|
+
events: EventsClient;
|
|
169
239
|
};
|
|
170
240
|
|
|
171
241
|
interface NodeClientOptions {
|
|
@@ -176,4 +246,4 @@ interface NodeClientOptions {
|
|
|
176
246
|
}
|
|
177
247
|
declare function createPyloNode<S>(options: NodeClientOptions): PyloClient<S>;
|
|
178
248
|
|
|
179
|
-
export { type AuthProvider, type ByIdOptions, type ClientOptions, type EntityClient, type EntityFields, type EntityMetadata, type EntityName, type EntityRelations, type EntityResult, type EntitySelect, type FilterInput, type ListOptions, type ListResult, type PaginationData, type PaginationInput, type PyloClient, PyloError, type QueryInput, type QueryInputCondition, type QueryOperator, type RequestOptions, type SchemaMetadata, type SearchValueInput, type SortInput, type SortOrder, type StrictSelect, type UpsertInput, createPyloNode };
|
|
249
|
+
export { type AggregateFunction, type AggregateInput, type AuthProvider, type ByIdOptions, type ClientOptions, type DimensionInput, type EntityClient, type EntityFields, type EntityMetadata, type EntityName, type EntityRelations, type EntityResult, type EntitySelect, type EventListFilterInput, type EventListOptions, type EventsClient, type FilterInput, type IngestEvents, type ListOptions, type ListResult, type MutationRequestOptions, type PaginationData, type PaginationInput, type PyloClient, PyloError, type PyloEvent, type PyloEventFieldValue, type PyloEventFieldValuesOptions, type PyloEventInput, type PyloEventListResult, type PyloEventProperty, type PyloEventPropertyKeysOptions, type QueryInput, type QueryInputCondition, type QueryOperator, type RequestOptions, type SchemaMetadata, type SearchValueInput, type SortInput, type SortOrder, type StrictSelect, type TimeBucketInput, type UpsertInput, createPyloNode };
|
package/dist/index.js
CHANGED
|
@@ -208,6 +208,89 @@ function buildByIdQuery(entityKey, id, options, schemaMetadata) {
|
|
|
208
208
|
function capitalize(str) {
|
|
209
209
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
210
210
|
}
|
|
211
|
+
var EVENT_LIST_ARG_TYPES = {
|
|
212
|
+
filter: "EventListFilterInput",
|
|
213
|
+
pagination: "PaginationInput",
|
|
214
|
+
select_fields: "[String!]",
|
|
215
|
+
interval: "String",
|
|
216
|
+
timezone: "String",
|
|
217
|
+
group_by: "[String!]",
|
|
218
|
+
startTime: "String"
|
|
219
|
+
};
|
|
220
|
+
var EVENT_LIST_DATA = `data
|
|
221
|
+
pagination {
|
|
222
|
+
total
|
|
223
|
+
current_page
|
|
224
|
+
per_page
|
|
225
|
+
last_page
|
|
226
|
+
has_more_pages
|
|
227
|
+
}
|
|
228
|
+
aggregations`;
|
|
229
|
+
function normalizeEventFilter(filter) {
|
|
230
|
+
var _a;
|
|
231
|
+
if (!((_a = filter.dimensions) == null ? void 0 : _a.length)) return filter;
|
|
232
|
+
const dimensions = filter.dimensions.map(
|
|
233
|
+
(dim) => dim.timeBucket && dim.timeBucket.field === void 0 ? { ...dim, timeBucket: { ...dim.timeBucket, field: "ts" } } : dim
|
|
234
|
+
);
|
|
235
|
+
return { ...filter, dimensions };
|
|
236
|
+
}
|
|
237
|
+
function buildEventListQuery(options) {
|
|
238
|
+
const variables = {};
|
|
239
|
+
const varDecls = [];
|
|
240
|
+
const argParts = [];
|
|
241
|
+
for (const key of Object.keys(EVENT_LIST_ARG_TYPES)) {
|
|
242
|
+
const value = options == null ? void 0 : options[key];
|
|
243
|
+
if (value === void 0) continue;
|
|
244
|
+
variables[key] = key === "filter" ? normalizeEventFilter(value) : value;
|
|
245
|
+
varDecls.push(`$${key}: ${EVENT_LIST_ARG_TYPES[key]}`);
|
|
246
|
+
argParts.push(`${key}: $${key}`);
|
|
247
|
+
}
|
|
248
|
+
const varSection = varDecls.length > 0 ? `(${varDecls.join(", ")})` : "";
|
|
249
|
+
const argSection = argParts.length > 0 ? `(${argParts.join(", ")})` : "";
|
|
250
|
+
const query = `query PyloEventList${varSection} {
|
|
251
|
+
pyloEventList${argSection} {
|
|
252
|
+
${EVENT_LIST_DATA}
|
|
253
|
+
}
|
|
254
|
+
}`;
|
|
255
|
+
return { query, variables };
|
|
256
|
+
}
|
|
257
|
+
function buildEventPropertyKeysQuery(options) {
|
|
258
|
+
const hasFilter = (options == null ? void 0 : options.filter) !== void 0;
|
|
259
|
+
const varSection = hasFilter ? "($filter: FilterInput)" : "";
|
|
260
|
+
const argSection = hasFilter ? "(filter: $filter)" : "";
|
|
261
|
+
const query = `query PyloEventPropertyKeys${varSection} {
|
|
262
|
+
pyloEventPropertyKeys${argSection} {
|
|
263
|
+
path
|
|
264
|
+
type
|
|
265
|
+
}
|
|
266
|
+
}`;
|
|
267
|
+
return {
|
|
268
|
+
query,
|
|
269
|
+
variables: hasFilter ? { filter: options.filter } : {}
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function buildEventFieldValuesQuery(field, options) {
|
|
273
|
+
const varDecls = ["$field: String!"];
|
|
274
|
+
const argParts = ["field: $field"];
|
|
275
|
+
const variables = { field };
|
|
276
|
+
if ((options == null ? void 0 : options.startTime) !== void 0) {
|
|
277
|
+
varDecls.push("$startTime: String");
|
|
278
|
+
argParts.push("startTime: $startTime");
|
|
279
|
+
variables["startTime"] = options.startTime;
|
|
280
|
+
}
|
|
281
|
+
if ((options == null ? void 0 : options.limit) !== void 0) {
|
|
282
|
+
varDecls.push("$limit: Int");
|
|
283
|
+
argParts.push("limit: $limit");
|
|
284
|
+
variables["limit"] = options.limit;
|
|
285
|
+
}
|
|
286
|
+
const query = `query PyloEventFieldValues(${varDecls.join(", ")}) {
|
|
287
|
+
pyloEventFieldValues(${argParts.join(", ")}) {
|
|
288
|
+
value
|
|
289
|
+
count
|
|
290
|
+
}
|
|
291
|
+
}`;
|
|
292
|
+
return { query, variables };
|
|
293
|
+
}
|
|
211
294
|
function buildUpsertMutation(_entityKey, pascalName, input) {
|
|
212
295
|
const mutation = `mutation Update${pascalName}($input: Update${pascalName}Input!) {
|
|
213
296
|
update${pascalName}(input: $input) {
|
|
@@ -234,6 +317,21 @@ function buildDeleteMutation(_entityKey, pascalName, ids) {
|
|
|
234
317
|
variables: { ids }
|
|
235
318
|
};
|
|
236
319
|
}
|
|
320
|
+
function buildIngestEventsMutation(events) {
|
|
321
|
+
const mutation = `mutation IngestPyloEventData($input: [PyloEventInput!]!) {
|
|
322
|
+
ingestPyloEventData(input: $input) {
|
|
323
|
+
data {
|
|
324
|
+
event_name
|
|
325
|
+
ts
|
|
326
|
+
properties
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}`;
|
|
330
|
+
return {
|
|
331
|
+
query: mutation,
|
|
332
|
+
variables: { input: events }
|
|
333
|
+
};
|
|
334
|
+
}
|
|
237
335
|
var PYLO_DRY_RUN_HEADER = "pylo-dry-run";
|
|
238
336
|
var PYLO_DO_NOT_TRIGGER_FLOWS_HEADER = "pylo-do-not-trigger-flow";
|
|
239
337
|
function flagsToHeaders(flags) {
|
|
@@ -368,14 +466,81 @@ function createEntityClient(entityKey, endpoint, metadata, auth, globalHeaders)
|
|
|
368
466
|
}
|
|
369
467
|
};
|
|
370
468
|
}
|
|
469
|
+
function createIngestEvents(endpoint, auth, globalHeaders) {
|
|
470
|
+
return async (events, options) => {
|
|
471
|
+
const { query, variables } = buildIngestEventsMutation(events);
|
|
472
|
+
const data = await executeGraphQL(
|
|
473
|
+
endpoint,
|
|
474
|
+
query,
|
|
475
|
+
variables,
|
|
476
|
+
auth,
|
|
477
|
+
mergeHeaders(
|
|
478
|
+
mergeHeaders(globalHeaders, options == null ? void 0 : options.headers),
|
|
479
|
+
flagsToHeaders(options != null ? options : {})
|
|
480
|
+
)
|
|
481
|
+
);
|
|
482
|
+
const result = data["ingestPyloEventData"];
|
|
483
|
+
if (!result) {
|
|
484
|
+
throw new PyloError("Unexpected response shape \u2014 missing ingestPyloEventData");
|
|
485
|
+
}
|
|
486
|
+
return result.data;
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function createEventsClient(endpoint, auth, globalHeaders) {
|
|
490
|
+
return {
|
|
491
|
+
async list(options) {
|
|
492
|
+
const { query, variables } = buildEventListQuery(options);
|
|
493
|
+
const data = await executeGraphQL(
|
|
494
|
+
endpoint,
|
|
495
|
+
query,
|
|
496
|
+
variables,
|
|
497
|
+
auth,
|
|
498
|
+
mergeHeaders(globalHeaders, options == null ? void 0 : options.headers)
|
|
499
|
+
);
|
|
500
|
+
const result = data["pyloEventList"];
|
|
501
|
+
if (!result) {
|
|
502
|
+
throw new PyloError("Unexpected response shape \u2014 missing pyloEventList");
|
|
503
|
+
}
|
|
504
|
+
return result;
|
|
505
|
+
},
|
|
506
|
+
async propertyKeys(options) {
|
|
507
|
+
var _a;
|
|
508
|
+
const { query, variables } = buildEventPropertyKeysQuery(options);
|
|
509
|
+
const data = await executeGraphQL(
|
|
510
|
+
endpoint,
|
|
511
|
+
query,
|
|
512
|
+
variables,
|
|
513
|
+
auth,
|
|
514
|
+
mergeHeaders(globalHeaders, options == null ? void 0 : options.headers)
|
|
515
|
+
);
|
|
516
|
+
return (_a = data["pyloEventPropertyKeys"]) != null ? _a : [];
|
|
517
|
+
},
|
|
518
|
+
async fieldValues(field, options) {
|
|
519
|
+
var _a;
|
|
520
|
+
const { query, variables } = buildEventFieldValuesQuery(field, options);
|
|
521
|
+
const data = await executeGraphQL(
|
|
522
|
+
endpoint,
|
|
523
|
+
query,
|
|
524
|
+
variables,
|
|
525
|
+
auth,
|
|
526
|
+
mergeHeaders(globalHeaders, options == null ? void 0 : options.headers)
|
|
527
|
+
);
|
|
528
|
+
return (_a = data["pyloEventFieldValues"]) != null ? _a : [];
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
}
|
|
371
532
|
function createPyloClient(options) {
|
|
372
533
|
const endpoint = getEndpoint(options.endpoint);
|
|
373
534
|
const metadata = options.schemaMetadata;
|
|
374
535
|
const auth = options.auth;
|
|
375
536
|
const globalHeaders = options.headers;
|
|
537
|
+
const ingestEvents = createIngestEvents(endpoint, auth, globalHeaders);
|
|
538
|
+
const events = createEventsClient(endpoint, auth, globalHeaders);
|
|
376
539
|
return new Proxy({}, {
|
|
377
540
|
get(_target, prop) {
|
|
378
541
|
if (typeof prop !== "string") return void 0;
|
|
542
|
+
if (prop === "ingestEvents") return ingestEvents;
|
|
543
|
+
if (prop === "events") return events;
|
|
379
544
|
return createEntityClient(prop, endpoint, metadata, auth, globalHeaders);
|
|
380
545
|
}
|
|
381
546
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pylo/node",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "Server-side Pylo SDK with API key authentication",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"pylo": "dist/cli.js"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
22
|
-
"dist"
|
|
22
|
+
"dist",
|
|
23
|
+
"LICENSE"
|
|
23
24
|
],
|
|
24
25
|
"dependencies": {
|
|
25
26
|
"jiti": "^2.6.1"
|
|
@@ -28,10 +29,20 @@
|
|
|
28
29
|
"@types/node": "^22.15.21",
|
|
29
30
|
"tsup": "^8.5.1",
|
|
30
31
|
"typescript": "^5.9.3",
|
|
31
|
-
"@pylo/core": "0.0.
|
|
32
|
+
"@pylo/core": "0.0.14",
|
|
32
33
|
"@pylo/auth": "0.0.5"
|
|
33
34
|
},
|
|
34
|
-
"
|
|
35
|
+
"author": "Okeano GmbH",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"homepage": "https://github.com/Okeano-GmbH/pylo-sdks/tree/main/node#readme",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/Okeano-GmbH/pylo-sdks.git",
|
|
41
|
+
"directory": "node"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/Okeano-GmbH/pylo-sdks/issues"
|
|
45
|
+
},
|
|
35
46
|
"scripts": {
|
|
36
47
|
"build": "tsup",
|
|
37
48
|
"watch": "tsc -w"
|