import fs from "fs" ; import http from "http" ; import { Server } from "net" ; import { promisify } from "util" ; import fetch , { Headers } from "cross-fetch" ; import { Application } from "express" ; import { camelCase } from "lodash" ; import pluralize from "pluralize" ; const customPrefix = /(?:__[a-z])$/ ; export const exists = promisify ( fs . exists ) ; export namespace display { export function address ( server ) { const info = server . address ( ) ; const protocol = "http" ; if ( info == null ) { return "" ; } if ( typeof info === "string" ) { return `${ protocol }://${ info }` ; } switch ( info . address ) { case "127.0.0.1" : case "0.0.0.0" : case "::" : { return `${ protocol }://localhost:${ info . port }` ; } default : { return `${ protocol }://${ info . address }:${ info . port }` ; } } } } export namespace json { const readFile = promisify ( fs . readFile ) ; const writeFile = promisify ( fs . writeFile ) ; export async function post < T = any > ( input , body ) { const response = await fetch ( input , { body : JSON . stringify ( body ) , method : "POST" , headers : new Headers ( { "Content-Type" : "application/json" , } ) , } ) ; return [ await response . json ( ) , response ] ; } export async function read < T = any > ( path ) { return JSON . parse ( await readFile ( path , "utf8" ) ) ; } export async function write ( path , json ) { await writeFile ( path , `${ JSON . stringify ( json , null , 2 ) }\n` , "utf8" ) ; } } export namespace net { export async function listen ( app , port ) { const server = http . createServer ( app ) ; return new Promise ( ( resolve , reject ) => { server . once ( "error" , reject ) ; server . listen ( port , ( ) => { server . off ( "error" , reject ) ; resolve ( [ display . address ( server ) , server ] ) ; } ) ; } ) ; } } export namespace string { export const { plural , singular } = pluralize ; export function fieldify ( input ) { return camelCase ( normalize ( input ) ) ; } export function typeify ( input ) { return pascalCase ( normalize ( input ) ) ; } function normalize ( input ) { return customPrefix . test ( input ) ? input . substr ( 0 , input . length - 3 ) : input ; } function pascalCase ( [ first , ... rest ] ) { return first . toUpperCase ( ) + camelCase ( rest . join ( "" ) ) ; } } export function isDevEnv ( ) { return process . env . NODE_ENV !== "production" ; } export async function mkdir ( path ) { return new Promise ( resolve => { fs . mkdir ( path , ( ) => resolve ( ) ) ; } ) ; }