@gscdump/cloudflare 0.25.8 → 0.25.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.
@@ -56,6 +56,37 @@ function partitionWhere(q) {
56
56
  ]
57
57
  };
58
58
  }
59
+ function facetPredicate(query) {
60
+ const facets = query.facets;
61
+ if (!facets?.length) return {
62
+ sql: "",
63
+ params: []
64
+ };
65
+ const parts = [];
66
+ const params = [];
67
+ for (const f of facets) {
68
+ const col = dimColumn(f.column);
69
+ switch (f.op) {
70
+ case "eq":
71
+ parts.push(`${col} = ?`);
72
+ params.push(f.value);
73
+ break;
74
+ case "regex":
75
+ parts.push(`regexp_matches(LOWER(${col}), ?)`);
76
+ params.push(f.value);
77
+ break;
78
+ case "notRegex":
79
+ parts.push(`NOT regexp_matches(LOWER(${col}), ?)`);
80
+ params.push(f.value);
81
+ break;
82
+ default: throw new Error(`[archetype-sql] unknown facet op: ${f.op}`);
83
+ }
84
+ }
85
+ return {
86
+ sql: parts.length ? ` AND ${parts.join(" AND ")}` : "",
87
+ params
88
+ };
89
+ }
59
90
  function buildSiteDailyTimeseries(q) {
60
91
  const w = partitionWhere(q);
61
92
  const metrics = q.metrics.map(metricExpr).join(", ");
@@ -109,11 +140,12 @@ function buildTopNBreakdown(q) {
109
140
  const col = dimColumn(q.dimension);
110
141
  const metrics = q.metrics.map(metricExpr).join(", ");
111
142
  const order = `${orderMetricExpr(q.orderBy.metric)} ${q.orderBy.dir.toUpperCase()}`;
112
- let sql = `SELECT ${col}, ${metrics} FROM ${TABLE_PLACEHOLDER} WHERE ${w.clause} GROUP BY ${col} ORDER BY ${order} LIMIT ${Math.max(0, Math.floor(q.limit))}`;
143
+ const facet = facetPredicate(q);
144
+ let sql = `SELECT ${col}, ${metrics} FROM ${TABLE_PLACEHOLDER} WHERE ${w.clause}${facet.sql} GROUP BY ${col} ORDER BY ${order} LIMIT ${Math.max(0, Math.floor(q.limit))}`;
113
145
  if (q.offset && q.offset > 0) sql += ` OFFSET ${Math.floor(q.offset)}`;
114
146
  return {
115
147
  table,
116
- params: w.params,
148
+ params: [...w.params, ...facet.params],
117
149
  sql
118
150
  };
119
151
  }
@@ -168,6 +200,9 @@ function buildTwoDimensionDetail(q) {
168
200
  clause += ` AND query = ?`;
169
201
  params.push(q.filter.query);
170
202
  }
203
+ const facet = facetPredicate(q);
204
+ clause += facet.sql;
205
+ params.push(...facet.params);
171
206
  let sql = `SELECT url, query, ${q.metrics.map(metricExpr).join(", ")} FROM ${TABLE_PLACEHOLDER} WHERE ${clause} GROUP BY url, query`;
172
207
  if (q.orderBy) sql += ` ORDER BY ${orderMetricExpr(q.orderBy.metric)} ${q.orderBy.dir.toUpperCase()}`;
173
208
  if (q.limit && q.limit > 0) sql += ` LIMIT ${Math.floor(q.limit)}`;
@@ -198,7 +233,8 @@ function resolveServerTailEngine(query) {
198
233
  if (cls === "cloud-only") throw new ServerTailRoutingError(`archetype '${query.archetype}' is cloud-only — not a server-tail query`);
199
234
  if (cls === "duckdb") return "duckdb";
200
235
  if (query.archetype === "top-n-breakdown" && query.offset && query.offset > 0) return "duckdb";
201
- if (query.facets && query.facets.length > 0) return "duckdb";
236
+ const facets = query.facets;
237
+ if (facets && facets.length > 0) return "duckdb";
202
238
  return "r2-sql";
203
239
  }
204
240
  function sourceFor(engine) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gscdump/cloudflare",
3
3
  "type": "module",
4
- "version": "0.25.8",
4
+ "version": "0.25.10",
5
5
  "description": "Cloudflare-Workers-flavored helpers for the gscdump analytics stack: AnalyticsEnv binding contract, R2 SigV4 presigner, size-hint HMAC, DuckDB Workers shims, engine factory.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -46,11 +46,11 @@
46
46
  "dependencies": {
47
47
  "@uwdata/flechette": "^2.5.0",
48
48
  "aws4fetch": "^1.0.20",
49
- "@gscdump/contracts": "0.25.8",
50
- "@gscdump/engine": "0.25.8",
51
- "@gscdump/engine-sqlite": "0.25.8",
52
- "@gscdump/sdk": "0.25.8",
53
- "gscdump": "0.25.8"
49
+ "@gscdump/contracts": "0.25.10",
50
+ "@gscdump/engine-sqlite": "0.25.10",
51
+ "@gscdump/sdk": "0.25.10",
52
+ "gscdump": "0.25.10",
53
+ "@gscdump/engine": "0.25.10"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@cloudflare/vitest-pool-workers": "^0.16.10",