Skip to content

Commit 4d17a54

Browse files
authored
Add skeleton implementation for Datastore provider (#138)
The backend team is still working on event payload changes, so this just helps them tests with an `Event<any>` implementation. It is very intentional that this is not exposed in index.ts; alpha testers will manually reach into lib/providers/datastore.
1 parent eb575ba commit 4d17a54

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

spec/index.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import './testing.spec';
3636
import './providers/analytics.spec';
3737
import './providers/auth.spec';
3838
import './providers/database.spec';
39+
import './providers/datastore.spec';
3940
import './providers/https.spec';
4041
import './providers/pubsub.spec';
4142
import './providers/storage.spec';

spec/providers/datastore.spec.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2017 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import * as datastore from '../../src/providers/datastore';
24+
import { expect } from 'chai';
25+
26+
describe('Datastore Functions', () => {
27+
28+
before(() => {
29+
process.env.GCLOUD_PROJECT = 'project1';
30+
});
31+
32+
after(() => {
33+
delete process.env.GCLOUD_PROJECT;
34+
});
35+
36+
describe('DataConstructors', () => {
37+
function expectedTrigger(resource: string) {
38+
return {
39+
eventTrigger: {
40+
resource,
41+
eventType: `providers/${datastore.provider}/eventTypes/document.write`,
42+
},
43+
};
44+
}
45+
46+
it('should allow terse constructors', () => {
47+
let resource = 'projects/project1/databases/(default)/documents/users/{uid}';
48+
let cloudFunction = datastore.document('users/{uid}').onWrite(() => null);
49+
expect(cloudFunction.__trigger).to.deep.equal(expectedTrigger(resource));
50+
});
51+
52+
it('should allow custom namespaces', () => {
53+
let resource = 'projects/project1/databases/(default)/documents@v2/users/{uid}';
54+
let cloudFunction = datastore.namespace('v2').document('users/{uid}').onWrite(() => null);
55+
expect(cloudFunction.__trigger).to.deep.equal(expectedTrigger(resource));
56+
});
57+
58+
it('should allow custom databases', () => {
59+
let resource = 'projects/project1/databases/myDB/documents/users/{uid}';
60+
let cloudFunction = datastore.database('myDB').document('users/{uid}').onWrite(() => null);
61+
expect(cloudFunction.__trigger).to.deep.equal(expectedTrigger(resource));
62+
});
63+
64+
it('should allow both custom database and namespace', () => {
65+
let resource = 'projects/project1/databases/myDB/documents@v2/users/{uid}';
66+
let cloudFunction = datastore.database('myDB').namespace('v2').document('users/{uid}').onWrite(() => null);
67+
expect(cloudFunction.__trigger).to.deep.equal(expectedTrigger(resource));
68+
});
69+
});
70+
});

src/providers/datastore.ts

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2017 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
import { makeCloudFunction, CloudFunction, Event } from '../cloud-functions';
24+
25+
/** @internal */
26+
export const provider = (new Buffer('Y2xvdWQuZmlyc3RvcmU=', 'base64')).toString();
27+
28+
/** @internal */
29+
export const defaultDatabase = '(default)';
30+
31+
/** Handle events in the Firebase Auth user lifecycle. */
32+
export function database(database: string = defaultDatabase) {
33+
return new DatabaseBuilder(`projects/${process.env.GCLOUD_PROJECT}/databases/${database}`);
34+
}
35+
36+
export function namespace(namespace: string) {
37+
return database().namespace(namespace);
38+
}
39+
40+
export function document(path: string) {
41+
return database().document(path);
42+
}
43+
44+
export class DatabaseBuilder {
45+
/** @internal */
46+
constructor(private resource: string) {}
47+
48+
namespace(namespace: string) {
49+
return new NamespaceBuilder(`${this.resource}/documents@${namespace}`);
50+
}
51+
52+
document(path: string) {
53+
return (new NamespaceBuilder(`${this.resource}/documents`)).document(path);
54+
}
55+
}
56+
57+
export class NamespaceBuilder {
58+
/** @internal */
59+
constructor(private resource: string) {}
60+
61+
document(path: string) {
62+
return new DocumentBuilder(`${this.resource}/${path}`);
63+
}
64+
}
65+
66+
export class DocumentBuilder {
67+
/** @internal */
68+
constructor(private resource: string) {
69+
// TODO what validation do we want to do here?
70+
}
71+
72+
onWrite(handler: (event: Event<any>) => PromiseLike<any> | any): CloudFunction<any> {
73+
return makeCloudFunction({
74+
provider, handler,
75+
resource: this.resource,
76+
eventType: 'document.write',
77+
});
78+
}
79+
}

0 commit comments

Comments
 (0)