Skip to content

Commit

Permalink
feat: support serialization of Moment.js (#879)
Browse files Browse the repository at this point in the history
  • Loading branch information
schmidt-sebastian committed Jan 14, 2020
1 parent b7b5fc9 commit 9169fae
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 2 deletions.
29 changes: 28 additions & 1 deletion dev/src/serializer.ts
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import {Moment} from 'moment';

import * as proto from '../protos/firestore_v1_proto_api';

import {detectValueType} from './convert';
Expand Down Expand Up @@ -119,7 +121,17 @@ export class Serializer {
}

if (val instanceof Date) {
const timestamp = Timestamp.fromDate(val as Date);
const timestamp = Timestamp.fromDate(val);
return {
timestampValue: {
seconds: timestamp.seconds,
nanos: timestamp.nanoseconds,
},
};
}

if (isMomentJsType(val)) {
const timestamp = Timestamp.fromDate(val.toDate());
return {
timestampValue: {
seconds: timestamp.seconds,
Expand Down Expand Up @@ -369,6 +381,8 @@ export function validateUserInput(
// Ok.
} else if (value instanceof Timestamp || value instanceof Date) {
// Ok.
} else if (isMomentJsType(value)) {
// Ok.
} else if (value instanceof Buffer || value instanceof Uint8Array) {
// Ok.
} else if (value === null) {
Expand All @@ -377,3 +391,16 @@ export function validateUserInput(
throw new Error(customObjectMessage(arg, value, path));
}
}

/**
* Returns true if value is a MomentJs date object.
* @private
*/
function isMomentJsType(value: unknown): value is Moment {
return (
typeof value === 'object' &&
value !== null &&
value.constructor.name === 'Moment' &&
typeof (value as Moment).toDate === 'function'
);
}
31 changes: 31 additions & 0 deletions dev/test/document.ts
Expand Up @@ -244,6 +244,37 @@ describe('serialize document', () => {
});
});

it('supports Moment.js', () => {
class Moment {
toDate(): Date {
return new Date('Jul 20 1969 20:18:00.123 UTC');
}
}

const overrides: ApiOverride = {
commit: request => {
requestEquals(
request,
set({
document: document('documentId', 'moonLanding', {
timestampValue: {
nanos: 123000000,
seconds: -14182920,
},
}),
})
);
return response(writeResult(1));
},
};

return createInstance(overrides).then(firestore => {
return firestore.doc('collectionId/documentId').set({
moonLanding: new Moment(),
});
});
});

it('serializes unicode keys', () => {
const overrides: ApiOverride = {
commit: request => {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -61,8 +61,10 @@
"@types/duplexify": "^3.5.0",
"@types/extend": "^3.0.0",
"@types/mocha": "^5.2.3",
"@types/moment": "^2.13.0",
"@types/node": "^12.12.17",
"@types/through2": "^2.0.34",
"c8": "^7.0.0",
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"codecov": "^3.6.1",
Expand All @@ -76,7 +78,6 @@
"jsdoc-region-tag": "^1.0.2",
"linkinator": "^1.8.0",
"mocha": "^7.0.0",
"c8": "^7.0.0",
"power-assert": "^1.6.1",
"protobufjs": "^6.8.6",
"proxyquire": "^2.1.3",
Expand Down

0 comments on commit 9169fae

Please sign in to comment.