import { homedir } from "os" ; import * as fs from "fs-extra" ; import * as path from "path" ; import * as api from "./utils/api" ; import { error } from "./utils/log" ; import { IS_STAGING } from "./utils/env" ; const ms = require ( "ms" ) ; const TTL = ms ( "8h" ) ; export interface IUser { avatar_url : string ; email : string ; id : string ; name : string ; username : string ; jwt : string ; } export interface IConfig { [ key ] : any | undefined ; lastUpdate ? : number ; user ? : IUser ; } const CONFIG_NAME = IS_STAGING ? ".codesandbox-staging.json" : ".codesandbox.json" ; const file = process . env . CODESANDBOX_JSON ? path . resolve ( process . env . CODESANDBOX_JSON ) : path . resolve ( homedir ( ) , CONFIG_NAME ) ; param { Object } data async function save ( data ) { await fs . writeFile ( file , JSON . stringify ( data , null , 2 ) ) ; } /**
 * Load and parse config file
 */ export async function read ( ) { let existing = { } ; try { const fileData = await ( fs . readFile ( file , "utf8" ) as Promise < string > ) ; existing = JSON . parse ( fileData ) ; } catch ( err ) { } if ( ! existing . token ) { return { } ; } if ( ! existing . lastUpdate || Date . now ( ) - existing . lastUpdate > TTL ) { const token = existing . token ; try { const user = await api . fetchUser ( token ) ; if ( user ) { existing = { ... existing , user , lastUpdate : Date . now ( ) } ; await save ( existing ) ; } else { await deleteUser ( ) ; } } catch ( e ) { error ( "Could not authorize the user." ) ; await deleteUser ( ) ; } } return existing ; } export async function remove ( key ) { const cfg = await read ( ) ; if ( key in cfg ) { delete cfg [ key ] ; } await fs . writeFile ( file , JSON . stringify ( cfg , null , 2 ) ) ; } param data export async function merge ( data ) { const oldConfig = await read ( ) ; const cfg = { ... oldConfig , ... data } ; await save ( cfg ) ; return cfg ; } export export async function deleteUser ( ) { await save ( { } ) ; } export param { User } user returns export function saveUser ( token , user ) { return merge ( { user , token , lastUpdate : Date . now ( ) } ) ; } export returns export async function getUser ( ) { const cfg = await read ( ) ; return cfg . user ; } export async function getToken ( ) { const cfg = await read ( ) ; return cfg . token ; } export const removeFile = async ( ) => fs . remove ( file ) ;