ga4-export-fixer 0.4.2-dev.0 → 0.4.2-dev.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.
@@ -2,7 +2,18 @@
2
2
  Handling event and session parameters
3
3
  */
4
4
 
5
- // filter the event_params array by the selected parameters
5
+ /**
6
+ * Generates a SQL expression that filters the `event_params` array by the given parameter names.
7
+ *
8
+ * When filterType is 'include', only parameters whose key matches one of the given names are kept.
9
+ * When filterType is 'exclude', parameters whose key matches are removed. If the params array is
10
+ * empty with 'exclude', the original `event_params` column is returned unfiltered.
11
+ *
12
+ * @param {string[]} params - Array of event parameter names to include or exclude.
13
+ * @param {'include'|'exclude'} filterType - Whether to include or exclude the listed parameters.
14
+ * @returns {string} SQL expression that produces a filtered event_params array.
15
+ * @throws {Error} If params is not an array of strings, or if filterType is not 'include' or 'exclude'.
16
+ */
6
17
  const filterEventParams = (params, filterType) => {
7
18
  if (!Array.isArray(params) || !params.every(p => typeof p === 'string')) {
8
19
  throw new Error("filterEventParams: 'params' must be an array of strings (empty array allowed).");
@@ -131,8 +142,8 @@ Aggregation
131
142
  * Throws an error if required parameters are missing or an unsupported aggregation type is requested.
132
143
  *
133
144
  * @param {string} column - The name of the column to aggregate.
134
- * @param {string} aggregateType - Type of aggregation ('max', 'min', 'first', 'last', or 'any').
135
- * @param {string} timestampColumn - Column to use for ordering when aggregateType is 'first' or 'last'.
145
+ * @param {'max'|'min'|'first'|'last'|'any'} aggregateType - Type of aggregation.
146
+ * @param {string} [timestampColumn] - Column to use for ordering. Required when aggregateType is 'first' or 'last'.
136
147
  * @returns {string} A SQL expression for the requested aggregation.
137
148
  * @throws {Error} If required parameters are missing or an unsupported aggregateType is provided.
138
149
  *
@@ -182,7 +193,20 @@ const aggregateValue = (column, aggregateType, timestampColumn) => {
182
193
  throw new Error(`aggregateValue: Unsupported aggregateType '${aggregateType}'. Supported values are 'max', 'min', 'first', 'last', and 'any'.`);
183
194
  };
184
195
 
185
- // perform aggregations on an array of values
196
+ /**
197
+ * Generates SQL aggregation expressions for an array of column specifications.
198
+ *
199
+ * Each item in the array is passed to {@link aggregateValue} and optionally aliased.
200
+ * The results are joined with commas for use in a SELECT clause.
201
+ *
202
+ * @param {Object[]} values - Array of aggregation specifications.
203
+ * @param {string} values[].column - The column to aggregate.
204
+ * @param {'max'|'min'|'first'|'last'|'any'} values[].aggregateType - Type of aggregation.
205
+ * @param {string} [values[].timestampColumn] - Column for ordering. Required for 'first'/'last'.
206
+ * @param {string} [values[].alias] - Optional output alias (appended as `AS alias`).
207
+ * @returns {string} Comma-separated SQL aggregation expressions.
208
+ * @throws {Error} If values is not an array.
209
+ */
186
210
  const aggregateValues = (values) => {
187
211
  if (Array.isArray(values)) {
188
212
  return values.map(value => {
@@ -2,9 +2,11 @@
2
2
  Date and time
3
3
  */
4
4
 
5
+ /**
6
+ * SQL expression that casts the GA4 `event_date` string column to a DATE using YYYYMMDD format.
7
+ */
5
8
  const eventDate = `cast(event_date as date format 'YYYYMMDD')`;
6
9
 
7
- // get the most accurate event timestamp
8
10
  /**
9
11
  * Returns a SQL expression for the event timestamp in microseconds.
10
12
  *
@@ -28,7 +30,6 @@ const getEventTimestampMicros = (customTimestampParameter) => {
28
30
  return 'event_timestamp';
29
31
  };
30
32
 
31
- // datetime in the local time zone
32
33
  /**
33
34
  * Returns a SQL expression representing the event's local datetime (in the specified time zone),
34
35
  * derived from the default event_timestamp field.
@@ -37,7 +38,7 @@ const getEventTimestampMicros = (customTimestampParameter) => {
37
38
  * - No custom timestamp parameter from event_params is used; the extraction is strictly from event_timestamp.
38
39
  * - The returned expression converts event_timestamp to a TIMESTAMP, then extracts the DATETIME in the desired time zone.
39
40
  *
40
- * @param {Object} config - Optional configuration with a timezone property (defaults to 'Etc/UTC').
41
+ * @param {Object} [config] - Optional configuration with a timezone property (defaults to 'Etc/UTC').
41
42
  * @param {string} [config.timezone] - IANA time zone string (e.g., 'Europe/Helsinki'). Defaults to 'Etc/UTC'.
42
43
  * @returns {string} SQL expression for the local datetime of the event.
43
44
  *
@@ -1,9 +1,8 @@
1
1
  const { unnestEventParam } = require('./params');
2
2
 
3
- /*
4
- Common identifiers
5
- */
6
-
3
+ /**
4
+ * SQL expression that builds a session ID by concatenating `user_pseudo_id` with the `ga_session_id` event parameter.
5
+ */
7
6
  const sessionId = `concat(user_pseudo_id, (select value.int_value from unnest(event_params) where key = 'ga_session_id'))`;
8
7
 
9
8
  /*
@@ -58,7 +57,7 @@ Check if GA4 data is "final" and is not expected to change anymore
58
57
  * @param {'EXPORT_TYPE'|'DAY_THRESHOLD'} detectionMethod - The method to use for finality determination.
59
58
  * 'EXPORT_TYPE': Uses patterns in _table_suffix (e.g., 'intraday_%', 'fresh_%').
60
59
  * 'DAY_THRESHOLD': Uses date difference between the current date and event_date.
61
- * @param {number} [dayThreshold=3] - (Only for 'DAY_THRESHOLD') Number of days after which data is considered final.
60
+ * @param {number} [dayThreshold] - (Only for 'DAY_THRESHOLD') Number of days after which data is considered final. Required when detectionMethod is 'DAY_THRESHOLD'.
62
61
  * @returns {string} SQL expression that evaluates to TRUE if the data is final, otherwise FALSE.
63
62
  *
64
63
  * @throws {Error} If an unsupported detectionMethod is provided.
@@ -141,6 +140,15 @@ const isGa4ExportColumn = (columnName) => {
141
140
  return ga4ExportColumns.includes(columnName);
142
141
  };
143
142
 
143
+ /**
144
+ * Generates a SQL CASE expression that determines the GA4 export type from a table suffix.
145
+ *
146
+ * Returns 'intraday' for suffixes like 'intraday_%', 'fresh' for 'fresh_%',
147
+ * and 'daily' for 8-digit date suffixes (YYYYMMDD).
148
+ *
149
+ * @param {string} tableSuffix - SQL expression or column reference for the table suffix (e.g., '_table_suffix').
150
+ * @returns {string} SQL CASE expression that evaluates to 'intraday', 'fresh', or 'daily'.
151
+ */
144
152
  const getGa4ExportType = (tableSuffix) => {
145
153
  return `case
146
154
  when ${tableSuffix} like 'intraday_%' then 'intraday'
package/helpers/params.js CHANGED
@@ -2,7 +2,20 @@
2
2
  Unnesting parameters
3
3
  */
4
4
 
5
- // unnest any parameter from the selected params array
5
+ /**
6
+ * Generates a SQL subquery to extract a value from a parameter array by key.
7
+ *
8
+ * When a dataType is provided, the value is extracted from the corresponding typed column
9
+ * (e.g., `value.string_value`, `value.int_value`). When omitted, a coalesce across all
10
+ * value columns is returned, cast as a string.
11
+ *
12
+ * @param {string} keyName - The parameter key to look up in the array.
13
+ * @param {string} paramsArray - The SQL expression for the parameter array to unnest (e.g., 'event_params').
14
+ * @param {string} [dataType] - Optional data type: 'string', 'int', 'int64', 'double', 'float', or 'float64'.
15
+ * If omitted, returns the value converted to a string.
16
+ * @returns {string} SQL subquery expression that extracts the parameter value.
17
+ * @throws {Error} If keyName or paramsArray is not a non-empty string, or if dataType is unsupported.
18
+ */
6
19
  const unnestParam = (keyName, paramsArray, dataType) => {
7
20
  if (typeof keyName !== 'string' || keyName.trim() === '') {
8
21
  throw new Error("unnestParam: 'keyName' is required and must be a non-empty string.");
@@ -30,14 +43,30 @@ const unnestParam = (keyName, paramsArray, dataType) => {
30
43
  }
31
44
  };
32
45
 
33
- // event_params and session_params
34
-
35
- // unnest a param from the event_params array
46
+ /**
47
+ * Extracts a value from the `event_params` array by key.
48
+ *
49
+ * Supported types: 'string', 'int', 'int64', 'double', 'float', 'float64'.
50
+ * If omitted, returns the value converted to a string.
51
+ *
52
+ * @param {string} keyName - The event parameter key to look up.
53
+ * @param {string} [dataType] - Optional data type for the extracted value.
54
+ * @returns {string} SQL subquery expression that extracts the event parameter value.
55
+ */
36
56
  const unnestEventParam = (keyName, dataType) => {
37
57
  return unnestParam(keyName, 'event_params', dataType);
38
58
  };
39
59
 
40
- // unnest a param from the session_params array
60
+ /**
61
+ * Extracts a value from the `session_params` array by key.
62
+ *
63
+ * Supported types: 'string', 'int', 'int64', 'double', 'float', 'float64'.
64
+ * If omitted, returns the value converted to a string.
65
+ *
66
+ * @param {string} keyName - The session parameter key to look up.
67
+ * @param {string} [dataType] - Optional data type for the extracted value.
68
+ * @returns {string} SQL subquery expression that extracts the session parameter value.
69
+ */
41
70
  const unnestSessionParam = (keyName, dataType) => {
42
71
  return unnestParam(keyName, 'session_params', dataType);
43
72
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ga4-export-fixer",
3
- "version": "0.4.2-dev.0",
3
+ "version": "0.4.2-dev.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "files": [