function renderDirectoryContentsTable(pieces: Piece[], folder: Folder): string { let table = [ '<table>', ' <thead>', ' <th class="first"></th>', // todo image ' <th>Name</th>', ' <th>Modified</th>', ' <th>Size</th>', ' </thead>', ' <tbody>' ].join('\n'); const sorted = folder.sort(compareFolder); let alt: boolean; let item: Either<FolderName, File>; let name: string; let href: string; for (let i = 0, len = sorted.length; i < len; i++) { alt = (i % 2) === 0; item = sorted[i]; name = isLeft(item) ? (item.value === '' ? '..' : item.value) : item.value.name; href = addCurrentDir(pieces, name) table += alt ? '<tr class="alt">' : '<tr>\n'; table += `<td class="first${isLeft(item) ? ' icon-dir' : ''}"></td>\n`; table += `<td><a href="${href}">${name}</a></td>\n`; table += `<td>${isRight(item) && isJust(item.value.getModified) ? formatCalender(item.value.getModified.value) : ''}</td>\n`; table += `<td>${isRight(item) ? prettyShow(item.value.size) : ''}</td>\n`; table += '</tr>\n'; } table += ' </tbody>\n'; table += '</table>\n'; return table; }
function go(e: P.Either<E, P.Either<A, B>>): P.Either<P.Either<E, P.Either<A, B>>, P.Either<E, B>> { if (P.isLeft(e)) { return P.right(e); } const ret = e.value; if (P.isLeft(ret)) { return P.left(f(ret.value)); } return P.right(ret); }
return Q.assertTask(T.co(function* () { const sup = T.makeSupervisor(); function action(s: string) { return T.delay(20).map(() => s); } let fib: T.Fiber<string> = yield T.forkWith(sup, action('bar')); let fib2: T.Fiber<string> = yield T.forkWith(sup, action('foo')); yield T.killAll(new Error('kill All'), sup); const s1: P.Either<Error, string> = yield T.attempt(T.joinFiber(fib)); const s2: P.Either<Error, string> = yield T.attempt(T.joinFiber(fib2)); return T.pure(P.isLeft(s1) && P.isLeft(s2)); }));
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)); });
return defParser(s => { const ret = this.fn(s); if (P.isLeft(ret)) { return ret.value.pos === s.pos ? other.fn(s) : ret; } return ret; });
test('reading from an empty Chan blocks', function* () { const chan: Q.Chan<number> = yield Q.newChan; const r: P.Either<void, number> = yield compete(T.delay(50), Q.readChan(chan)); assert.ok(P.isLeft(r)); return T.pure(void 0); });
function compareFolder(fa: Either<FolderName, File>, fb: Either<FolderName, File>): 0 | 1 | -1 { if (isLeft(fa) && isRight(fb)) { return -1; } if (isRight(fa) && isLeft(fb)) { return 1; } if (isLeft(fa) && isLeft(fb)) { return fa.value < fb.value ? -1 : fa.value === fb.value ? 0 : 1; } if (isRight(fa) && isRight(fb)) { let a = fa.value.name, b = fb.value.name; return a < b ? -1 : a === b ? 0 : 1; } // should never reached here return 0; }
export function tailRec<A, B>( i: A, f: (i: A) => P.Either<A, B> ): B { let current = f(i); while (P.isLeft(current)) { current = f(current.value); } return current.value; }
it('should report error from storage', async function () { const middleware = mutter({ getStorage: getTntStorage }); const form = new FormData(); form.append('small', file('small0.txt')); const result = await T.toPromise(T.attempt(submitForm(middleware, form))); assert.ok(isLeft(result)); assert.equal((result.value as any).message, 'tnt storage handleFile'); });
it('should respect file key limit', async function () { const middleware = mutter({ limits: { fieldNameSize: 4 } }); const form = new FormData(); form.append('small0', file('small0.txt')); const result = await T.toPromise(T.attempt(submitForm(middleware, form))); assert.ok(isLeft(result)); assert.equal((result.value as any).code, 'LIMIT_FIELD_KEY'); });