Skip to content

Commit

Permalink
Alternative approach with replaacer and reviver methods.
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-andersen committed Dec 8, 2023
1 parent 3ccdf33 commit e71c894
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 24 deletions.
30 changes: 21 additions & 9 deletions dev/src/timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
* limitations under the License.
*/

import * as firestore from '@google-cloud/firestore';

import {google} from '../protos/firestore_v1_proto_api';
import {validateInteger} from './validate';
import * as firestore from "@google-cloud/firestore";

Check failure on line 17 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `"@google-cloud/firestore"` with `'@google-cloud/firestore'`

Check warning on line 17 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote

import { google } from "../protos/firestore_v1_proto_api";

Check failure on line 19 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·google·}·from·"../protos/firestore_v1_proto_api"` with `google}·from·'../protos/firestore_v1_proto_api'`

Check warning on line 19 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
import { validateInteger } from "./validate";

Check failure on line 20 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·validateInteger·}·from·"./validate"` with `validateInteger}·from·'./validate'`

Check warning on line 20 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Strings must use singlequote
import api = google.firestore.v1;

/*!
Expand Down Expand Up @@ -309,10 +308,23 @@ export class Timestamp implements firestore.Timestamp {
return formattedSeconds + '.' + formattedNanoseconds;
}

/**
* Returns a value to use when encoding this object into JSON.
*/
toJSON(): string {
return this.toDate().toISOString();
static reviver(this: any, key: string, value: any): any {

Check warning on line 311 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

Check warning on line 311 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

Check warning on line 311 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (key === '') {
const match = value.match(/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)\.(\d+)([+-][0-2]\d:[0-5]\d|Z)/);

Check failure on line 313 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)\.(\d+)([+-][0-2]\d:[0-5]\d|Z)/` with `⏎········/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d)\.(\d+)([+-][0-2]\d:[0-5]\d|Z)/⏎······`
return new Timestamp(
Math.floor(Date.parse(match[1] + 'Z') / 1000),
Number(match[2].padEnd(9, '0'))
);
}
}

static replacer(this: any, key: string, value: any): any {

Check warning on line 321 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

Check warning on line 321 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type

Check warning on line 321 in dev/src/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (key === '') {
const t: Timestamp = value;
const isoDateSeconds: string = new Date(t._seconds * 1000)
.toISOString()
.split('.')[0];
return `${isoDateSeconds}.${String(t._nanoseconds).padStart(9, '0')}Z`;
}
}
}
17 changes: 17 additions & 0 deletions dev/src/write-batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,23 @@ export class WriteResult implements firestore.WriteResult {
this._writeTime.isEqual(other._writeTime))
);
}

static reviver(this: any, key: string, value: any): any {

Check warning on line 100 in dev/src/write-batch.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
if (key === 'writeTime') {
return JSON.parse(value, Timestamp.reviver);
}
}

static replacer(this: any, key: string, value: any): any {
switch (key) {
case '':
return {
writeTime: value._writeTime,
};
case 'writeTime':
return JSON.stringify(value, Timestamp.replacer);
}
}
}

/**
Expand Down
48 changes: 33 additions & 15 deletions dev/test/timestamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {describe, it} from 'mocha';
import {expect} from 'chai';
import * as through2 from 'through2';
import { describe, it } from "mocha";

Check failure on line 15 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·describe,·it·}·from·"mocha"` with `describe,·it}·from·'mocha'`
import { expect } from "chai";

Check failure on line 16 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·expect·}·from·"chai"` with `expect}·from·'chai'`
import * as through2 from "through2";

Check failure on line 17 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `"through2"` with `'through2'`

import {google} from '../protos/firestore_v1_proto_api';

import * as Firestore from '../src/index';
import {
ApiOverride,
createInstance as createInstanceHelper,
document,
} from '../test/util/helpers';
import { google } from "../protos/firestore_v1_proto_api";

Check failure on line 19 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·google·}·from·"../protos/firestore_v1_proto_api"` with `google}·from·'../protos/firestore_v1_proto_api'`

import * as Firestore from "../src/index";

