Skip to content

Commit 6a34bbb

Browse files
Merge
2 parents f6553cb + 3c61f24 commit 6a34bbb

File tree

9 files changed

+76
-64
lines changed

9 files changed

+76
-64
lines changed

packages/firestore/exp/index.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,13 @@ export interface SnapshotMetadata {
5252
isEqual(other: SnapshotMetadata): boolean;
5353
}
5454

55-
export type LogLevel = 'debug' | 'error' | 'silent';
55+
export type LogLevel =
56+
| 'debug'
57+
| 'error'
58+
| 'silent'
59+
| 'warn'
60+
| 'info'
61+
| 'verbose';
5662

5763
export function setLogLevel(logLevel: LogLevel): void;
5864

packages/firestore/lite/index.d.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ export interface Settings {
3333
ignoreUndefinedProperties?: boolean;
3434
}
3535

36-
export type LogLevel = 'debug' | 'error' | 'silent';
36+
export type LogLevel =
37+
| 'debug'
38+
| 'error'
39+
| 'silent'
40+
| 'warn'
41+
| 'info'
42+
| 'verbose';
3743

3844
export function setLogLevel(logLevel: LogLevel): void;
3945

packages/firestore/lite/index.node.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,6 @@ export {
3737
parent
3838
} from './src/api/reference';
3939

