Skip to content

Commit

Permalink
beginning of JSON API (#1)
Browse files Browse the repository at this point in the history
* partial user, group, & session
* add GHA configs
* bring in SQL schemas
* ci: enable mysql service (ubuntu, macos, windows)
* feat(config): copy properties recursively
* session: get cookie params from config
* move http config into conf.d/http.yml
* ci: mark win as experimental
* doc(README): add ci & coverage badges
  • Loading branch information
msimerson authored Feb 19, 2024
1 parent c049177 commit 7555113
Show file tree
Hide file tree
Showing 42 changed files with 1,989 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
env:
node: true
es2021: true
extends: eslint:recommended
parserOptions:
ecmaVersion: latest
sourceType: module
rules: {}
110 changes: 110 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: CI

on:
push:
pull_request:

env:
CI: true
NODE_ENV: test

jobs:
lint:
uses: NicTool/.github/.github/workflows/lint.yml@main

coverage:
runs-on: ubuntu-latest
steps:
- name: Start MySQL
run: sudo /etc/init.d/mysql start
- uses: actions/setup-node@v4
- uses: actions/checkout@v4
- run: npm install
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- name: run coverage
run: npx -y c8 --reporter=lcov npm test
env:
NODE_ENV: cov
- name: codecov
uses: codecov/codecov-action@v2
- name: Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.github_token }}

get-lts:
runs-on: ubuntu-latest
steps:
- id: get
uses: msimerson/node-lts-versions@v1
outputs:
lts: ${{ steps.get.outputs.lts }}
active: ${{ steps.get.outputs.active }}

test:
needs: [ lint, get-lts ]
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
fail-fast: false
steps:
- name: Start MySQL
run: sudo /etc/init.d/mysql start
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: npm install
- run: npm test

test-mac:
needs: [ lint, get-lts ]
runs-on: macos-latest
strategy:
matrix:
node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
fail-fast: false
steps:
- name: Install & Start MySQL
run: |
brew install mysql
brew tap homebrew/services
brew services start mysql
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: npm install
- run: npm test

test-win:
# if: false
needs: [ lint, get-lts ]
runs-on: windows-latest
strategy:
matrix:
node-version: ${{ fromJson(needs.get-lts.outputs.active) }}
experimental: [true]
fail-fast: false
steps:
- name: Install MySQL
run: |
choco install mysql
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
name: Node ${{ matrix.node-version }} on ${{ matrix.os }}
with:
node-version: ${{ matrix.node-version }}
- name: Initialize MySQL
run: sh sql/init-mysql.sh
- run: npm install
- run: npm test
14 changes: 14 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: CodeQL

on:
push:
branches: [main]
pull_request:
# The branches below must be a subset of the branches above
branches: [main]
schedule:
- cron: '18 7 * * 4'

jobs:
codeql:
uses: NicTool/.github/.github/workflows/codeql.yml@main
18 changes: 18 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: publish

on:
push:
branches:
- main
paths:
- package.json
release:
types: [published]

env:
CI: true

jobs:
publish:
uses: NicTool/.github/.github/workflows/publish.yml@main
secrets: inherit
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

package-lock.json
3 changes: 3 additions & 0 deletions .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
trailingComma: 'all'
semi: false
singleQuote: true
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# api
[![Build Status](https://github.com/NicTool/api/actions/workflows/ci.yml/badge.svg)](https://github.com/NicTool/api/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/NicTool/api/badge.svg)](https://coveralls.io/github/NicTool/api)

# nt-api

nictool api


4 changes: 4 additions & 0 deletions conf.d/http.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

default:
host: localhost
port: 3000
27 changes: 27 additions & 0 deletions conf.d/mysql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

default:
host: 127.0.0.1
port: 3306
user: nictool
database: nictool
timezone: +00:00
dateStrings:
- DATETIME
- TIMESTAMP
decimalNumbers: true

production:
host: mysql
password: "********"

test:
user: root
password: root

cov:
user: root
password: root

development:
password: StaySafeOutThere
# socketPath: /opt/local/var/run/mysql82/mysqld.sock
30 changes: 30 additions & 0 deletions conf.d/session.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

default:
cookie:
# https://hapi.dev/module/cookie/api/?v=12.0.1
name: sid-nictool
password: af1b926a5e21f535c4f5b6c42941c4cf
# ttl:
# domain:
path: /
# clearInvalid: false
isSameSite: Strict
isSecure: true
isHttpOnly: true
keepAlive: false
# redirectTo:

production:
cookie:
# Change to your own secret password. hint: openssl rand -hex 16
# password:

test:
cookie:
isSecure: false
password: ^NicTool.Is,The#Best_Dns-Manager$

development:
cookie:
isSecure: false
password: ^NicTool.Is,The#Best_Dns-Manager$
8 changes: 8 additions & 0 deletions html/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<html>
<head>
Index
</head>
<body>
Hello World.
</body>
</html>
48 changes: 48 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const fs = require('fs/promises')

const YAML = require('yaml')

class config {
constructor(opts = {}) {
this.cfg = {}
this.debug = process.env.NODE_DEBUG ? true : false
this.env = process.env.NODE_ENV ?? opts.env
if (this.debug) console.log(`debug: true, env: ${this.env}`)
}

async get(name, env) {
const cacheKey = [name, env ?? this.env].join(':')
if (this.cfg?.[cacheKey]) return this.cfg[cacheKey] // cached

const str = await fs.readFile(`./conf.d/${name}.yml`, 'utf8')
const cfg = YAML.parse(str)
// if (this.debug) console.log(cfg)

this.cfg[cacheKey] = applyDefaults(cfg[env ?? this.env], cfg.default)
return this.cfg[cacheKey]
}

getSync(name, env) {
const cacheKey = [name, env ?? this.env].join(':')
if (this.cfg?.[cacheKey]) return this.cfg[cacheKey] // cached

const str = require('fs').readFileSync(`./conf.d/${name}.yml`, 'utf8')
const cfg = YAML.parse(str)

this.cfg[cacheKey] = applyDefaults(cfg[env ?? this.env], cfg.default)
return this.cfg[cacheKey]
}
}

function applyDefaults(cfg = {}, defaults = {}) {
for (const d in defaults) {
if (cfg[d] === undefined) {
cfg[d] = defaults[d]
} else if (typeof cfg[d] === 'object' && typeof defaults[d] === 'object') {
cfg[d] = applyDefaults(cfg[d], defaults[d])
}
}
return cfg
}

module.exports = new config()
39 changes: 39 additions & 0 deletions lib/group.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const mysql = require('./mysql')

const validate = require('@nictool/nt-validate')

class Group {
constructor() {}

async create(args) {
// console.log(`create`)
const { error } = validate.group.validate(args)
if (error) console.error(error)

const g = await this.read({ nt_group_id: args.nt_group_id })
if (g.length) {
// console.log(g)
return g[0].nt_group_id
}

const groupId = await mysql.insert(`INSERT INTO nt_group`, args)
return groupId
}

async read(args) {
return await mysql.select(`SELECT * FROM nt_group WHERE`, args)
}

async destroy(args) {
const g = await this.read({ nt_group_id: args.nt_group_id })
// console.log(g)
if (g.length === 1) {
await mysql.execute(`DELETE FROM nt_group WHERE nt_group_id=?`, [
g[0].nt_group_id,
])
}
}
}

module.exports = new Group()
module.exports._mysql = mysql
Loading

0 comments on commit 7555113

Please sign in to comment.