From dd9299faf085dc478f13a56ed9f8abe026339e53 Mon Sep 17 00:00:00 2001 From: Sasha Koss Date: Tue, 6 Aug 2019 15:03:32 +0200 Subject: [PATCH] Start adding docs --- src/add/index.ts | 20 ++++++ src/all/index.ts | 21 ++++++ src/batch/index.ts | 141 ++++++++++++++++++++++++++++++++++------ src/clear/index.ts | 18 +++++ src/collection/index.ts | 15 +++++ src/cursor/index.ts | 76 +++++++++++++++++++++- src/data/index.ts | 4 ++ src/set/index.ts | 24 +++++++ src/update/index.ts | 46 +++++++++++++ 9 files changed, 342 insertions(+), 23 deletions(-) diff --git a/src/add/index.ts b/src/add/index.ts index 7bf5a766..d4bd19e0 100644 --- a/src/add/index.ts +++ b/src/add/index.ts @@ -4,6 +4,26 @@ import { unwrapData } from '../data' import { doc } from '../doc' import { ref } from '../ref' +/** + * Adds a new document with a random id to a collection. + * + * @param collection - the collection to add to + * @param data - the data to add to + * @returns a promise to the document + * + * @example + * import { add, collection } from 'typesaurus' + * + * type User = { name: string } + * const users = collection('users') + * + * add(users, { name: 'Sasha' }).then(sasha => { + * console.log(sasha.ref.id) + * //=> '00sHm46UWKObv2W7XK9e' + * console.log(sasha.data) + * //=> { name: 'Sasha' } + * }) + */ export default async function add( collection: Collection, data: Model diff --git a/src/all/index.ts b/src/all/index.ts index 5d7872f7..710c6773 100644 --- a/src/all/index.ts +++ b/src/all/index.ts @@ -4,6 +4,27 @@ import { doc, Doc } from '../doc' import { ref } from '../ref' import { wrapData } from '../data' +/** + * Returns all documents in a collection. + * + * @param collection - the collection to get all documents from + * @returns a promise to all documents + * + * @example + * import { all, collection } from 'typesaurus' + * + * type User = { name: string } + * const users = collection('users') + * + * all(users).then(allUsers => { + * console.log(allUsers.length) + * //=> 420 + * console.log(allUsers[0].ref.id) + * //=> '00sHm46UWKObv2W7XK9e' + * console.log(allUsers[0].data) + * //=> { name: 'Sasha' } + * }) + */ export default async function all( collection: Collection ): Promise[]> { diff --git a/src/batch/index.ts b/src/batch/index.ts index 65585785..d34207ba 100644 --- a/src/batch/index.ts +++ b/src/batch/index.ts @@ -3,31 +3,65 @@ import { Collection } from '../collection' import { Ref, ref } from '../ref' import { Doc, doc } from '../doc' import { unwrapData } from '../data' -import set from '../set' -import update, { ModelUpdate } from '../update' +import { ModelUpdate } from '../update' import { Field } from '../field' -import clear from '../clear' - -export type BatchAPI = { - set: typeof set - update: typeof update - clear: typeof clear - commit: () => Promise -} +/** + * @returns batch API (set, update, clear, commit) + * + * @example + * import { batch, collection } from 'typesaurus' + * + * type Counter = { count: number } + * const counters = collection('counters') + * + * const { set, update, clear, commit } = batch() + * + * for (let count = 0; count < 500; count++) { + * set(counters, count.toString(), { count }) + * } + * + * commit().then(() => console.log('Done!')) + */ export function batch() { - const b = firestore().batch() - - // set + const firestoreBatch = firestore().batch() + /** + * @param ref - the reference to the document to set + * @param data - the document data + */ function set(ref: Ref, data: Model): Doc + /** + * @param collection - the collection to set document in + * @param id - the id of the document to set + * @param data - the document data + */ function set( collection: Collection, id: string, data: Model ): Doc + /** + * Sets a document to the given data. + * + * @returns the document + * + * @example + * import { batch, collection } from 'typesaurus' + * + * type Counter = { count: number } + * const counters = collection('counters') + * + * const { set, commit } = batch() + * + * for (let count = 0; count < 500; count++) { + * set(counters, count.toString(), { count }) + * } + * + * commit() + */ function set( collectionOrRef: Collection | Ref, idOrData: string | Model, @@ -53,29 +87,67 @@ export function batch() { .doc(id) // ^ above // TODO: Refactor code above and below because is all the same as in the regular set function - b.set(firestoreDoc, unwrapData(data)) + firestoreBatch.set(firestoreDoc, unwrapData(data)) // v below return doc(ref(collection, id), data) } - // update - + /** + * @param collection - the collection to update document in + * @param id - the id of the document to update + * @param data - the document data to update + */ function update( collection: Collection, id: string, data: Field[] ): void + /** + * @param ref - the reference to the document to set + * @param data - the document data to update + */ function update(ref: Ref, data: Field[]): void + /** + * @param collection - the collection to update document in + * @param id - the id of the document to update + * @param data - the document data to update + */ function update( collection: Collection, id: string, data: ModelUpdate ): void + /** + * @param ref - the reference to the document to set + * @param data - the document data to update + */ function update(ref: Ref, data: ModelUpdate): void + /** + * @returns void + * + * @example + * import { batch, collection } from 'typesaurus' + * + * type Counter = { count: number, meta: { updatedAt: number } } + * const counters = collection('counters') + * + * const { update, commit } = batch() + * + * for (let count = 0; count < 500; count++) { + * update(counters, count.toString(), { count: count + 1 }) + * // or using key paths: + * update(counters, count.toString(), [ + * ['count', count + 1], + * [['meta', 'updatedAt'], Date.now()] + * ]) + * } + * + * commit() + */ function update( collectionOrRef: Collection | Ref, idOrData: string | Field[] | ModelUpdate, @@ -110,15 +182,37 @@ export function batch() { : data // ^ above // TODO: Refactor code above because is all the same as in the regular update function - b.update(firebaseDoc, unwrapData(updateData)) + firestoreBatch.update(firebaseDoc, unwrapData(updateData)) } - // clear - + /** + * @param collection - the collection to remove document in + * @param id - the id of the documented to remove + */ function clear(collection: Collection, id: string): void + /** + * @param ref - the reference to the document to remove + */ function clear(ref: Ref): void + /** + * Removes a document. + * + * @example + * import { batch, collection } from 'typesaurus' + * + * type Counter = { count: number } + * const counters = collection('counters') + * + * const { clear, commit } = batch() + * + * for (let count = 0; count < 500; count++) { + * clear(counters, count.toString()) + * } + * + * commit() + */ function clear( collectionOrRef: Collection | Ref, maybeId?: string @@ -140,11 +234,16 @@ export function batch() { .doc(id) // ^ above // TODO: Refactor code above because is all the same as in the regular update function - b.delete(firebaseDoc) + firestoreBatch.delete(firebaseDoc) } + /** + * Starts the execution of the operations in the batch. + * + * @returns a promise that resolves when the operations are finished + */ async function commit() { - await b.commit() + await firestoreBatch.commit() } return { diff --git a/src/clear/index.ts b/src/clear/index.ts index 9b406c5c..df26f92a 100644 --- a/src/clear/index.ts +++ b/src/clear/index.ts @@ -2,13 +2,31 @@ import firestore from '../adaptor' import { Collection } from '../collection' import { Ref } from '../ref' +/** + * @param collection - the collection to remove document in + * @param id - the id of the documented to remove + */ async function clear( collection: Collection, id: string ): Promise +/** + * @param ref - the reference to the document to remove + */ async function clear(ref: Ref): Promise +/** + * Removes a document. + * + * @example + * import { clear } from 'typesaurus' + * + * type User = { name: string } + * const users = collection('users') + * + * clear(users, '00sHm46UWKObv2W7XK9e').then(() => console.log('Done!')) + */ async function clear( collectionOrRef: Collection | Ref, maybeId?: string diff --git a/src/collection/index.ts b/src/collection/index.ts index 248dc046..cb4e76bc 100644 --- a/src/collection/index.ts +++ b/src/collection/index.ts @@ -3,6 +3,21 @@ export interface Collection<_Model> { path: string } +/** + * Creates collection object. + * + * @param path - the collection path + * @returns collection object + * + * @example + * import { add, collection } from 'typesaurus' + * + * type User = { name: string } + * const users = collection('users') + * // { __type__: 'collection', path: 'users' } + * + * add(users, { name: 'Sasha' }) + */ export function collection(path: string): Collection { return { __type__: 'collection', path } } diff --git a/src/cursor/index.ts b/src/cursor/index.ts index 18f9b52b..36163888 100644 --- a/src/cursor/index.ts +++ b/src/cursor/index.ts @@ -1,12 +1,33 @@ -// import { Ref } from '../ref' - +/** + * Available cursor methods. + */ export type CursorMethod = 'startAfter' | 'startAt' | 'endBefore' | 'endAt' +/** + * The cursor interface, holds the method and the value for pagination. + */ export interface Cursor { method: CursorMethod value: Model[Key] | /*Ref |*/ undefined } +/** + * Start the query results after the given value. + * + * @param value - the value to end the query results after + * + * @example + * import { startAfter, order, query, collection } from 'typesaurus' + * + * type Contact = { name: string; year: number } + * const contacts = collection('contacts') + * + * query(contacts, [order('year', 'asc', [startAfter(1999)])]) + * .then(youngerThan2K => { + * console.log(youngerThan2K.length) + * //=> 420 + * }) + */ export function startAfter( value: Model[Key] | /*Ref |*/ undefined ): Cursor { @@ -16,6 +37,23 @@ export function startAfter( } } +/** + * Start the query results on the given value. + * + * @param value - the value to start the query results at + * + * @example + * import { startAt, order, query, collection } from 'typesaurus' + * + * type Contact = { name: string; year: number } + * const contacts = collection('contacts') + * + * query(contacts, [order('year', 'asc', [startAt(2000)])]) + * .then(youngerThan2K => { + * console.log(youngerThan2K.length) + * //=> 420 + * }) + */ export function startAt( value: Model[Key] | /*Ref |*/ undefined ): Cursor { @@ -25,6 +63,23 @@ export function startAt( } } +/** + * Ends the query results before the given value. + * + * @param value - the value to end the query results before + * + * @example + * import { endBefore, order, query, collection } from 'typesaurus' + * + * type Contact = { name: string; year: number } + * const contacts = collection('contacts') + * + * query(contacts, [order('year', 'asc', [endBefore(2000)])]) + * .then(olderThan2K => { + * console.log(olderThan2K.length) + * //=> 420 + * }) + */ export function endBefore( value: Model[Key] | /*Ref |*/ undefined ): Cursor { @@ -34,6 +89,23 @@ export function endBefore( } } +/** + * Ends the query results on the given value. + * + * @param value - the value to end the query results at + * + * @example + * import { endAt, order, query, collection } from 'typesaurus' + * + * type Contact = { name: string; year: number } + * const contacts = collection('contacts') + * + * query(contacts, [order('year', 'asc', [endAt(1999)])]) + * .then(olderThan2K => { + * console.log(olderThan2K.length) + * //=> 420 + * }) + */ export function endAt( value: Model[Key] | /*Ref |*/ undefined ): Cursor { diff --git a/src/data/index.ts b/src/data/index.ts index da4cea62..f1234d46 100644 --- a/src/data/index.ts +++ b/src/data/index.ts @@ -6,6 +6,10 @@ import { import { pathToRef, Ref, refToFirebaseDocument } from '../ref' import { UpdateValue } from '../value' +/** + * + * @param value - the value to convert + */ export function unwrapData(value: any) { if (value instanceof Date) { return FirestoreTimestamp.fromDate(value) diff --git a/src/set/index.ts b/src/set/index.ts index ee664c01..061f4a9c 100644 --- a/src/set/index.ts +++ b/src/set/index.ts @@ -4,14 +4,38 @@ import { doc, Doc } from '../doc' import { ref, Ref } from '../ref' import { unwrapData } from '../data' +/** + * @param ref - the reference to the document to set + */ async function set(ref: Ref, data: Model): Promise> +/** + * @param collection - the collection to set document in + * @param id - the id of the document to set + * @param data - the document data + */ async function set( collection: Collection, id: string, data: Model ): Promise> +/** + * Sets a document to the given data. + * + * @returns a promise to the document + * + * @example + * import { set, collection } from 'typesaurus' + * + * type User = { name: string } + * const users = collection('users') + * + * set(users, '00sHm46UWKObv2W7XK9e', { name: 'Sasha Koss' }).then(sasha => { + * console.log(sasha.data) + * //=> { name: 'Sasha Koss' } + * }) + */ async function set( collectionOrRef: Collection | Ref, idOrData: string | Model, diff --git a/src/update/index.ts b/src/update/index.ts index a6c6b8e0..ad6fc565 100644 --- a/src/update/index.ts +++ b/src/update/index.ts @@ -5,32 +5,78 @@ import { Field } from '../field' import { unwrapData } from '../data' import { Ref } from '../ref' +/** + * Type of the data passed to the update function. It extends the model + * making values optional and allow to set value object. + */ export type ModelUpdate = { [Key in keyof Model]?: Model[Key] | UpdateValue } +/** + * @param collection - the collection to update document in + * @param id - the id of the document to update + * @param data - the document data to update + */ async function update( collection: Collection, id: string, data: Field[] ): Promise +/** + * @param ref - the reference to the document to set + * @param data - the document data to update + */ async function update( ref: Ref, data: Field[] ): Promise +/** + * @param collection - the collection to update document in + * @param id - the id of the document to update + * @param data - the document data to update + */ async function update( collection: Collection, id: string, data: ModelUpdate ): Promise +/** + * @param ref - the reference to the document to set + * @param data - the document data to update + */ async function update( ref: Ref, data: ModelUpdate ): Promise +/** + * @returns a promise that resolves when operation is finished + * + * @example + * import { update, collection } from 'typesaurus' + * + * type User = { + * name: string, + * address: { + * country: string, + * city: string + * } + * } + * + * const users = collection('users') + * + * update(users, '00sHm46UWKObv2W7XK9e', { name: 'Sasha Koss' }) + * .then(() => console.log('Done!')) + * // or using key paths: + * update(users, '00sHm46UWKObv2W7XK9e', [ + * ['name', 'Sasha Koss'], + * [['address', 'city'], 'Moscow'] + * ]) + */ async function update( collectionOrRef: Collection | Ref, idOrData: string | Field[] | ModelUpdate,