| 1 | // This file is part of HFS - Copyright 2021-2023, Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt |
| 2 | |
| 3 | import minimist from 'minimist' |
| 4 | import * as fs from 'fs' |
| 5 | import { homedir } from 'os' |
| 6 | import _ from 'lodash' |
| 7 | import { basename, dirname, join } from 'path' |
| 8 | import { formatTimestamp } from './cross' |
| 9 | import { argv } from './argv' |
| 10 | export * from './cross-const' |
| 11 | |
| 12 | export const API_VERSION = 13.1 |
| 13 | export const COMPATIBLE_API_VERSION = 1 // the day we break with the past, we'll update this |
| 14 | |
| 15 | // you can add arguments with this file, currently used for the update process on mac/linux. |
| 16 | // we are using homedir because it's the only stable path both the old and new process can agree on (open() doesn't preserve cwd) |
| 17 | export const ARGS_FILE = join(homedir(), 'hfs-args') |
| 18 | try { |
| 19 | const s = fs.readFileSync(ARGS_FILE, 'utf-8') |
| 20 | console.log('Additional arguments', s) |
| 21 | _.defaults(argv, minimist(JSON.parse(s))) |
| 22 | fs.unlinkSync(ARGS_FILE) |
| 23 | } |
| 24 | catch(e: any) { |
| 25 | if (e?.code !== 'ENOENT') |
| 26 | console.error(ARGS_FILE, String(e)) |
| 27 | } |
| 28 | |
| 29 | export const DEV = process.env.DEV ? 'DEV' : '' |
| 30 | export const ORIGINAL_CWD = process.cwd() |
| 31 | export const HFS_STARTED = new Date() |
| 32 | const PKG_PATH = join(__dirname, '..', 'package.json') |
| 33 | export const BUILD_TIMESTAMP = fs.statSync(PKG_PATH).mtime.toISOString() |
| 34 | const pkg = JSON.parse(fs.readFileSync(PKG_PATH,'utf8')) |
| 35 | export const VERSION = pkg.version as string |
| 36 | export const RUNNING_BETA = VERSION.includes('-') |
| 37 | export const IS_WINDOWS = process.platform === 'win32' |
| 38 | export const IS_MAC = process.platform === 'darwin' |
| 39 | export const IS_BINARY = !/node|bun/.test(basename(process.execPath)) // this won't be node if pkg was used |
| 40 | export const APP_PATH = dirname(IS_BINARY ? process.execPath : __dirname) // __dirname's parent can be compared with cwd |
| 41 | export const MIME_AUTO = 'auto' |
| 42 | export const CONFIG_FILE = 'config.yaml' |
| 43 | |
| 44 | if (argv.version) { |
| 45 | process.stdout.write(VERSION+ '\n') |
| 46 | process.exit(0) |
| 47 | } |
| 48 | |
| 49 | // we want this to be the first stuff to be printed, then we print it in this module, that is executed at the beginning |
| 50 | if (DEV) { |
| 51 | console.clear() |
| 52 | process.env.DEBUG = 'acme-client' |
| 53 | } |
| 54 | console.log(`HFS ~ HTTP File Server`) |
| 55 | console.log(`© Massimo Melina <a@rejetto.com> - License https://www.gnu.org/licenses/gpl-3.0.txt`) |
| 56 | console.log('Started', formatTimestamp(HFS_STARTED), DEV) |
| 57 | console.log('Version', VERSION||'-') |
| 58 | console.log('Build', BUILD_TIMESTAMP||'-') |
| 59 | // still considering whether to use ".hfs" with Windows users, who may be less accustomed to it |
| 60 | const dir = argv.cwd || useHomeDir() && join(homedir(), '.hfs') |
| 61 | if (dir) { |
| 62 | try { fs.mkdirSync(dir, { recursive: true }) } |
| 63 | catch(e: any) { |
| 64 | if (e.code !== 'EEXIST') |
| 65 | console.error(e) |
| 66 | } |
| 67 | process.chdir(dir) |
| 68 | } |
| 69 | else if (process.cwd().startsWith(process.env.windir + '\\')) // this happens if you run hfs from task scheduler |
| 70 | process.chdir(APP_PATH) |
| 71 | console.log('Working directory (cwd)', process.cwd()) |
| 72 | if (APP_PATH !== process.cwd()) |
| 73 | console.log('App', APP_PATH) |
| 74 | console.log('Node', process.version) |
| 75 | const bun = (globalThis as any).Bun |
| 76 | if (bun) console.log('Bun', bun.version) |
| 77 | console.log('Platform', process.platform, process.arch, IS_BINARY ? 'binary' : basename(process.execPath)) |
| 78 | console.log('Pid', process.pid) |
| 79 | setImmediate(() => // after commands.ts has handled console.debug |
| 80 | console.debug("Args", argv)) |
| 81 | |
| 82 | function useHomeDir() { |
| 83 | if (!IS_WINDOWS || !IS_BINARY) return true |
| 84 | try { fs.accessSync(CONFIG_FILE, fs.constants.W_OK) } |
| 85 | catch(e: any) { |
| 86 | if (e.code !== 'ENOENT') |
| 87 | return true |
| 88 | try { |
| 89 | fs.writeFileSync(CONFIG_FILE, '') // not found, try to create |
| 90 | fs.unlinkSync(CONFIG_FILE) |
| 91 | } |
| 92 | catch { return true } |
| 93 | } |
| 94 | } |