UNPKG

functional-google-cloud

Version:

Google Cloud Utilities functions in Functional Programming Style

319 lines 10.4 kB
import { Timestamp, } from '@google-cloud/firestore'; import * as A from 'fp-ts/lib/Array'; import * as E from 'fp-ts/lib/Either'; import * as R from 'fp-ts/lib/Reader'; import * as RTE from 'fp-ts/lib/ReaderTaskEither'; import * as TE from 'fp-ts/lib/TaskEither'; import * as TEUtils from 'functional-types/lib/fp-ts/TaskEither'; import { allPass, evolve, ifElse, is, isEmpty, map, not, pipe, prop, propIs, propSatisfies, reduce, } from 'ramda'; /** * ```haskell * isModel :: a -> bool * ``` */ export const isModel = (a) => allPass([is(Object), propIs(String, 'id')])(a); /** * ```haskell * isTimestampModel :: a -> bool * ``` */ export const isTimestampModel = (a) => allPass([ isModel, propIs(Timestamp, 'created_at'), propIs(Timestamp, 'updated_at'), ])(a); /** * ```haskell * isDateModel :: a -> bool * ``` */ export const isDateModel = (a) => allPass([isModel, propIs(Date, 'created_at'), propIs(Date, 'updated_at')])(a); /** * ```haskell * isDateString :: a -> bool * ``` */ export const isDateString = (a) => allPass([is(String), pipe(Date.parse, isNaN, not)])(a); /** * ```haskell * isSerializedModel :: a -> bool * ``` */ export const isSerializedModel = (a) => allPass([ isModel, propSatisfies(isDateString, 'created_at'), propSatisfies(isDateString, 'updated_at'), ])(a); /** * ```haskell * getDateFromTimestamp :: Timestamp -> Date * ``` */ const getDateFromTimestamp = (timestamp) => timestamp.toDate(); /** * ```haskell * getTimestampFromDate :: Date -> Timestamp * ``` */ const getTimestampFromDate = (date) => Timestamp.fromDate(date); /** * ```haskell * serializeDate :: Date -> String * ``` */ const serializeDate = (date) => date.toISOString(); /** * ```haskell * fromTimestampModel :: TimestampModel -> DateModel * ``` */ export const fromTimestampModel = (model) => evolve({ created_at: getDateFromTimestamp, updated_at: getDateFromTimestamp, })(model); /** * ```haskell * fromDateModel :: DateModel -> TimestampModel * ``` */ export const fromDateModel = (model) => evolve({ created_at: getTimestampFromDate, updated_at: getTimestampFromDate, })(model); /** * ```haskell * serializeDateModel :: DateModel -> SerializedModel * ``` */ export const serializeDateModel = (model) => evolve({ created_at: serializeDate, updated_at: serializeDate, })(model); /** * ```haskell * serializeTimestampModel :: TimestampModel -> SerializedModel * ``` */ export const serializeTimestampModel = pipe(fromTimestampModel, serializeDateModel); /** * ```haskell * serialize :: Model -> Either SerializedModel Error * ``` */ export const serialize = ifElse(isSerializedModel, E.right, pipe(ifElse(isDateModel, E.right, pipe(E.fromPredicate(isTimestampModel, () => new Error('Model is not a TimestampModel.')), E.map(fromTimestampModel))), E.map(serializeDateModel))); /** * ```haskell * getCollectionFromFirestore :: Firestore -> Reader String Collection * ``` */ export const getCollectionFromFirestore = (firestore) => (table) => firestore.collection(table); /** * ```haskell * getDocumentFromCollection :: Collection -> Reader Model Document * ``` */ export const getDocumentFromCollection = (collection) => (model) => collection.doc(model.id); /** * ```haskell * getQueryFromCollection :: Collection -> Reader [Condition] Document Error * ``` */ export const getQueryFromCollection = (collection) => { return pipe(E.fromPredicate(pipe(isEmpty, not), () => new Error('No condition has been provided.')), E.map(reduce((query, condition) => query.where(...condition), collection))); }; /** * ```haskell * getCollectionFromDocument :: Document -> Reader String Collection * ``` */ export const getCollectionFromDocument = (document) => (table) => document.collection(table); /** * @internal * ```haskell * storeModelToDocumentTask :: Document -> Reader Model (Task Model) * ``` */ const storeModelToDocumentTask = (document) => (model) => async () => { await document.set(model); return model; }; /** * ```haskell * storeModelToDocument :: Document -> ReaderTaskEither Model Model Error * ``` */ export const storeModelToDocument = pipe(storeModelToDocumentTask, R.map(TEUtils.fromTask)); /** * ```haskell * storeModelToCollection :: Collection -> String -> ReaderTaskEither Model Model Error * ``` */ export const storeModelToCollection = pipe(getDocumentFromCollection, R.chain(storeModelToDocument)); /** * ```haskell * storeModelToFirestore :: Firestore -> Reader String (ReaderTaskEither Model Model Error) * ``` */ export const storeModelToFirestore = pipe(getCollectionFromFirestore, R.map(storeModelToCollection)); /** * ```haskell * storeModelToFirestoreWith :: Firestore -> Reader String (ReaderTaskEither (() -> Model) Model Error) * ``` */ export const storeModelToFirestoreWith = (firestore) => (table) => (fn) => pipe(fn, storeModelToFirestore(firestore)(table)); /** * ```haskell * updateModelInDocumentTask :: Collection -> ReaderTask Model Model * ``` */ export const updateModelInDocumentTask = (document) => (model) => async () => { await document.update(model); return model; }; /** * ```haskell * updateModelInDocument :: Collection -> ReaderTaskEither Model Model Error * ``` */ export const updateModelInDocument = pipe(updateModelInDocumentTask, R.map(TEUtils.fromTask)); /** * ```haskell * getSnapshotFromDocumentTask :: Document -> Task Snapshot * ``` */ export const getSnapshotFromDocumentTask = (document) => () => document.get(); /** * ```haskell * getSnapshotFromDocument :: Document -> TaskEither Snapshot Error * ``` */ export const getSnapshotFromDocument = pipe(getSnapshotFromDocumentTask, TEUtils.fromTask); /** * @internal * ```haskell * getSnapshotFromCollection :: Collection -> ReaderTaskEither Model Snapshot Error * ``` */ const getSnapshotFromCollection = pipe(getDocumentFromCollection, R.map(getSnapshotFromDocument)); /** * @internal * ```haskell * getDataFromSnapshot :: Snapshot -> a * ``` */ const getDataFromSnapshot = (snapshot) => snapshot.data(); /** * ```haskell * validateSnapshotExistence :: snapshot -> Either a Error * ``` */ export const validateSnapshotExistence = ifElse(prop('exists'), E.right, () => E.left(new Error('Item does not exist.'))); /** * ```haskell * validateModel :: a -> Either Model Error * ``` */ export const validateModel = ifElse(isModel, E.right, () => E.left(new Error('Item is not a valid model.'))); /** * ```haskell * getModelFromDocumentSnapshot :: Snapshot -> Either Model Error * ``` */ const getModelFromDocumentSnapshot = pipe(validateSnapshotExistence, E.map(getDataFromSnapshot), E.chain(validateModel)); /** * ```haskell * getModelFromCollection :: Collection -> ReaderTaskEither Model Model Error * ``` */ export const getModelFromCollection = pipe(getSnapshotFromCollection, RTE.chainEitherK(getModelFromDocumentSnapshot)); /** * ```haskell * getModelFromFirestore :: Firestore -> Reader String (ReaderTaskEither Model Model Error) * ``` */ export const getModelFromFirestore = pipe(getCollectionFromFirestore, R.map(getModelFromCollection)); /** * ```haskell * listCollectionsInFirestore :: Firestore -> Task [Collection] * ``` */ export const listCollectionsInFirestore = (firestore) => () => firestore.listCollections(); /** * ```haskell * listDocumentsInCollectionTask :: Collection -> Task [Document] * ``` */ export const listDocumentsInCollectionTask = (collection) => () => collection.listDocuments(); /** * ```haskell * listDocumentsInCollection :: Collection -> TaskEither [Document] Error * ``` */ export const listDocumentsInCollection = pipe(listDocumentsInCollectionTask, TEUtils.fromTask); /** * ```haskell * listDocumentsInFirestore :: Firestore ReaderTaskEither String [Document] Error * ``` */ export const listDocumentsInFirestore = pipe(getCollectionFromFirestore, R.map(listDocumentsInCollection)); /** * ```haskell * getModelFromDocument :: Document -> TaskEither Model Error * ``` */ export const getModelFromDocument = pipe(getSnapshotFromDocument, TE.chainEitherK(getModelFromDocumentSnapshot)); /** * ```haskell * getSnapshotFromQueryTask :: Query -> Task Snapshot * ``` */ export const getSnapshotFromQueryTask = (query) => () => query.get(); /** * ```haskell * getSnapshotFromQuery :: Query -> TaskEither Snapshot Error * ``` */ export const getSnapshotFromQuery = pipe(getSnapshotFromQueryTask, TEUtils.fromTask); /** * ```haskell * getDocumentSnapshotsFromQuerySnapshot :: QuerySnapshot -> [DocumentSnapshot] * ``` */ export const getDocumentSnapshotsFromQuerySnapshot = prop('docs'); /** * ```haskell * getModelsFromQuerySnapshot :: QuerySnapshot -> Either [Model] Error * ``` */ export const getModelsFromQuerySnapshot = pipe(getDocumentSnapshotsFromQuerySnapshot, map(getModelFromDocumentSnapshot), A.array.sequence(E.either)); /** * ```haskell * getModelsFromQuery :: Query -> TaskEither [Model] Error * ``` */ export const getModelsFromQuery = pipe(getSnapshotFromQuery, TE.chainEitherK(getModelsFromQuerySnapshot)); /** * ```haskell * getModelsInCollectionWhere :: Collection -> ReaderTaskEither [Condition] [Model] Error * ``` */ export const getModelsInCollectionWhere = pipe(getQueryFromCollection, RTE.fromReaderEither, RTE.chainTaskEitherK(getModelsFromQuery)); /** * ```haskell * getModelsInFirestoreWhere :: Firestore -> Reader String (ReaderTaskEither [Condition] [Model] Error) * ``` */ export const getModelsInFirestoreWhere = pipe(getCollectionFromFirestore, R.map(getModelsInCollectionWhere)); /** * ```haskell * getModelsInCollection :: Collection -> TaskEither [Model] Error * ``` */ export const getModelsInCollection = pipe(listDocumentsInCollection, TE.chain(pipe(map(getModelFromDocument), A.array.sequence(TE.taskEither)))); /** * ```haskell * getModelsInFirestore :: Firestore -> ReaderTaskEither String [Model] Error * ``` */ export const getModelsInFirestore = pipe(getCollectionFromFirestore, R.map(getModelsInCollection)); //# sourceMappingURL=index.js.map