Skip to content

Commit

Permalink
Merge pull request #11 from curvenote/feat/session
Browse files Browse the repository at this point in the history
User Sessions
  • Loading branch information
rowanc1 authored Jan 16, 2022
2 parents 619fb70 + 09e9637 commit d426232
Show file tree
Hide file tree
Showing 25 changed files with 262 additions and 125 deletions.
13 changes: 8 additions & 5 deletions src/actions/getChildren.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { VersionId } from '@curvenote/blocks';
import { Block, Version } from '../models';
import { Session } from '../session';
import { ISession } from '../session/types';

export async function getChildren(session: Session, versionId: VersionId) {
const { status, json } = await session.get(
`/blocks/${versionId.project}/${versionId.block}/versions/${versionId.version}/children`,
);
export async function getChildren(session: ISession, versionId: VersionId) {
const url = `/blocks/${versionId.project}/${versionId.block}/versions/${versionId.version}/children`;
session.log.debug(`Fetching version children: ${url}`);
const { status, json } = await session.get(url);
if (status !== 200) throw new Error('Could not get children');
session.log.debug(
`Version children include ${json.blocks.items.length} block(s) and ${json.versions.items} version(s)`,
);
const blocks = json.blocks.items.map((item: any) => {
const block = new Block(session, item.id);
block.data = item;
Expand Down
12 changes: 6 additions & 6 deletions src/actions/getLatest.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { ALL_BLOCKS, BlockId } from '@curvenote/blocks';
import { ALL_BLOCKS, BlockId, versionIdToString } from '@curvenote/blocks';
import { Block, Version, VersionQueryOpts } from '../models';
import { Session } from '../session';
import { ISession } from '../session/types';

export async function getLatestVersion<T extends ALL_BLOCKS>(
session: Session,
session: ISession,
blockId: BlockId,
query?: VersionQueryOpts,
) {
const block = await new Block(session, blockId).get();
const { latest_version } = block.data;
if (!latest_version) throw new Error('Block has no versions');
const version = await new Version<T>(session, { ...block.id, version: latest_version }).get(
query,
);
const versionId = { ...block.id, version: latest_version };
session.log.debug(`Fetching latest version of block: ${versionIdToString(versionId)}`);
const version = await new Version<T>(session, versionId).get(query);
return { block, version };
}
12 changes: 6 additions & 6 deletions src/base.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { JsonObject } from '@curvenote/blocks';
import { AnyAction } from '@reduxjs/toolkit';
import { Session } from './session/session';
import { ISession } from './session/types';
import { RootState } from './store';

export class BaseTransfer<
Expand All @@ -10,7 +10,7 @@ export class BaseTransfer<
> {
modelKind = '';

session: Session;
session: ISession;

id: ID;

Expand All @@ -28,7 +28,7 @@ export class BaseTransfer<

$recieve?: (dto: DTO) => AnyAction;

constructor(session: Session, id: ID) {
constructor(session: ISession, id: ID) {
this.id = id;
this.session = session;
}
Expand All @@ -41,12 +41,12 @@ export class BaseTransfer<
set data(data: DTO) {
this.id = data.id;
this.$data = this.$fromDTO(data.id, data);
if (this.$recieve) this.session.$store.dispatch(this.$recieve(data));
if (this.$recieve) this.session.store.dispatch(this.$recieve(data));
}

async get(query?: GetOptions) {
const url = this.$createUrl();
const fromSession = this.$selector?.(this.session.$store.getState(), this.id);
const fromSession = this.$selector?.(this.session.store.getState(), this.id);
if (fromSession) {
this.session.log.debug(`Loading ${this.modelKind} from cache: "${url}"`);
this.data = fromSession;
Expand All @@ -60,7 +60,7 @@ export class BaseTransfer<
}
throw new Error(`${this.modelKind}: Not found (${url}) or you do not have access.`);
}
this.data = json;
this.data = json as any;
return this;
}
}
5 changes: 3 additions & 2 deletions src/cli/services/auth.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Command } from 'commander';
import { MyUser, Session } from '../..';
import { MyUser } from '../..';
import { ISession } from '../../session/types';
import { clirun } from './utils';

async function checkAuth(session: Session) {
async function checkAuth(session: ISession) {
if (session.isAnon) {
session.log.error('Your session is not authenticated.');
return;
Expand Down
6 changes: 4 additions & 2 deletions src/cli/services/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function addTokenCLI(program: Command) {
.command('set <token>')
.description('Set a token and save to a config directory')
.action(
clirun(async (_, token: string) => setToken(token), {
clirun(async (_session, token: string) => setToken(token), {
program,
session: anonSession(program),
}),
Expand All @@ -19,6 +19,8 @@ export function addTokenCLI(program: Command) {
.command('delete')
.alias('remove')
.description('Delete all tokens from the config directory')
.action(clirun(deleteToken, { program, session: anonSession(program) }));
.action(
clirun((session) => deleteToken(session.log), { program, session: anonSession(program) }),
);
program.addCommand(command);
}
18 changes: 9 additions & 9 deletions src/cli/services/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Command } from 'commander';
import { Session } from '../../..';
import { chalkLogger, LogLevel } from '../../../logging';
import { getToken } from '../../../session';
import { ISession } from '../../../session/types';

function getLogLevel(level: LogLevel | Command = LogLevel.info): LogLevel {
let useLevel: LogLevel = typeof level === 'number' ? level : LogLevel.info;
Expand All @@ -13,23 +14,22 @@ function getLogLevel(level: LogLevel | Command = LogLevel.info): LogLevel {
}

export function anonSession(level?: LogLevel | Command) {
const session = new Session();
session.$logger = chalkLogger(getLogLevel(level));
const logger = chalkLogger(getLogLevel(level));
const session = new Session(undefined, { logger });
return session;
}

export function getSession(level?: LogLevel | Command): Session {
const logger = chalkLogger(getLogLevel(level));
const token = process.env.CURVENOTE_TOKEN || getToken();
const token = getToken(logger);
if (!token) {
logger.warn('No token was found in settings or CURVENOTE_TOKEN. Session is not authenticated.');
logger.info('You can set a token with:');
logger.info('curvenote token set YOUR_API_TOKEN');
logger.info('curvenote token set API_TOKEN');
}
let session;
try {
session = new Session(token);
session.$logger = logger;
session = new Session(token, { logger });
} catch (error) {
logger.error((error as Error).message);
logger.info('You can remove your token using:');
Expand All @@ -41,9 +41,9 @@ export function getSession(level?: LogLevel | Command): Session {

export function clirun(
func:
| ((session: Session, ...args: any[]) => Promise<void>)
| ((session: Session, ...args: any[]) => void),
cli: { program: Command; session?: Session },
| ((session: ISession, ...args: any[]) => Promise<void>)
| ((session: ISession, ...args: any[]) => void),
cli: { program: Command; session?: ISession },
) {
return async (...args: any[]) => {
const useSession = cli.session ?? getSession(cli.program);
Expand Down
9 changes: 7 additions & 2 deletions src/export/jupyter-book/exportAll.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Blocks, KINDS } from '@curvenote/blocks';
import { articleToMarkdown, Session, Version } from '../..';
import { articleToMarkdown, Version } from '../..';
import { getLatestVersion } from '../../actions/getLatest';
import { ISession } from '../../session/types';
import { ArticleState } from '../utils';
import { writeBibtex } from '../utils/writeBibtex';

interface Options {
bibtex?: string;
}

export async function exportAll(session: Session, nav: Version<Blocks.Navigation>, opts?: Options) {
export async function exportAll(
session: ISession,
nav: Version<Blocks.Navigation>,
opts?: Options,
) {
const { bibtex = 'references.bib' } = opts ?? {};
const blocks = await Promise.all(
nav.data.items.map((item) => getLatestVersion(session, item.blockId)),
Expand Down
4 changes: 2 additions & 2 deletions src/export/jupyter-book/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { ProjectId, Blocks } from '@curvenote/blocks';
import { Project } from '../../models';
import { Session } from '../../session';
import { exportFromProjectLink } from '../utils';
import { getLatestVersion } from '../../actions/getLatest';
import { writeTOC } from './toc';
import { exportAll } from './exportAll';
import { writeConfig } from './config';
import { ISession } from '../../session/types';

type Options = {
something?: string;
};

export async function projectToJupyterBook(session: Session, projectId: ProjectId, opts: Options) {
export async function projectToJupyterBook(session: ISession, projectId: ProjectId, opts: Options) {
const [project, { version: nav }] = await Promise.all([
new Project(session, projectId).get(),
getLatestVersion<Blocks.Navigation>(session, { project: projectId, block: 'nav' }),
Expand Down
5 changes: 3 additions & 2 deletions src/export/jupyter-book/toc.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import fs from 'fs';
import YAML from 'yaml';
import { Blocks } from '@curvenote/blocks';
import { Block, Session, Version } from '../..';
import { Block, Version } from '../..';
import { ISession } from '../../session/types';

interface Options {
filename: string;
}

export async function writeTOC(session: Session, nav: Version<Blocks.Navigation>, opts?: Options) {
export async function writeTOC(session: ISession, nav: Version<Blocks.Navigation>, opts?: Options) {
const { filename = '_toc.yml' } = opts ?? {};
const items = await Promise.all(
nav.data.items.map(async (item) => {
Expand Down
4 changes: 2 additions & 2 deletions src/export/markdown/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import YAML from 'yaml';
import { VersionId, KINDS, oxaLink, formatDate } from '@curvenote/blocks';
import { toMarkdown } from '@curvenote/schema';
import { Block, Version, User } from '../../models';
import { Session } from '../../session';
import { getChildren } from '../../actions/getChildren';
import { exportFromOxaLink, walkArticle, writeImagesToFiles } from '../utils';
import { localizationOptions } from '../utils/localizationOptions';
import { ISession } from '../../session/types';

type Options = {
filename: string;
images?: string;
};

export async function articleToMarkdown(session: Session, versionId: VersionId, opts: Options) {
export async function articleToMarkdown(session: ISession, versionId: VersionId, opts: Options) {
const [block, version] = await Promise.all([
new Block(session, versionId).get(),
new Version(session, versionId).get(),
Expand Down
14 changes: 9 additions & 5 deletions src/export/pdf/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import fs from 'fs';
import util from 'util';
import { exportFromOxaLink, exec } from '../utils';
import { articleToTex } from '../tex';
import { Session } from '../../session';
import { TexExportOptions } from '../tex/types';
import { ISession } from '../../session/types';

const copyFile = util.promisify(fs.copyFile);

export async function articleToPdf(session: Session, versionId: VersionId, opts: TexExportOptions) {
export async function articleToPdf(
session: ISession,
versionId: VersionId,
opts: TexExportOptions,
) {
const basename = path.basename(opts.filename, path.extname(opts.filename));
const tex_filename = `${basename}.tex`;
const pdf_filename = `${basename}.pdf`;
Expand All @@ -26,17 +30,17 @@ export async function articleToPdf(session: Session, versionId: VersionId, opts:
try {
await exec(CMD);
} catch (err) {
session.$logger.error(`Error while invoking mklatex: ${err}`);
session.log.error(`Error while invoking mklatex: ${err}`);
}

const built_pdf = path.join('_build', pdf_filename);
if (!fs.existsSync(built_pdf)) {
session.$logger.error(`Could not find ${built_pdf} as expected, pdf export failed`);
session.log.error(`Could not find ${built_pdf} as expected, pdf export failed`);
throw Error(`Could not find ${built_pdf} as expected, pdf export failed`);
}

await copyFile(built_pdf, pdf_filename);
session.$logger.debug(`Copied PDF file to ${pdf_filename}`);
session.log.debug(`Copied PDF file to ${pdf_filename}`);

return article;
}
Expand Down
6 changes: 3 additions & 3 deletions src/export/tex/frontMatter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import YAML from 'yaml';
import { Author, Blocks, oxaLink } from '@curvenote/blocks';
import { Session } from 'session';
import { toTex } from '@curvenote/schema';
import { Block, User, Version } from '../../models';
import { getEditorState } from '../../actions/utils';
import { ISession } from '../../session/types';

function escapeLatex(maybeUnsafe: string): string {
return toTex(getEditorState(`<p>${maybeUnsafe}</p>`).doc);
Expand Down Expand Up @@ -72,7 +72,7 @@ function getCorresponsingAuthorNames(options: {
}

async function toAuthorFields(
session: Session,
session: ISession,
author: Author,
corresponding: Set<string>,
): Promise<ExportAuthorModel> {
Expand All @@ -90,7 +90,7 @@ async function toAuthorFields(
}

export async function buildFrontMatter(
session: Session,
session: ISession,
block: Block,
version: Version<Blocks.Article>,
tagged: Record<string, string>,
Expand Down
Loading

0 comments on commit d426232

Please sign in to comment.