@firebaseextensions/firestore-bigquery-change-tracker 1.1.29 → 1.1.31

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.
@@ -35,7 +35,8 @@ class Partitioning {
35
35
  }
36
36
  isValidPartitionTypeDate(value) {
37
37
  /* Check if valid timestamp value from sdk */
38
- if (value instanceof firebase.firestore.Timestamp)
38
+ // if (value instanceof firebase.firestore.Timestamp) return true;
39
+ if (isTimestampLike(value))
39
40
  return true;
40
41
  /* Check if valid date/timstemap, expedted result from production */
41
42
  if (value && value.toDate && value.toDate())
@@ -62,10 +63,14 @@ class Partitioning {
62
63
  /* No custom config has been set, use partition value option only */
63
64
  if (hasNoCustomOptions)
64
65
  return true;
65
- /* check if all options have been provided to be */
66
- return (!!timePartitioningField &&
67
- !!timePartitioningFieldType &&
68
- !!timePartitioningFirestoreField);
66
+ /* check if all valid combinations have been provided*/
67
+ const hasOnlyTimestamp = timePartitioningField === "timestamp" &&
68
+ !timePartitioningFieldType &&
69
+ !timePartitioningFirestoreField;
70
+ return (hasOnlyTimestamp ||
71
+ (!!timePartitioningField &&
72
+ !!timePartitioningFieldType &&
73
+ !!timePartitioningFirestoreField));
69
74
  }
70
75
  hasValidTimePartitionOption() {
71
76
  const { timePartitioning } = this.config;
@@ -137,7 +142,7 @@ class Partitioning {
137
142
  Extracts a valid Partition field from the Document Change Event.
138
143
  Matches result based on a pre-defined Firestore field matching the event data object.
139
144
  Return an empty object if no field name or value provided.
140
- Returns empty object if not a string or timestamp
145
+ Returns empty object if not a string or timestamp (or result of serializing a timestamp)
141
146
  Logs warning if not a valid datatype
142
147
  Delete changes events have no data, return early as cannot partition on empty data.
143
148
  **/
@@ -155,6 +160,12 @@ class Partitioning {
155
160
  }
156
161
  if (this.isValidPartitionTypeDate(fieldValue)) {
157
162
  /* Return converted console value */
163
+ if (isTimestampLike(fieldValue)) {
164
+ const convertedTimestampFieldValue = convertToTimestamp(fieldValue);
165
+ return {
166
+ [fieldName]: this.convertDateValue(convertedTimestampFieldValue.toDate()),
167
+ };
168
+ }
158
169
  if (fieldValue.toDate) {
159
170
  return { [fieldName]: this.convertDateValue(fieldValue.toDate()) };
160
171
  }
@@ -173,53 +184,53 @@ class Partitioning {
173
184
  async addPartitioningToSchema(fields = []) {
174
185
  /** check if class has valid table reference */
175
186
  if (!this.hasValidTableReference())
176
- return Promise.resolve();
187
+ return;
177
188
  /** return if table is already partitioned **/
178
189
  if (await this.isTablePartitioned())
179
- return Promise.resolve();
190
+ return;
180
191
  /** return if an invalid partition type has been requested**/
181
192
  if (!this.hasValidTimePartitionType())
182
- return Promise.resolve();
193
+ return;
183
194
  /** Return if invalid partitioning and field type combination */
184
195
  if (this.hasHourAndDatePartitionConfig())
185
- return Promise.resolve();
196
+ return;
186
197
  /** return if an invalid partition type has been requested**/
187
198
  if (!this.hasValidCustomPartitionConfig())
188
- return Promise.resolve();
199
+ return;
189
200
  /** return if an invalid partition type has been requested**/
190
201
  if (!this.hasValidCustomPartitionConfig())
191
- return Promise.resolve();
202
+ return;
192
203
  /** update fields with new schema option ** */
193
204
  if (!this.hasValidTimePartitionOption())
194
- return Promise.resolve();
205
+ return;
195
206
  /* Check if partition field has been provided */
196
207
  if (!this.config.timePartitioningField)
197
- return Promise.resolve();
208
+ return;
198
209
  // if (await !this.hasExistingSchema) return Promise.resolve();
199
210
  // Field already exists on schema, skip
200
211
  if (this.customFieldExists(fields))
201
- return Promise.resolve();
212
+ return;
202
213
  fields.push((0, schema_1.getNewPartitionField)(this.config));
203
214
  /** log successful addition of partition column */
204
215
  logs.addPartitionFieldColumn(this.table.id, this.config.timePartitioningField);
205
- return Promise.resolve();
216
+ return;
206
217
  }
207
218
  async updateTableMetadata(options) {
208
219
  /** return if table is already partitioned **/
209
220
  if (await this.isTablePartitioned())
210
- return Promise.resolve();
221
+ return;
211
222
  /** return if an invalid partition type has been requested**/
212
223
  if (!this.hasValidTimePartitionType())
213
- return Promise.resolve();
224
+ return;
214
225
  /** update fields with new schema option ** */
215
226
  if (!this.hasValidTimePartitionOption())
216
- return Promise.resolve();
227
+ return;
217
228
  /** Return if invalid partitioning and field type combination */
218
229
  if (this.hasHourAndDatePartitionConfig())
219
- return Promise.resolve();
230
+ return;
220
231
  /** return if an invalid partition type has been requested**/
221
232
  if (!this.hasValidCustomPartitionConfig())
222
- return Promise.resolve();
233
+ return;
223
234
  // if (await !this.hasExistingSchema) return Promise.resolve();
224
235
  if (this.config.timePartitioning) {
225
236
  options.timePartitioning = { type: this.config.timePartitioning };
@@ -234,3 +245,18 @@ class Partitioning {
234
245
  }
235
246
  }
236
247
  exports.Partitioning = Partitioning;
248
+ const isTimestampLike = (value) => {
249
+ if (value instanceof firebase.firestore.Timestamp)
250
+ return true;
251
+ return (typeof value === "object" &&
252
+ value !== null &&
253
+ "_seconds" in value &&
254
+ typeof value["_seconds"] === "number" &&
255
+ "_nanoseconds" in value &&
256
+ typeof value["_nanoseconds"] === "number");
257
+ };
258
+ const convertToTimestamp = (value) => {
259
+ if (value instanceof firebase.firestore.Timestamp)
260
+ return value;
261
+ return new firebase.firestore.Timestamp(value._seconds, value._nanoseconds);
262
+ };
package/package.json CHANGED
@@ -5,14 +5,14 @@
5
5
  "url": "github.com/firebase/extensions.git",
6
6
  "directory": "firestore-bigquery-export/firestore-bigquery-change-tracker"
7
7
  },
8
- "version": "1.1.29",
8
+ "version": "1.1.31",
9
9
  "description": "Core change-tracker library for Cloud Firestore Collection BigQuery Exports",
10
10
  "main": "./lib/index.js",
11
11
  "scripts": {
12
12
  "build": "npm run clean && npm run compile",
13
13
  "clean": "rimraf lib",
14
14
  "compile": "tsc",
15
- "test:local": "firebase ext:dev:emulators:exec ./node_modules/.bin/jest --test-params=./src/__tests__/emulator-params.env --project=extensions-testing --config=./src/__tests__/firebase.json",
15
+ "test:local": "jest",
16
16
  "prepare": "npm run build",
17
17
  "generate-stresstest-table": "bq query --project_id=extensions-testing --use_legacy_sql=false < ./src/__tests__/fixtures/sql/generateSnapshotStresstestTable.sql"
18
18
  },
@@ -35,16 +35,16 @@
35
35
  "traverse": "^0.6.6"
36
36
  },
37
37
  "devDependencies": {
38
+ "@types/chai": "^4.1.6",
39
+ "@types/jest": "^24.0.18",
38
40
  "@types/node": "14.18.34",
39
41
  "@types/traverse": "^0.6.32",
40
- "typescript": "^4.9.4",
41
- "rimraf": "^2.6.3",
42
- "nyc": "^14.0.0",
43
- "jest": "^24.9.0",
44
42
  "chai": "^4.2.0",
45
- "ts-node": "^7.0.1",
43
+ "jest": "^24.9.0",
44
+ "nyc": "^14.0.0",
45
+ "rimraf": "^2.6.3",
46
46
  "ts-jest": "^24.1.0",
47
- "@types/jest": "^24.0.18",
48
- "@types/chai": "^4.1.6"
47
+ "ts-node": "^7.0.1",
48
+ "typescript": "^4.9.4"
49
49
  }
50
50
  }