@gscdump/analysis 0.36.0 → 0.36.1
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/analyzer/index.mjs +22 -15
- package/dist/default-registry.mjs +22 -15
- package/dist/index.mjs +22 -15
- package/package.json +4 -4
package/dist/analyzer/index.mjs
CHANGED
|
@@ -2011,24 +2011,31 @@ function coerceNumericCols(row) {
|
|
|
2011
2011
|
function shapeDataQuery(rows, extras, opts) {
|
|
2012
2012
|
let totalCount;
|
|
2013
2013
|
let cleaned;
|
|
2014
|
+
let totals;
|
|
2014
2015
|
if (opts.hasPrev) {
|
|
2015
2016
|
cleaned = rows.map(coerceNumericCols);
|
|
2016
2017
|
totalCount = Number((extras?.count?.[0])?.total ?? cleaned.length);
|
|
2018
|
+
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2019
|
+
totals = {
|
|
2020
|
+
clicks: Number(totalsRow.clicks ?? 0),
|
|
2021
|
+
impressions: Number(totalsRow.impressions ?? 0),
|
|
2022
|
+
ctr: Number(totalsRow.ctr ?? 0),
|
|
2023
|
+
position: Number(totalsRow.position ?? 0)
|
|
2024
|
+
};
|
|
2017
2025
|
} else {
|
|
2018
2026
|
const first = rows[0];
|
|
2019
2027
|
totalCount = Number(first?.totalCount ?? 0);
|
|
2028
|
+
totals = {
|
|
2029
|
+
clicks: Number(first?.totalClicks ?? 0),
|
|
2030
|
+
impressions: Number(first?.totalImpressions ?? 0),
|
|
2031
|
+
ctr: Number(first?.totalCtr ?? 0),
|
|
2032
|
+
position: Number(first?.totalPosition ?? 0)
|
|
2033
|
+
};
|
|
2020
2034
|
cleaned = rows.map((raw) => {
|
|
2021
2035
|
const { totalCount: _tc, totalClicks: _tclk, totalImpressions: _timp, totalCtr: _tctr, totalPosition: _tpos, sum_position: _sp, ...rest } = raw;
|
|
2022
2036
|
return coerceNumericCols(rest);
|
|
2023
2037
|
});
|
|
2024
2038
|
}
|
|
2025
|
-
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2026
|
-
const totals = {
|
|
2027
|
-
clicks: Number(totalsRow.clicks ?? 0),
|
|
2028
|
-
impressions: Number(totalsRow.impressions ?? 0),
|
|
2029
|
-
ctr: Number(totalsRow.ctr ?? 0),
|
|
2030
|
-
position: Number(totalsRow.position ?? 0)
|
|
2031
|
-
};
|
|
2032
2039
|
const extrasResults = [];
|
|
2033
2040
|
if (extras?.canonicalExtras) extrasResults.push({
|
|
2034
2041
|
key: "canonicalExtras",
|
|
@@ -2046,20 +2053,20 @@ function buildDataQueryPlan(params, options) {
|
|
|
2046
2053
|
const state = requireBuilderState(params.q, "data-query");
|
|
2047
2054
|
if (state.dimensions.includes("date")) throw new Error("data-query: date dimension not supported; use data-detail");
|
|
2048
2055
|
const prev = optionalBuilderState(params.qc, "data-query", "qc");
|
|
2049
|
-
const
|
|
2050
|
-
const extras = buildExtrasQueries(state, options);
|
|
2051
|
-
const extraQueries = [{
|
|
2052
|
-
name: "totals",
|
|
2053
|
-
sql: totals.sql,
|
|
2054
|
-
params: totals.params
|
|
2055
|
-
}, ...extras.map((extra) => ({
|
|
2056
|
+
const extraQueries = [...buildExtrasQueries(state, options).map((extra) => ({
|
|
2056
2057
|
name: extra.key,
|
|
2057
2058
|
sql: extra.sql,
|
|
2058
2059
|
params: extra.params
|
|
2059
2060
|
}))];
|
|
2060
2061
|
const tableKey = options.adapter.inferTable(state.dimensions);
|
|
2061
2062
|
if (prev) {
|
|
2063
|
+
const totals = buildTotalsSql(state, options);
|
|
2062
2064
|
const comparison = resolveComparisonSQL(state, prev, options, params.comparisonFilter);
|
|
2065
|
+
extraQueries.unshift({
|
|
2066
|
+
name: "totals",
|
|
2067
|
+
sql: totals.sql,
|
|
2068
|
+
params: totals.params
|
|
2069
|
+
});
|
|
2063
2070
|
extraQueries.push({
|
|
2064
2071
|
name: "count",
|
|
2065
2072
|
sql: comparison.countSql,
|
|
@@ -2122,7 +2129,7 @@ function shapeDataQueryRowResults(rowMap, params) {
|
|
|
2122
2129
|
};
|
|
2123
2130
|
const state = requireBuilderState(params.q, "data-query");
|
|
2124
2131
|
const dims = state.dimensions;
|
|
2125
|
-
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("
|
|
2132
|
+
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("");
|
|
2126
2133
|
const prevByKey = /* @__PURE__ */ new Map();
|
|
2127
2134
|
for (const r of rowMap.prevMain ?? []) prevByKey.set(keyOf(r), r);
|
|
2128
2135
|
const filter = params.comparisonFilter;
|
|
@@ -2011,24 +2011,31 @@ function coerceNumericCols(row) {
|
|
|
2011
2011
|
function shapeDataQuery(rows, extras, opts) {
|
|
2012
2012
|
let totalCount;
|
|
2013
2013
|
let cleaned;
|
|
2014
|
+
let totals;
|
|
2014
2015
|
if (opts.hasPrev) {
|
|
2015
2016
|
cleaned = rows.map(coerceNumericCols);
|
|
2016
2017
|
totalCount = Number((extras?.count?.[0])?.total ?? cleaned.length);
|
|
2018
|
+
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2019
|
+
totals = {
|
|
2020
|
+
clicks: Number(totalsRow.clicks ?? 0),
|
|
2021
|
+
impressions: Number(totalsRow.impressions ?? 0),
|
|
2022
|
+
ctr: Number(totalsRow.ctr ?? 0),
|
|
2023
|
+
position: Number(totalsRow.position ?? 0)
|
|
2024
|
+
};
|
|
2017
2025
|
} else {
|
|
2018
2026
|
const first = rows[0];
|
|
2019
2027
|
totalCount = Number(first?.totalCount ?? 0);
|
|
2028
|
+
totals = {
|
|
2029
|
+
clicks: Number(first?.totalClicks ?? 0),
|
|
2030
|
+
impressions: Number(first?.totalImpressions ?? 0),
|
|
2031
|
+
ctr: Number(first?.totalCtr ?? 0),
|
|
2032
|
+
position: Number(first?.totalPosition ?? 0)
|
|
2033
|
+
};
|
|
2020
2034
|
cleaned = rows.map((raw) => {
|
|
2021
2035
|
const { totalCount: _tc, totalClicks: _tclk, totalImpressions: _timp, totalCtr: _tctr, totalPosition: _tpos, sum_position: _sp, ...rest } = raw;
|
|
2022
2036
|
return coerceNumericCols(rest);
|
|
2023
2037
|
});
|
|
2024
2038
|
}
|
|
2025
|
-
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2026
|
-
const totals = {
|
|
2027
|
-
clicks: Number(totalsRow.clicks ?? 0),
|
|
2028
|
-
impressions: Number(totalsRow.impressions ?? 0),
|
|
2029
|
-
ctr: Number(totalsRow.ctr ?? 0),
|
|
2030
|
-
position: Number(totalsRow.position ?? 0)
|
|
2031
|
-
};
|
|
2032
2039
|
const extrasResults = [];
|
|
2033
2040
|
if (extras?.canonicalExtras) extrasResults.push({
|
|
2034
2041
|
key: "canonicalExtras",
|
|
@@ -2046,20 +2053,20 @@ function buildDataQueryPlan(params, options) {
|
|
|
2046
2053
|
const state = requireBuilderState(params.q, "data-query");
|
|
2047
2054
|
if (state.dimensions.includes("date")) throw new Error("data-query: date dimension not supported; use data-detail");
|
|
2048
2055
|
const prev = optionalBuilderState(params.qc, "data-query", "qc");
|
|
2049
|
-
const
|
|
2050
|
-
const extras = buildExtrasQueries(state, options);
|
|
2051
|
-
const extraQueries = [{
|
|
2052
|
-
name: "totals",
|
|
2053
|
-
sql: totals.sql,
|
|
2054
|
-
params: totals.params
|
|
2055
|
-
}, ...extras.map((extra) => ({
|
|
2056
|
+
const extraQueries = [...buildExtrasQueries(state, options).map((extra) => ({
|
|
2056
2057
|
name: extra.key,
|
|
2057
2058
|
sql: extra.sql,
|
|
2058
2059
|
params: extra.params
|
|
2059
2060
|
}))];
|
|
2060
2061
|
const tableKey = options.adapter.inferTable(state.dimensions);
|
|
2061
2062
|
if (prev) {
|
|
2063
|
+
const totals = buildTotalsSql(state, options);
|
|
2062
2064
|
const comparison = resolveComparisonSQL(state, prev, options, params.comparisonFilter);
|
|
2065
|
+
extraQueries.unshift({
|
|
2066
|
+
name: "totals",
|
|
2067
|
+
sql: totals.sql,
|
|
2068
|
+
params: totals.params
|
|
2069
|
+
});
|
|
2063
2070
|
extraQueries.push({
|
|
2064
2071
|
name: "count",
|
|
2065
2072
|
sql: comparison.countSql,
|
|
@@ -2122,7 +2129,7 @@ function shapeDataQueryRowResults(rowMap, params) {
|
|
|
2122
2129
|
};
|
|
2123
2130
|
const state = requireBuilderState(params.q, "data-query");
|
|
2124
2131
|
const dims = state.dimensions;
|
|
2125
|
-
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("
|
|
2132
|
+
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("");
|
|
2126
2133
|
const prevByKey = /* @__PURE__ */ new Map();
|
|
2127
2134
|
for (const r of rowMap.prevMain ?? []) prevByKey.set(keyOf(r), r);
|
|
2128
2135
|
const filter = params.comparisonFilter;
|
package/dist/index.mjs
CHANGED
|
@@ -2243,24 +2243,31 @@ function coerceNumericCols(row) {
|
|
|
2243
2243
|
function shapeDataQuery(rows, extras, opts) {
|
|
2244
2244
|
let totalCount;
|
|
2245
2245
|
let cleaned;
|
|
2246
|
+
let totals;
|
|
2246
2247
|
if (opts.hasPrev) {
|
|
2247
2248
|
cleaned = rows.map(coerceNumericCols);
|
|
2248
2249
|
totalCount = Number((extras?.count?.[0])?.total ?? cleaned.length);
|
|
2250
|
+
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2251
|
+
totals = {
|
|
2252
|
+
clicks: Number(totalsRow.clicks ?? 0),
|
|
2253
|
+
impressions: Number(totalsRow.impressions ?? 0),
|
|
2254
|
+
ctr: Number(totalsRow.ctr ?? 0),
|
|
2255
|
+
position: Number(totalsRow.position ?? 0)
|
|
2256
|
+
};
|
|
2249
2257
|
} else {
|
|
2250
2258
|
const first = rows[0];
|
|
2251
2259
|
totalCount = Number(first?.totalCount ?? 0);
|
|
2260
|
+
totals = {
|
|
2261
|
+
clicks: Number(first?.totalClicks ?? 0),
|
|
2262
|
+
impressions: Number(first?.totalImpressions ?? 0),
|
|
2263
|
+
ctr: Number(first?.totalCtr ?? 0),
|
|
2264
|
+
position: Number(first?.totalPosition ?? 0)
|
|
2265
|
+
};
|
|
2252
2266
|
cleaned = rows.map((raw) => {
|
|
2253
2267
|
const { totalCount: _tc, totalClicks: _tclk, totalImpressions: _timp, totalCtr: _tctr, totalPosition: _tpos, sum_position: _sp, ...rest } = raw;
|
|
2254
2268
|
return coerceNumericCols(rest);
|
|
2255
2269
|
});
|
|
2256
2270
|
}
|
|
2257
|
-
const totalsRow = extras?.totals?.[0] ?? {};
|
|
2258
|
-
const totals = {
|
|
2259
|
-
clicks: Number(totalsRow.clicks ?? 0),
|
|
2260
|
-
impressions: Number(totalsRow.impressions ?? 0),
|
|
2261
|
-
ctr: Number(totalsRow.ctr ?? 0),
|
|
2262
|
-
position: Number(totalsRow.position ?? 0)
|
|
2263
|
-
};
|
|
2264
2271
|
const extrasResults = [];
|
|
2265
2272
|
if (extras?.canonicalExtras) extrasResults.push({
|
|
2266
2273
|
key: "canonicalExtras",
|
|
@@ -2278,20 +2285,20 @@ function buildDataQueryPlan(params, options) {
|
|
|
2278
2285
|
const state = requireBuilderState(params.q, "data-query");
|
|
2279
2286
|
if (state.dimensions.includes("date")) throw new Error("data-query: date dimension not supported; use data-detail");
|
|
2280
2287
|
const prev = optionalBuilderState(params.qc, "data-query", "qc");
|
|
2281
|
-
const
|
|
2282
|
-
const extras = buildExtrasQueries(state, options);
|
|
2283
|
-
const extraQueries = [{
|
|
2284
|
-
name: "totals",
|
|
2285
|
-
sql: totals.sql,
|
|
2286
|
-
params: totals.params
|
|
2287
|
-
}, ...extras.map((extra) => ({
|
|
2288
|
+
const extraQueries = [...buildExtrasQueries(state, options).map((extra) => ({
|
|
2288
2289
|
name: extra.key,
|
|
2289
2290
|
sql: extra.sql,
|
|
2290
2291
|
params: extra.params
|
|
2291
2292
|
}))];
|
|
2292
2293
|
const tableKey = options.adapter.inferTable(state.dimensions);
|
|
2293
2294
|
if (prev) {
|
|
2295
|
+
const totals = buildTotalsSql(state, options);
|
|
2294
2296
|
const comparison = resolveComparisonSQL(state, prev, options, params.comparisonFilter);
|
|
2297
|
+
extraQueries.unshift({
|
|
2298
|
+
name: "totals",
|
|
2299
|
+
sql: totals.sql,
|
|
2300
|
+
params: totals.params
|
|
2301
|
+
});
|
|
2295
2302
|
extraQueries.push({
|
|
2296
2303
|
name: "count",
|
|
2297
2304
|
sql: comparison.countSql,
|
|
@@ -2354,7 +2361,7 @@ function shapeDataQueryRowResults(rowMap, params) {
|
|
|
2354
2361
|
};
|
|
2355
2362
|
const state = requireBuilderState(params.q, "data-query");
|
|
2356
2363
|
const dims = state.dimensions;
|
|
2357
|
-
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("
|
|
2364
|
+
const keyOf = (row) => dims.map((d) => String(row[d] ?? "")).join("");
|
|
2358
2365
|
const prevByKey = /* @__PURE__ */ new Map();
|
|
2359
2366
|
for (const r of rowMap.prevMain ?? []) prevByKey.set(keyOf(r), r);
|
|
2360
2367
|
const filter = params.comparisonFilter;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/analysis",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.36.
|
|
4
|
+
"version": "0.36.1",
|
|
5
5
|
"description": "GSC analyzers — striking-distance, opportunity, movers, decay, brand, clustering, concentration, seasonality. Pure row-based + DuckDB-native.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"drizzle-orm": "1.0.0-rc.3",
|
|
78
78
|
"pluralize": "^8.0.0",
|
|
79
|
-
"@gscdump/engine
|
|
80
|
-
"@gscdump/engine": "0.36.
|
|
81
|
-
"gscdump": "0.36.
|
|
79
|
+
"@gscdump/engine": "0.36.1",
|
|
80
|
+
"@gscdump/engine-gsc-api": "0.36.1",
|
|
81
|
+
"gscdump": "0.36.1"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"vitest": "^4.1.9"
|