mirror of
https://github.com/Drop-OSS/headscalez.git
synced 2026-01-30 20:55:17 +01:00
initial commit
This commit is contained in:
5
.eslintrc
Normal file
5
.eslintrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": [
|
||||
"@nuxtjs/eslint-config-typescript"
|
||||
]
|
||||
}
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
node_modules
|
||||
*.log*
|
||||
dist
|
||||
77
README.md
Normal file
77
README.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# 🥭 mongoz
|
||||
|
||||
> Ad hoc MongoDB server for Node.js
|
||||
|
||||
## Why?
|
||||
|
||||
[MongoDB](https://www.mongodb.com) is fantastic but setup for small projects can be lots of trouble.
|
||||
|
||||
This little package does everything necessary to download and start a fresh mongo server!
|
||||
|
||||
## Usage
|
||||
|
||||
**Note:** You need to have [Node.js](https://nodejs.org/en/) and [npm](https://docs.npmjs.com/cli/v7/commands/npm) already installed!
|
||||
|
||||
**Note:** Make sure there is not already a local mongodb server listening on default port (`2701`). If you do, either stop it or use `PORT` environment variable to change the port.
|
||||
|
||||
### Standalone Server
|
||||
|
||||
Let's start a fresh mongoz shall we?
|
||||
|
||||
```sh
|
||||
npx mongoz
|
||||
```
|
||||
|
||||
It will take few seconds on first time of usage to install and extract mongo server.
|
||||
|
||||
### Programmatic Usage
|
||||
|
||||
Do you need a MongoDB server? No problems!
|
||||
|
||||
```js
|
||||
// CommonJS
|
||||
const { startMongo } = require('mongoz')
|
||||
|
||||
// ESM
|
||||
import { startMongo } from 'mongoz'
|
||||
|
||||
// Install and start listening MongoDB on 127.0.0.1:27017 in background
|
||||
await startMongo()
|
||||
```
|
||||
|
||||
When closing server, mongo will also gracefully shutdown with [node-graceful-shutdown](https://www.npmjs.com/package/node-graceful-shutdown).
|
||||
|
||||
### In parallel with server
|
||||
|
||||
You can also use [concurrently](https://www.npmjs.com/package/concurrently) to start mongo alongside with server:
|
||||
|
||||
`package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start": "concurrently 'npx mongoz' 'node ./server.mjs'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or directly with `npx`:
|
||||
|
||||
```sh
|
||||
npx concurrently 'npx mongoz' 'node ./server.mjs'
|
||||
```
|
||||
|
||||
## Supported platforms
|
||||
|
||||
Windows, Linux and Darwin (Mac) are supported. Check [formula](./src/formula) for details.
|
||||
|
||||
## Changing data dir
|
||||
|
||||
By default, we use a temporary directory to store data and logs. You can customize it with `MONGO_DIR` environment variable.
|
||||
|
||||
## License
|
||||
|
||||
MIT.
|
||||
|
||||
See [MongoDB Licensing](https://www.mongodb.com/community/licensing) for underlying server license.
|
||||
|
||||
3
bin/mongoz
Executable file
3
bin/mongoz
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
require('../dist/cli')
|
||||
10
build.config.ts
Normal file
10
build.config.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineBuildConfig } from 'unbuild'
|
||||
|
||||
export default defineBuildConfig({
|
||||
declaration: true,
|
||||
entries: [
|
||||
'./src/cli',
|
||||
'./src/index'
|
||||
],
|
||||
inlineDependencies: true
|
||||
})
|
||||
39
package.json
Normal file
39
package.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "mongoz",
|
||||
"version": "0.0.0",
|
||||
"repository": "unjs/mongoz",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"exports": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"bin": "./bin/mongoz",
|
||||
"files": [
|
||||
"dist",
|
||||
"bin"
|
||||
],
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .ts,.js",
|
||||
"prepack": "unbuild",
|
||||
"dev": "jiti ./src/cli.ts",
|
||||
"start": "npx concurrently 'yarn dev' 'node server.mjs'",
|
||||
"release": "yarn test && standard-version && git push --follow-tags && npm publish",
|
||||
"test": "yarn lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"download": "^8.0.0",
|
||||
"ora": "^5.4.1",
|
||||
"decompress": "^4.2.1",
|
||||
"consola": "^2.15.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"node-graceful-shutdown": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config-typescript": "^6.0.1",
|
||||
"eslint": "^7.30.0",
|
||||
"execa": "^5.1.1",
|
||||
"jiti": "^1.10.1",
|
||||
"standard-version": "^9.3.0",
|
||||
"typescript": "^4.3.5",
|
||||
"unbuild": "^0.3.1"
|
||||
}
|
||||
}
|
||||
11
src/cli.ts
Normal file
11
src/cli.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { startMongo } from './index'
|
||||
|
||||
async function main() {
|
||||
const args = process.argv.splice(2)
|
||||
const mongoserver = await startMongo({ args })
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
21
src/formula.ts
Normal file
21
src/formula.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
export const mongoFormula = {
|
||||
name: 'mongo',
|
||||
version: '4.4.2',
|
||||
port: 27017,
|
||||
exec: 'bin/mongod',
|
||||
execArgs: '--port {port} --dbpath {data}',
|
||||
platforms: [
|
||||
{
|
||||
name: 'linux',
|
||||
source: 'https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.2.tgz'
|
||||
},
|
||||
{
|
||||
name: 'win32',
|
||||
source: 'https://fastdl.mongodb.org/windows/mongodb-windows-x86_64-4.4.2.zip'
|
||||
},
|
||||
{
|
||||
name: 'darwin',
|
||||
source: 'https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-4.4.2.tgz'
|
||||
}
|
||||
]
|
||||
}
|
||||
84
src/index.ts
Normal file
84
src/index.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import path from 'path'
|
||||
import os from 'os'
|
||||
import fsExtra from 'fs-extra'
|
||||
import download from 'download'
|
||||
import consola from 'consola'
|
||||
import decompress from 'decompress'
|
||||
import execa from 'execa'
|
||||
import ora from 'ora'
|
||||
import { onShutdown } from 'node-graceful-shutdown'
|
||||
import { mongoFormula as formula } from './formula'
|
||||
|
||||
export async function startMongo (opts = { args: null }) {
|
||||
const platformName = process.platform
|
||||
let platform = formula.platforms.find(p => p.name === platformName)
|
||||
if (!platform) {
|
||||
throw new Error(`Platform '${platformName}' is not available for '${formula.name}'`)
|
||||
}
|
||||
|
||||
const instanceName = 'default'
|
||||
const appDir = process.env.MONGO_DIR || path.resolve(os.tmpdir(), formula.name)
|
||||
|
||||
// Resolve paths
|
||||
const dataDir = path.resolve(appDir, 'data', instanceName, formula.name)
|
||||
const logsDir = path.resolve(appDir, 'logs', instanceName, formula.name)
|
||||
const logFile = path.resolve(logsDir, 'logs.txt')
|
||||
const sourceDir = path.resolve(appDir, 'source', formula.name, formula.version, platform.name)
|
||||
const sourceFileName = `${formula.name}-${formula.version}-${platform.name}` + path.extname(platform.source)
|
||||
const sourceFile = path.resolve(sourceDir, sourceFileName)
|
||||
const extractDir = path.resolve(sourceDir, 'unpacked')
|
||||
const execFile = path.resolve(extractDir, formula.exec)
|
||||
|
||||
// Ensure data dir exists
|
||||
await fsExtra.mkdirp(dataDir)
|
||||
|
||||
// Show a spinner
|
||||
const spinner = ora()
|
||||
|
||||
// Ensure package is installed
|
||||
if (!fsExtra.existsSync(extractDir) || !fsExtra.existsSync(execFile)) {
|
||||
if (!fsExtra.existsSync(sourceFile)) {
|
||||
const dlMessage = `Downloading ${sourceFileName}`
|
||||
spinner.start(dlMessage + '...')
|
||||
const res = download(platform.source, sourceDir, { filename: sourceFileName })
|
||||
res.on('downloadProgress', (e) => {
|
||||
spinner.text = `${dlMessage} | ${Math.round(e.percent * 100)}%`
|
||||
})
|
||||
await res
|
||||
}
|
||||
spinner.start(`Decompressing ${sourceFileName}...`)
|
||||
await decompress(sourceFile, extractDir, { strip: 1 })
|
||||
spinner.stop()
|
||||
}
|
||||
await fsExtra.mkdirp(logsDir)
|
||||
await fsExtra.remove(logFile)
|
||||
|
||||
// Open logs file
|
||||
let stdout, stderr
|
||||
const logsFile = await fsExtra.open(logFile, 'w+')
|
||||
stdout = stderr = logsFile
|
||||
consola.info(`Writing logs to: ${logFile}`)
|
||||
|
||||
// Port and args
|
||||
const port = process.env.PORT || formula.port
|
||||
const execArgs = formula.execArgs.replace('{port}', port + '').replace('{data}', dataDir).split(' ')
|
||||
if (Array.isArray(opts.args)) {
|
||||
execArgs.push(...opts.args)
|
||||
}
|
||||
|
||||
// Start app
|
||||
spinner.info(`Starting ${formula.name} at port ${port}`)
|
||||
const server = execa(execFile, execArgs, {
|
||||
stdout,
|
||||
stderr
|
||||
})
|
||||
|
||||
const close = () => Promise.resolve(server.cancel())
|
||||
|
||||
onShutdown(() => close())
|
||||
|
||||
return {
|
||||
server,
|
||||
close
|
||||
}
|
||||
}
|
||||
6
tsconfig.json
Normal file
6
tsconfig.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "Node",
|
||||
"esModuleInterop": true
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user