Skip to content

Instantly share code, notes, and snippets.

const userExistsHandler = (userExists: boolean): E.Either<t.Error, boolean> => {
if (R.equals(userExists, true)) {
return E.left({
statusCode: 400,
errorType: t.ErrorType.generic,
errorMessage: 'User already exists'
});
} else {
return E.right(true);
}
interface System {
pgclient: Client;
someKey?: string;
someOtherKey?: string;
}
interface Entity {
entityType: EntityType;
entity: any | any[]; // ok this will aspirationally be an actual entity map when we can enumerate every single one in all the different namespaces
}
// although the error code implies http status, could also
// be exitcode
//
// if you're paying attention you'll notice that this is
// essentially equivalent to the existing reponse type
const getSavesByUserIdRTE = (id: string): RTE.ReaderTaskEither<db.System, t.Error, pg.QueryResult<st.DbSave[]>> =>
(system: db.System): TE.TaskEither<t.Error, pg.QueryResult<st.DbSave[]>> =>
TE.tryCatch(
() => getSavesByUserId(system.pgclient, id),
() => { return { statusCode: 500, errorType: t.ErrorType.generic, errorMessage: 'Could not retrieve saves' }; });
const deletePipeline = (event: requests.MinimalRequestEvent): RTE.ReaderTaskEither<db.System, t.Error, t.Entity> =>
Do(RTE.readerTaskEither)
.bind('eventBody', RTE.fromEither(requests.getParsedEventBody(event)))
.doL(({ eventBody }) => RTE.fromEither(su.validateBodyE(ss.saveDelete, eventBody)))
.bindL('dbLookupFn', ({ eventBody }) => RTE.fromEither(payloadToDbFn(eventBody)))
.bindL('saveRes', ({ dbLookupFn }) => dbLookupFn())
.bindL('save', ({ saveRes }) => RTE.fromEither(sXfms.getSaveFromResE(saveRes)))
.doL(({ save }) => checkIdAgainstHeaderRTE(event, save.user_uuid_id))
.doL(({ save }) => sDb.deleteSaveRTE(save.id))
.return(() => { return { entityType: t.EntityType.success, entity: 'Save deleted' }; });
const pipeline = pipe(
TE.fromEither(getIdFromPath(event)), // start a pipe of TaskEither
TE.chain(uid => getUser(client, uid)),
TE.chainEitherK(getUserFromRes), // chainEitherK: <E, A, B>(f: (a: A) => E.Either<E, B>) => (ma: TaskEither<E, A>) => TaskEither<E, B>
TE.chainEitherK(userToSharable),
TE.map(userWithoutPII => responses.respond200('<your-project>/user', userWithoutPII)));
'use strict';
import * as R from 'ramda';
import * as responses from '../../common/responses';
import * as db from '../../common/db';
import * as uDb from '../../common/users/db';
import * as uXfms from '../../common/users/transformations';
// welcome to the party, pal
import { pipe } from 'fp-ts/lib/pipeable';
import * as T from 'fp-ts/lib/Task';
import * as E from 'fp-ts/lib/Either';
// -- handler namespace --
'use strict';
import * as _ from 'lodash';
import * as responses from '../../common/responses';
import * as db from '../../common/db';
import * as uDb from '../../common/users/db';
import * as uXfms from '../../common/users/transformations';
export const usersGet = async (event): Promise<any> => {
@the-frey
the-frey / re-frame-workshop.md
Created February 17, 2020 14:14
Re-Frame Workshop Instructions

Re-Frame workshop

NB: This repo is available at the short URL https://tinyurl.com/ll-feb-20-workshop

The goal of this workshop is to better understand how re-frame event flows work, and how to build and debug re-frame apps.

The basics of the framework are simple, and scale pretty well, so we'll be going over the basics of the entire re-frame event flow.

Getting started

@the-frey
the-frey / cypress_videos_in_circleci.sh
Created January 28, 2020 10:22
debugging cypress in circleci using videos
# circle will give you some ssh creds
# open a session with the port and IP they give you
$ ssh -p 1234 1.1.1.1
# then, in another tab you can grab the video
$ scp -P <port> <ip>:/root/<yr-user>/path/to/cypress/videos/yr-failing-test.js.mp4 ./video.mp4