Check failure on line 21 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `"../src/index"` with `'../src/index'`
import { ApiOverride, createInstance as createInstanceHelper, document } from "../test/util/helpers";

Check failure on line 22 in dev/test/timestamp.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·ApiOverride,·createInstance·as·createInstanceHelper,·document·}·from·"../test/util/helpers"` with `⏎··ApiOverride,⏎··createInstance·as·createInstanceHelper,⏎··document,⏎}·from·'../test/util/helpers'`
import api = google.firestore.v1;

function createInstance(opts: {}, document: api.IDocument) {
Expand Down Expand Up @@ -54,7 +49,7 @@ const DOCUMENT_WITH_EMPTY_TIMESTAMP = document('documentId', 'moonLanding', {
timestampValue: {},
});

describe('timestamps', () => {
describe.only('timestamps', () => {
it('returned by default', () => {
return createInstance({}, DOCUMENT_WITH_TIMESTAMP).then(firestore => {
const expected = new Firestore.Timestamp(-14182920, 123000123);
Expand Down Expand Up @@ -224,16 +219,39 @@ describe('timestamps', () => {

it('JSON.stringify() on the smallest Timestamp object', () => {
const timestamp = new Firestore.Timestamp(-62135596800, 0);
expect(JSON.stringify(timestamp)).to.equal('"0001-01-01T00:00:00.000Z"');
const writeResult = new Firestore.WriteResult(timestamp);
expect(JSON.stringify(timestamp, Firestore.Timestamp.replacer)).to.equal('"0001-01-01T00:00:00.000000000Z"');
expect(JSON.stringify(writeResult, Firestore.WriteResult.replacer)).to.equal('{"writeTime":"\\"0001-01-01T00:00:00.000000000Z\\""}');
});

it('JSON.parse() on the smallest Timestamp object', () => {
const timestamp = new Firestore.Timestamp(-62135596800, 0);
expect(JSON.parse('"0001-01-01T00:00:00.000000000Z"', Firestore.Timestamp.reviver)).to.deep.equal(timestamp);
});

it('JSON.stringify() on the largest Timestamp object', () => {
const timestamp = new Firestore.Timestamp(253402300799, 999999999);
expect(JSON.stringify(timestamp)).to.equal('"9999-12-31T23:59:59.999Z"');
expect(JSON.parse('"9999-12-31T23:59:59.999999999Z"', Firestore.Timestamp.reviver)).to.deep.equal(timestamp);
});

it('JSON.parse() on the largest Timestamp object', () => {
const timestamp = new Firestore.Timestamp(253402300799, 999999999);
expect(JSON.stringify(timestamp, Firestore.Timestamp.replacer)).to.equal('"9999-12-31T23:59:59.999999999Z"');
});

it('JSON.stringify() on a Timestamp object whose date is in 2023', () => {
const timestamp = new Firestore.Timestamp(1680272000, 840000000);
expect(JSON.stringify(timestamp)).to.equal('"2023-03-31T14:13:20.840Z"');
expect(JSON.parse('"2023-03-31T14:13:20.840000000Z"', Firestore.Timestamp.reviver)).to.deep.equal(timestamp);
});

it('JSON.parse() on a Timestamp object whose date is in 2023', () => {
const timestamp = new Firestore.Timestamp(1680272000, 840000000);
expect(JSON.stringify(timestamp, Firestore.Timestamp.replacer)).to.equal('"2023-03-31T14:13:20.840000000Z"');
});

it.only('JSON.stringify() on the smallest Timestamp object', () => {
const timestamp = new Firestore.Timestamp(-62135596800, 0);
const writeResult = new Firestore.WriteResult(timestamp);
expect(JSON.stringify(writeResult, Firestore.WriteResult.replacer)).to.equal('{"writeTime":"\\"0001-01-01T00:00:00.000000000Z\\""}');
});
});
3 changes: 3 additions & 0 deletions types/firestore.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,9 @@ declare namespace FirebaseFirestore {
export class WriteResult {
private constructor();

static reviver(this: any, key: string, value: any): any;
static replacer(this: any, key: string, value: any): any;

/**
* The write time as set by the Firestore servers.
*/
Expand Down

0 comments on commit e71c894

Please sign in to comment.