const lookupResult: T.Task<P.Either<string, LookupResult>> = T.co(function* () { const nonIndexResult: LookupResult = yield settings.lookupFile(pieces); if (nonIndexResult.tag === LookupResultType.LRFILE) { return T.pure(P.right(nonIndexResult)); } const eIndexResult: P.Either<string, LookupResult> = yield lookupIndices( settings.indices.map(ix => dropLastIfNull(pieces.concat(ix))) ); if (P.isLeft(eIndexResult)) { return T.pure(P.left(eIndexResult.value)); } const { value: indexResult } = eIndexResult; if (indexResult.tag === LookupResultType.LRNOTFOUND) { return T.pure(P.right(nonIndexResult)); } if (indexResult.tag === LookupResultType.LRFILE && settings.redirectToIndex) { const file = indexResult.file; return T.pure(P.left((function () { const repieces = pieces.slice().reverse(); if (repieces.length === 0) { return file.name; } const lastSegment = repieces[0]; if (lastSegment == '') return file.name; return `${lastSegment}/${file.name}`; })())); } return T.pure(P.right(indexResult)); });
function sendRsp( conn: Z.Connection, ii: Z.InternalInfo, status: H.Status, headers: H.ResponseHeaders, rsp: Rsp ): T.Task<[P.Maybe<H.Status>, P.Maybe<number>]> { switch (rsp.tag) { case RspType.RSPBUFFER: return conn.writeHead(status, headers) .chain(() => conn.sendAll(rsp.buffer)) .then(T.pure([P.just(status), P.just(Buffer.byteLength(rsp.buffer))] as [P.Maybe<H.Status>, P.Maybe<number>])); case RspType.RSPREADABLE: return conn.writeHead(status, headers) .chain(_ => conn.sendStream(rsp.readable)) .map(_ => [P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>]); case RspType.RSPNOBODY: return conn.writeHead(status, headers) .then(T.pure([P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>])); case RspType.RSPFILE: if (rsp.part != null) { const part = rsp.part; return sendRspFile2XX(conn, ii, status, addContentHeadersForFilePart(headers, part), rsp.path, part.offset, part.byteCount, rsp.isHead); } return T.attempt(ii.getFinfo(rsp.path)) .chain(efinfo => { if (P.isLeft(efinfo)) { return sendRspFile404(conn, ii, headers); } const rspFile = conditionalRequest(efinfo.value, headers, rsp.header); switch (rspFile.tag) { case RspFileInfoType.WITHBODY: return sendRspFile2XX(conn, ii, rspFile.status, rspFile.header, rsp.path, rspFile.offset, rspFile.length, rsp.isHead); case RspFileInfoType.WITHOUTBODY: return sendRsp(conn, ii, rspFile.status, headers, { tag: RspType.RSPNOBODY }); } }); case RspType.RSPSTREAM: return conn.writeHead(status, headers) .chain(_ => rsp.body(buff => conn.sendAll(buff))) .map(_ => [P.just(status), P.nothing] as [P.Maybe<H.Status>, P.Maybe<number>]); /* istanbul ignore next */ default: throw new TypeError('last argument to sendRsp must be Rsp'); } }
.chain(lr => { if (lr.tag === LookupResultType.LRNOTFOUND) { return lookupIndices(xs.slice(1)); } if (settings.addTrailingSlash) { const redirect = addTrailingSlash(request); if (redirect != null) { return T.pure(P.left(redirect)); } } return T.pure(P.right(lr)); });
return lookupResult.chain(res => { if (P.isLeft(res)) { return T.pure({ tag: StaticResponseType.RAWREDIRECT, path: res.value } as StaticResponse); } const { value: result } = res; if (result.tag === LookupResultType.LRNOTFOUND) { return T.pure({ tag: StaticResponseType.NOTFOUND } as StaticResponse); } if (result.tag === LookupResultType.LRFILE) { return serveFile(settings, request, result.file); } return serveFolder(settings, pieces, request, result.folder); });
export function parseRequestBody(ctx: HttpContext, opts?: MutterOptions): T.Task<[Params, Files]> { if (!requestHasBody(ctx.request)) return T.pure([{}, {}] as [Params, Files]); const mctype = getRequestBodyType(ctx.request); if (isNothing(mctype)) return T.pure([{}, {}] as [Params, Files]); const { value: ctype } = mctype; return ctype.tag === 'urlencoded' ? parseUrlEncodedBody(ctx, opts) : ctype.tag === 'multipart' ? parseMultipartBody(ctx, opts) : /* istanbul ignore next */ T.pure([{}, {}] as [Params, Files]); }
.chain(efinfo => { if (isLeft(efinfo)) { assert.equal(true, false); return T.pure(false); } const { value: finfo } = efinfo; let hs = S.assign({}, rsp.header, { 'Last-Modified': finfo.date }); let rsp2 = rspFileInfo(RspFileInfoType.WITHBODY, rsp.status, hs, rsp.offset, rsp.length); assert.deepEqual(conditionalRequest(finfo, {}, headers), rsp2); return T.pure(false); });
return T.co(function* () { const id: string = yield generateSessionId; const authId: null | string = yield ( auth === HasAuthId.HAS_AUTH_ID ? generateSessionId : T.pure(null)); const keys: string[] = yield T.sequencePar(replicateArr(20, randomString(8))); const values: string[] = yield T.sequencePar(replicateArr(20, randomString(16))); const data = fromPairs(zip(keys, values)); const now = Date.now(); return T.pure(createSession(id, authId, data, now - 1000, now)); });
function update( state: AppState<M, Q, S>, action: AppAction<M, Q, S, I> ): T.Task<AppState<M, Q, S>> { let next: Transition<M, S, I>, needsRender: boolean, nextState: AppState<M, Q, S>, appChange: AppChange<S, I>; switch (action.tag) { case AppActionType.INTERPRET: return state.interpret.loop(action.payload) .chain(ni => { return T.pure(S.assign({}, state, { interpret: ni })); }); case AppActionType.ACTION: next = app.update(state.model, action.payload); needsRender = state.needsRender || state.model !== next.model; nextState = S.assign({}, state, { needsRender, model: next.model }); appChange = { old: state.model, action: action.payload, model: nextState.model }; return onChange(appChange).then(T.forInPar(next.effects, pushEffect)).map(() => nextState); case AppActionType.RESTORE: needsRender = state.needsRender || state.model !== action.payload; nextState = S.assign({}, state, { needsRender, model: action.payload }); return T.pure(nextState); } }
.chain(() => { let st: AppState<M, Q, S> = { snabbdom , interpret: it2 , needsRender: false , model: app.init.model }; return T.pure({ update, commit, init: st}); });
it('storage.destroyAllOfAuthId should only delete relevant Auth Id', function* () { const master: Session = yield generateSession(HasAuthId.HAS_AUTH_ID); const authId = master.authId as string; const preslaves: Session[] = yield (replicateA(20, generateSession(HasAuthId.HAS_AUTH_ID)) .concat(replicateA(20, generateSession(HasAuthId.NO_AUTH_ID))) ); const slaves = preslaves.map(x => createSession(x.id, authId, x.data, x.createdAt, x.accessedAt)); const others: Session[] = yield (replicateA(20, generateSession(HasAuthId.HAS_AUTH_ID)) .concat(replicateA(20, generateSession(HasAuthId.NO_AUTH_ID))) ); const allS = [master].concat(slaves, others); // insert session yield T.forInPar_([master].concat(preslaves, others), x => run(storage.insert(x))); yield T.forInPar_(slaves, x => run(storage.replace(x))); const xs: (Session | null)[] = yield T.forInPar(allS, x => run(storage.get(x.id))); assert.deepEqual(xs, allS); yield run(storage.destroyAllOfAuthId(authId)); const ys: (Session | null)[] = yield T.forInPar(allS, x => run(storage.get(x.id))); const xxs = new Array(slaves.length + 1).fill(null); assert.deepEqual(ys, xxs.concat(others as any)); return T.pure(true); });