@voltro/plugin-tinybird 0.84.0 → 0.86.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/dist/index.js CHANGED
@@ -1,157 +1,25 @@
1
- import { Effect as e } from "effect";
2
- import { AnalyticsError as t } from "@voltro/runtime";
3
- //#region src/sink.ts
4
- var n = "tinybird", r = (r) => e.mapError((e) => new t({
5
- provider: n,
6
- operation: r,
7
- cause: e instanceof Error ? `${e.name}: ${e.message}` : String(e)
8
- })), i = /^[A-Za-z_][A-Za-z0-9_]*$/, a = (e, r) => {
9
- if (!i.test(e)) throw new t({
10
- provider: n,
11
- operation: "config",
12
- cause: `invalid ${r} ${JSON.stringify(e)} — must match ${i.source} (letters, digits, underscore; no dots/slashes/quotes/spaces)`
13
- });
14
- return e;
15
- }, o = /['\\]/, s = (e) => {
16
- for (let t = 0; t < e.length; t++) if (e.charCodeAt(t) < 32) return !0;
17
- return !1;
18
- }, c = (e) => {
19
- if (o.test(e) || s(e)) throw Error(`tinybird: invalid property key ${JSON.stringify(e)} — must not contain quotes, backslashes, or control characters`);
20
- return e;
21
- }, l = (e, t) => {
22
- let n = [];
23
- if (t != null && n.push(`tenant_id = '${t.replace(/'/g, "''")}'`), e) for (let [t, r] of Object.entries(e)) {
24
- let e = String(r).replace(/'/g, "''");
25
- n.push(`JSONExtractString(properties, '${c(t)}') = '${e}'`);
26
- }
27
- return n.length === 0 ? "" : ` AND ${n.join(" AND ")}`;
28
- }, u = (e) => e === "count" ? "count()" : e === "unique" ? "uniqExact(subject_id)" : "sum" in e ? `sum(JSONExtractFloat(properties, '${c(e.sum)}'))` : `avg(JSONExtractFloat(properties, '${c(e.avg)}'))`, d = async (e, t, n) => {
29
- let r = new URL(`${e.apiUrl}/v0/pipes/${t}.json`);
30
- for (let [e, t] of Object.entries(n)) r.searchParams.set(e, String(t));
31
- let i = await fetch(r.toString(), { headers: { authorization: `Bearer ${e.token}` } });
32
- if (!i.ok) {
33
- let e = await i.text().catch(() => "");
34
- throw Error(`tinybird pipe ${t} returned HTTP ${i.status}: ${e}`);
35
- }
36
- return i.json();
37
- }, f = (t) => ({
38
- info: {
39
- provider: n,
40
- capabilities: {
41
- track: !0,
42
- aggregate: !0,
43
- timeseries: !0,
44
- topN: !0,
45
- mirror: !1
46
- },
47
- detail: {
48
- apiUrl: t.apiUrl,
49
- datasource: t.datasource,
50
- pipes: t.pipes
51
- }
52
- },
53
- track: (n) => e.gen(function* () {
54
- let r = `${t.apiUrl}/v0/events?name=${encodeURIComponent(t.datasource)}`, i = JSON.stringify({
55
- name: n.name,
56
- subject_id: n.subjectId ?? null,
57
- tenant_id: n.tenantId ?? null,
58
- properties: JSON.stringify(n.properties),
59
- occurred_at: (n.occurredAt ?? /* @__PURE__ */ new Date()).toISOString()
60
- }), a = yield* e.tryPromise({
61
- try: () => fetch(r, {
62
- method: "POST",
63
- headers: {
64
- authorization: `Bearer ${t.token}`,
65
- "content-type": "application/json"
66
- },
67
- body: i
68
- }),
69
- catch: (e) => e
70
- });
71
- if (!a.ok) {
72
- let t = yield* e.tryPromise({
73
- try: () => a.text(),
74
- catch: () => "no body"
75
- });
76
- return yield* e.fail(/* @__PURE__ */ Error(`tinybird events API returned HTTP ${a.status}: ${t}`));
77
- }
78
- }).pipe(r("track")),
79
- aggregate: (n) => e.gen(function* () {
80
- let { data: r } = yield* e.tryPromise({
81
- try: () => d(t, t.pipes.aggregate, {
82
- event: n.event,
83
- from: n.range.from.toISOString(),
84
- to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
85
- metric_expr: u(n.metric),
86
- filter_sql: l(n.filter, n.tenantId)
87
- }),
88
- catch: (e) => e
89
- }), i = r[0]?.value ?? 0;
90
- return typeof i == "number" ? i : Number(i ?? 0);
91
- }).pipe(r("aggregate")),
92
- timeseries: (n) => e.gen(function* () {
93
- let { data: r } = yield* e.tryPromise({
94
- try: () => d(t, t.pipes.timeseries, {
95
- event: n.event,
96
- from: n.range.from.toISOString(),
97
- to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
98
- metric_expr: u(n.metric),
99
- filter_sql: l(n.filter, n.tenantId),
100
- bucket_fn: p(n.bucket)
101
- }),
102
- catch: (e) => e
103
- });
104
- return r.map((e) => ({
105
- bucketStart: new Date(e.bucket_start),
106
- value: typeof e.value == "number" ? e.value : Number(e.value ?? 0)
107
- }));
108
- }).pipe(r("timeseries")),
109
- topN: (n) => e.gen(function* () {
110
- let { data: r } = yield* e.tryPromise({
111
- try: () => d(t, t.pipes.topN, {
112
- event: n.event,
113
- from: n.range.from.toISOString(),
114
- to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
115
- group_expr: `JSONExtractString(properties, '${c(n.groupBy)}')`,
116
- metric_expr: n.metric === "count" ? "count()" : `sum(JSONExtractFloat(properties, '${c(n.metric.sum)}'))`,
117
- filter_sql: l(n.filter, n.tenantId),
118
- limit: Math.max(1, Math.floor(n.n))
119
- }),
120
- catch: (e) => e
121
- });
122
- return r.filter((e) => e.key !== null).map((e) => ({
123
- key: e.key,
124
- value: typeof e.value == "number" ? e.value : Number(e.value ?? 0)
125
- }));
126
- }).pipe(r("topN"))
127
- }), p = (e) => {
128
- switch (e) {
129
- case "minute": return "toStartOfMinute";
130
- case "hour": return "toStartOfHour";
131
- case "day": return "toStartOfDay";
132
- case "week": return "toStartOfWeek";
133
- case "month": return "toStartOfMonth";
134
- }
135
- }, m = {
1
+ import { assertIdentifier as e, buildTinybirdSink as t } from "./sink.js";
2
+ //#region src/index.ts
3
+ var n = {
136
4
  eu: "https://api.tinybird.co",
137
5
  "us-east": "https://api.us-east.tinybird.co",
138
6
  "us-west": "https://api.us-west.tinybird.co",
139
7
  "asia-southeast": "https://api.tinybird.co"
140
- }, h = (e) => {
141
- let t = e.apiUrl ?? m[e.region ?? "eu"] ?? "https://api.tinybird.co", n = {
142
- token: e.token,
143
- apiUrl: t,
144
- datasource: a(e.datasource ?? "voltro_events", "datasource"),
8
+ }, r = (r) => {
9
+ let i = r.apiUrl ?? n[r.region ?? "eu"] ?? "https://api.tinybird.co", a = {
10
+ token: r.token,
11
+ apiUrl: i,
12
+ datasource: e(r.datasource ?? "voltro_events", "datasource"),
145
13
  pipes: {
146
- aggregate: a(e.pipes?.aggregate ?? "events_aggregate", "aggregate pipe name"),
147
- timeseries: a(e.pipes?.timeseries ?? "events_timeseries", "timeseries pipe name"),
148
- topN: a(e.pipes?.topN ?? "events_topn", "topN pipe name")
14
+ aggregate: e(r.pipes?.aggregate ?? "events_aggregate", "aggregate pipe name"),
15
+ timeseries: e(r.pipes?.timeseries ?? "events_timeseries", "timeseries pipe name"),
16
+ topN: e(r.pipes?.topN ?? "events_topn", "topN pipe name")
149
17
  }
150
18
  };
151
19
  return {
152
20
  kind: "tinybird",
153
- build: (e) => f(n)
21
+ build: (e) => t(a)
154
22
  };
155
23
  };
156
24
  //#endregion
157
- export { h as tinybirdAnalytics };
25
+ export { r as tinybirdAnalytics };
package/dist/sink.js ADDED
@@ -0,0 +1,137 @@
1
+ import { Effect as e } from "effect";
2
+ import { AnalyticsError as t } from "@voltro/runtime";
3
+ //#region src/sink.ts
4
+ var n = "tinybird", r = (r) => e.mapError((e) => new t({
5
+ provider: n,
6
+ operation: r,
7
+ cause: e instanceof Error ? `${e.name}: ${e.message}` : String(e)
8
+ })), i = /^[A-Za-z_][A-Za-z0-9_]*$/, a = (e, r) => {
9
+ if (!i.test(e)) throw new t({
10
+ provider: n,
11
+ operation: "config",
12
+ cause: `invalid ${r} ${JSON.stringify(e)} — must match ${i.source} (letters, digits, underscore; no dots/slashes/quotes/spaces)`
13
+ });
14
+ return e;
15
+ }, o = /['\\]/, s = (e) => {
16
+ for (let t = 0; t < e.length; t++) if (e.charCodeAt(t) < 32) return !0;
17
+ return !1;
18
+ }, c = (e) => {
19
+ if (o.test(e) || s(e)) throw Error(`tinybird: invalid property key ${JSON.stringify(e)} — must not contain quotes, backslashes, or control characters`);
20
+ return e;
21
+ }, l = (e, t) => {
22
+ let n = [];
23
+ if (t != null && n.push(`tenant_id = '${t.replace(/'/g, "''")}'`), e) for (let [t, r] of Object.entries(e)) {
24
+ let e = String(r).replace(/'/g, "''");
25
+ n.push(`JSONExtractString(properties, '${c(t)}') = '${e}'`);
26
+ }
27
+ return n.length === 0 ? "" : ` AND ${n.join(" AND ")}`;
28
+ }, u = (e) => e === "count" ? "count()" : e === "unique" ? "uniqExact(subject_id)" : "sum" in e ? `sum(JSONExtractFloat(properties, '${c(e.sum)}'))` : `avg(JSONExtractFloat(properties, '${c(e.avg)}'))`, d = async (e, t, n) => {
29
+ let r = new URL(`${e.apiUrl}/v0/pipes/${t}.json`);
30
+ for (let [e, t] of Object.entries(n)) r.searchParams.set(e, String(t));
31
+ let i = await fetch(r.toString(), { headers: { authorization: `Bearer ${e.token}` } });
32
+ if (!i.ok) {
33
+ let e = await i.text().catch(() => "");
34
+ throw Error(`tinybird pipe ${t} returned HTTP ${i.status}: ${e}`);
35
+ }
36
+ return i.json();
37
+ }, f = (t) => ({
38
+ info: {
39
+ provider: n,
40
+ capabilities: {
41
+ track: !0,
42
+ aggregate: !0,
43
+ timeseries: !0,
44
+ topN: !0,
45
+ mirror: !1
46
+ },
47
+ detail: {
48
+ apiUrl: t.apiUrl,
49
+ datasource: t.datasource,
50
+ pipes: t.pipes
51
+ }
52
+ },
53
+ track: (n) => e.gen(function* () {
54
+ let r = `${t.apiUrl}/v0/events?name=${encodeURIComponent(t.datasource)}`, i = JSON.stringify({
55
+ name: n.name,
56
+ subject_id: n.subjectId ?? null,
57
+ tenant_id: n.tenantId ?? null,
58
+ properties: JSON.stringify(n.properties),
59
+ occurred_at: (n.occurredAt ?? /* @__PURE__ */ new Date()).toISOString()
60
+ }), a = yield* e.tryPromise({
61
+ try: () => fetch(r, {
62
+ method: "POST",
63
+ headers: {
64
+ authorization: `Bearer ${t.token}`,
65
+ "content-type": "application/json"
66
+ },
67
+ body: i
68
+ }),
69
+ catch: (e) => e
70
+ });
71
+ if (!a.ok) {
72
+ let t = yield* e.tryPromise({
73
+ try: () => a.text(),
74
+ catch: () => "no body"
75
+ });
76
+ return yield* e.fail(/* @__PURE__ */ Error(`tinybird events API returned HTTP ${a.status}: ${t}`));
77
+ }
78
+ }).pipe(r("track")),
79
+ aggregate: (n) => e.gen(function* () {
80
+ let { data: r } = yield* e.tryPromise({
81
+ try: () => d(t, t.pipes.aggregate, {
82
+ event: n.event,
83
+ from: n.range.from.toISOString(),
84
+ to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
85
+ metric_expr: u(n.metric),
86
+ filter_sql: l(n.filter, n.tenantId)
87
+ }),
88
+ catch: (e) => e
89
+ }), i = r[0]?.value ?? 0;
90
+ return typeof i == "number" ? i : Number(i ?? 0);
91
+ }).pipe(r("aggregate")),
92
+ timeseries: (n) => e.gen(function* () {
93
+ let { data: r } = yield* e.tryPromise({
94
+ try: () => d(t, t.pipes.timeseries, {
95
+ event: n.event,
96
+ from: n.range.from.toISOString(),
97
+ to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
98
+ metric_expr: u(n.metric),
99
+ filter_sql: l(n.filter, n.tenantId),
100
+ bucket_fn: p(n.bucket)
101
+ }),
102
+ catch: (e) => e
103
+ });
104
+ return r.map((e) => ({
105
+ bucketStart: new Date(e.bucket_start),
106
+ value: typeof e.value == "number" ? e.value : Number(e.value ?? 0)
107
+ }));
108
+ }).pipe(r("timeseries")),
109
+ topN: (n) => e.gen(function* () {
110
+ let { data: r } = yield* e.tryPromise({
111
+ try: () => d(t, t.pipes.topN, {
112
+ event: n.event,
113
+ from: n.range.from.toISOString(),
114
+ to: (n.range.to ?? /* @__PURE__ */ new Date()).toISOString(),
115
+ group_expr: `JSONExtractString(properties, '${c(n.groupBy)}')`,
116
+ metric_expr: n.metric === "count" ? "count()" : `sum(JSONExtractFloat(properties, '${c(n.metric.sum)}'))`,
117
+ filter_sql: l(n.filter, n.tenantId),
118
+ limit: Math.max(1, Math.floor(n.n))
119
+ }),
120
+ catch: (e) => e
121
+ });
122
+ return r.filter((e) => e.key !== null).map((e) => ({
123
+ key: e.key,
124
+ value: typeof e.value == "number" ? e.value : Number(e.value ?? 0)
125
+ }));
126
+ }).pipe(r("topN"))
127
+ }), p = (e) => {
128
+ switch (e) {
129
+ case "minute": return "toStartOfMinute";
130
+ case "hour": return "toStartOfHour";
131
+ case "day": return "toStartOfDay";
132
+ case "week": return "toStartOfWeek";
133
+ case "month": return "toStartOfMonth";
134
+ }
135
+ };
136
+ //#endregion
137
+ export { a as assertIdentifier, f as buildTinybirdSink };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/plugin-tinybird",
3
- "version": "0.84.0",
3
+ "version": "0.86.0",
4
4
  "description": "Tinybird AnalyticsSink. Hosted ClickHouse with the Tinybird Events API + Pipes for low-friction OLAP. Pay-as-you-go alternative to running your own ClickHouse.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -33,10 +33,10 @@
33
33
  "node": ">=24.0.0"
34
34
  },
35
35
  "dependencies": {
36
- "@voltro/runtime": "0.84.0"
36
+ "@voltro/runtime": "0.86.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "effect": "^3.22.2"
39
+ "effect": "4.0.1"
40
40
  },
41
41
  "publishConfig": {
42
42
  "access": "public"