@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 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.10",
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.12",
32
+ "@pylo/core": "0.0.14",
32
33
  "@pylo/auth": "0.0.5"
33
34
  },
34
- "license": "ISC",
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"