40-
export { FieldPath } from './src/api/field_path';
41-
42-
// TOOD(firestorelite): Add tests when Queries are usable
43-
export { documentId } from './src/api/field_path';
44-
45-
export { DocumentSnapshot, QueryDocumentSnapshot } from './src/api/snapshot';
46-
4740
// TOOD(firestorelite): Add tests when setDoc() is available
4841
export {
4942
FieldValue,
@@ -54,6 +47,10 @@ export {
5447
serverTimestamp
5548
} from './src/api/field_value';
5649

50+
export { DocumentSnapshot, QueryDocumentSnapshot } from './src/api/snapshot';
51+
52+
export { setLogLevel } from '../src/util/log';
53+
5754
export function registerFirestore(): void {
5855
_registerComponent(
5956
new Component(

packages/firestore/lite/src/api/reference.ts

Lines changed: 16 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@ import { DocumentKeyReference } from '../../../src/api/user_data_reader';
2323
import { Query as InternalQuery } from '../../../src/core/query';
2424
import { FirebaseFirestore, FirestoreDataConverter } from '../../index';
2525
import { ResourcePath } from '../../../src/model/path';
26-
import { Code, FirestoreError } from '../../../src/util/error';
2726
import { AutoId } from '../../../src/util/misc';
28-
import { tryCast } from './util';
27+
import { cast } from './util';
28+
import {
29+
validateArgType,
30+
validateCollectionPath,
31+
validateDocumentPath
32+
} from '../../../src/util/input_validation';
2933

3034
/**
3135
* A reference to a particular document in a collection in the database.
@@ -166,31 +170,15 @@ export function collection(
166170
parent: firestore.FirebaseFirestore | firestore.DocumentReference<unknown>,
167171
relativePath: string
168172
): CollectionReference<firestore.DocumentData> {
169-
if (relativePath.length === 0) {
170-
throw new FirestoreError(
171-
Code.INVALID_ARGUMENT,
172-
`Invalid path (${relativePath}). Empty paths are not supported.`
173-
);
174-
}
175-
173+
validateArgType('doc', 'non-empty string', 2, relativePath);
176174
const path = ResourcePath.fromString(relativePath);
177175
if (parent instanceof Firestore) {
178-
if (DocumentKey.isDocumentKey(path)) {
179-
throw new FirestoreError(
180-
Code.INVALID_ARGUMENT,
181-
`Invalid path (${path}). Path points to a document.`
182-
);
183-
}
176+
validateCollectionPath(path);
184177
return new CollectionReference(parent, path);
185178
} else {
186-
const doc = tryCast(parent, DocumentReference);
179+
const doc = cast(parent, DocumentReference);
187180
const absolutePath = doc._key.path.child(path);
188-
if (DocumentKey.isDocumentKey(absolutePath)) {
189-
throw new FirestoreError(
190-
Code.INVALID_ARGUMENT,
191-
`Invalid path (${absolutePath}). Path points to a document.`
192-
);
193-
}
181+
validateCollectionPath(absolutePath);
194182
return new CollectionReference(doc.firestore, absolutePath);
195183
}
196184
}
@@ -212,32 +200,15 @@ export function doc<T>(
212200
if (arguments.length === 1) {
213201
relativePath = AutoId.newId();
214202
}
215-
216-
if (!relativePath) {
217-
throw new FirestoreError(
218-
Code.INVALID_ARGUMENT,
219-
`Invalid path (${relativePath}). Empty paths are not supported.`
220-
);
221-
}
222-
223-
const path = ResourcePath.fromString(relativePath);
203+
validateArgType('doc', 'non-empty string', 2, relativePath);
204+
const path = ResourcePath.fromString(relativePath!);
224205
if (parent instanceof Firestore) {
225-
if (!DocumentKey.isDocumentKey(path)) {
226-
throw new FirestoreError(
227-
Code.INVALID_ARGUMENT,
228-
`Invalid path (${path}). Path points to a collection.`
229-
);
230-
}
206+
validateDocumentPath(path);
231207
return new DocumentReference(parent, new DocumentKey(path));
232208
} else {
233-
const coll = tryCast(parent, CollectionReference);
209+
const coll = cast(parent, CollectionReference);
234210
const absolutePath = coll._path.child(path);
235-
if (!DocumentKey.isDocumentKey(absolutePath)) {
236-
throw new FirestoreError(
237-
Code.INVALID_ARGUMENT,
238-
`Invalid path (${absolutePath}). Path points to a collection.`
239-
);
240-
}
211+
validateDocumentPath(absolutePath);
241212
return new DocumentReference(
242213
coll.firestore,
243214
new DocumentKey(absolutePath),
@@ -266,7 +237,7 @@ export function parent<T>(
266237
);
267238
}
268239
} else {
269-
const doc = tryCast(child, DocumentReference) as DocumentReference<T>;
240+
const doc = cast<DocumentReference<T>>(child, DocumentReference);
270241
return new CollectionReference<T>(
271242
doc.firestore,
272243
doc._key.path.popLast(),

packages/firestore/lite/src/api/util.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ import { Code, FirestoreError } from '../../../src/util/error';
2323
* This cast is used in the Lite and Full SDK to verify instance types for
2424
* arguments passed to the public API.
2525
*/
26-
export function tryCast<T>(
26+
export function cast<T>(
2727
obj: object,
2828
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2929
constructor: { new (...args: any[]): T }
30-
): T {
30+
): T | never {
3131
if (!(obj instanceof constructor)) {
3232
if (constructor.name === obj.constructor.name) {
3333
throw new FirestoreError(

packages/firestore/lite/test/integration.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,13 @@ describe('doc', () => {
8181
it('validates path', () => {
8282
return withTestDb(db => {
8383
expect(() => doc(db, 'coll')).to.throw(
84-
'Invalid path (coll). Path points to a collection.'
84+
'Invalid document path (coll). Path points to a collection.'
8585
);
8686
expect(() => doc(db, '')).to.throw(
87-
'Invalid path (). Empty paths are not supported.'
87+
'Function doc() requires its second argument to be of type non-empty string, but it was: ""'
8888
);
8989
expect(() => doc(collection(db, 'coll'), 'doc/coll')).to.throw(
90-
'Invalid path (coll/doc/coll). Path points to a collection.'
90+
'Invalid document path (coll/doc/coll). Path points to a collection.'
9191
);
9292
expect(() => doc(db, 'coll//doc')).to.throw(
9393
'Invalid path (coll//doc). Paths must not contain // in them.'
@@ -117,13 +117,15 @@ describe('collection', () => {
117117
it('validates path', () => {
118118
return withTestDb(db => {
119119
expect(() => collection(db, 'coll/doc')).to.throw(
120-
'Invalid path (coll/doc). Path points to a document.'
120+
'Invalid collection path (coll/doc). Path points to a document.'
121121
);
122+
// TODO(firestorelite): Explore returning a more helpful message
123+
// (e.g. "Empty document paths are not supported.")
122124
expect(() => collection(doc(db, 'coll/doc'), '')).to.throw(
123-
'Invalid path (). Empty paths are not supported.'
125+
'Function doc() requires its second argument to be of type non-empty string, but it was: ""'
124126
);
125127
expect(() => collection(doc(db, 'coll/doc'), 'coll/doc')).to.throw(
126-
'Invalid path (coll/doc/coll/doc). Path points to a document.'
128+
'Invalid collection path (coll/doc/coll/doc). Path points to a document.'
127129
);
128130
});
129131
});

packages/firestore/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
"author": "Firebase <[email protected]> (https://firebase.google.com/)",
99
"scripts": {
1010
"prebuild": "tsc -m es2015 --moduleResolution node scripts/*.ts ",
11+
"prebuild:release": "yarn prebuild",
1112
"build": "rollup -c rollup.config.es2017.js && rollup -c rollup.config.es5.js && yarn build:lite",
13+
"build:release": "rollup -c rollup.config.es2017.js && rollup -c rollup.config.es5.js",
1214
"build:deps": "lerna run --scope @firebase/'{app,firestore}' --include-dependencies build",
1315
"build:console": "node tools/console.build.js",
1416
"build:exp": "rollup -c rollup.config.exp.js",
@@ -35,7 +37,7 @@
3537
"test:minified": "(cd ../../integration/firestore ; yarn test)",
3638
"pretest:lite": "yarn build:lite",
3739
"test:lite": "TS_NODE_CACHE=NO TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha 'lite/test/**/*.test.ts' --file lite/index.node.ts --config ../../config/mocharc.node.js",
38-
"prepare": "yarn build"
40+
"prepare": "yarn build:release"
3941
},
4042
"main": "dist/index.node.cjs.js",
4143
"main-esm2017": "dist/index.node.esm2017.js",

packages/firestore/src/util/assert.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export function debugCast<T>(
7979
obj: object,
8080
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8181
constructor: { new (...args: any[]): T }
82-
): T {
82+
): T | never {
8383
debugAssert(
8484
obj instanceof constructor,
8585
`Expected type '${constructor.name}', but was '${obj.constructor.name}'`

packages/firestore/src/util/input_validation.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import { fail } from './assert';
1818
import { Code, FirestoreError } from './error';
1919
import { Dict, forEach } from './obj';
20+
import { DocumentKey } from '../model/document_key';
21+
import { ResourcePath } from '../model/path';
2022

2123
/** Types accepted by validateType() and related methods for validation. */
2224
export type ValidationType =
@@ -317,6 +319,32 @@ export function validateStringEnum<T>(
317319
return argument as T;
318320
}
319321

322+
/**
323+
* Validates that `path` refers to a document (indicated by the fact it contains
324+
* an even numbers of segments).
325+
*/
326+
export function validateDocumentPath(path: ResourcePath): void {
327+
if (!DocumentKey.isDocumentKey(path)) {
328+
throw new FirestoreError(
329+
Code.INVALID_ARGUMENT,
330+
`Invalid document path (${path}). Path points to a collection.`
331+
);
332+
}
333+
}
334+
335+
/**
336+
* Validates that `path` refers to a collection (indicated by the fact it
337+
* contains an odd numbers of segments).
338+
*/
339+
export function validateCollectionPath(path: ResourcePath): void {
340+
if (DocumentKey.isDocumentKey(path)) {
341+
throw new FirestoreError(
342+
Code.INVALID_ARGUMENT,
343+
`Invalid collection path (${path}). Path points to a document.`
344+
);
345+
}
346+
}
347+
320348
/** Helper to validate the type of a provided input. */
321349
function validateType(
322350
functionName: string,

0 commit comments

Comments
 (0)