parent
4af65abe8e
commit
94dee357d8
26 changed files with 4215 additions and 428 deletions
@ -0,0 +1,5 @@ |
||||
# dependencies |
||||
node_modules |
||||
|
||||
# output |
||||
out |
@ -0,0 +1,14 @@ |
||||
{ |
||||
"env": { |
||||
"es2022": true, |
||||
"node": true |
||||
}, |
||||
"extends": [ |
||||
"eslint:recommended", |
||||
"plugin:import/errors", |
||||
"plugin:import/typescript", |
||||
"plugin:import/warnings", |
||||
"prettier" |
||||
], |
||||
"plugins": ["import"] |
||||
} |
@ -0,0 +1,5 @@ |
||||
# dependencies |
||||
node_modules |
||||
|
||||
# output |
||||
out |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,8 @@ |
||||
{ |
||||
"extends": ["../.eslintrc.json", "plugin:@typescript-eslint/recommended"], |
||||
"parser": "@typescript-eslint/parser", |
||||
"parserOptions": { |
||||
"project": "./tsconfig.json" |
||||
}, |
||||
"plugins": ["@typescript-eslint"] |
||||
} |
@ -1,18 +0,0 @@ |
||||
const cors = require('cors'); |
||||
const express = require('express'); |
||||
const path = require('path'); |
||||
|
||||
const API_ROOT_PATH = require('./lib/consts/API_ROOT_PATH'); |
||||
|
||||
const echoRouter = require('./routes/echo'); |
||||
const filesRouter = require('./routes/files'); |
||||
|
||||
const app = express(); |
||||
|
||||
app.use(express.json()); |
||||
app.use(cors()); |
||||
|
||||
app.use(path.join(API_ROOT_PATH, 'echo'), echoRouter); |
||||
app.use(path.join(API_ROOT_PATH, 'files'), filesRouter); |
||||
|
||||
module.exports = app; |
@ -0,0 +1,18 @@ |
||||
import cors from 'cors'; |
||||
import express from 'express'; |
||||
import path from 'path'; |
||||
|
||||
import API_ROOT_PATH from './lib/consts/API_ROOT_PATH'; |
||||
|
||||
import echoRouter from './routes/echo'; |
||||
import filesRouter from './routes/files'; |
||||
|
||||
const app = express(); |
||||
|
||||
app.use(express.json()); |
||||
app.use(cors()); |
||||
|
||||
app.use(path.join(API_ROOT_PATH, 'echo'), echoRouter); |
||||
app.use(path.join(API_ROOT_PATH, 'files'), filesRouter); |
||||
|
||||
export default app; |
@ -1,6 +1,6 @@ |
||||
const app = require('./app'); |
||||
import app from './app'; |
||||
|
||||
const SERVER_PORT = require('./lib/consts/SERVER_PORT'); |
||||
import SERVER_PORT from './lib/consts/SERVER_PORT'; |
||||
|
||||
app.listen(SERVER_PORT, () => { |
||||
console.log(`Listening on localhost:${SERVER_PORT}.`); |
@ -1,94 +0,0 @@ |
||||
const { spawnSync } = require('child_process'); |
||||
|
||||
const SERVER_PATHS = require('./consts/SERVER_PATHS'); |
||||
|
||||
const execStrikerAccessDatabase = ( |
||||
args, |
||||
options = { |
||||
timeout: 10000, |
||||
encoding: 'utf-8', |
||||
}, |
||||
) => { |
||||
const { error, stdout, stderr } = spawnSync( |
||||
SERVER_PATHS.usr.sbin['striker-access-database'].self, |
||||
args, |
||||
options, |
||||
); |
||||
|
||||
if (error) { |
||||
throw error; |
||||
} |
||||
|
||||
if (stderr) { |
||||
throw new Error(stderr); |
||||
} |
||||
|
||||
let output; |
||||
|
||||
try { |
||||
output = JSON.parse(stdout); |
||||
} catch (stdoutParseError) { |
||||
output = stdout; |
||||
|
||||
console.warn( |
||||
`Failed to parse striker-access-database output [${output}]; error: [${stdoutParseError}]`, |
||||
); |
||||
} |
||||
|
||||
return { |
||||
stdout: output, |
||||
}; |
||||
}; |
||||
|
||||
const execDatabaseModuleSubroutine = (subName, subParams, options) => { |
||||
const args = ['--sub', subName]; |
||||
|
||||
if (subParams) { |
||||
args.push('--sub-params', JSON.stringify(subParams)); |
||||
} |
||||
|
||||
const { stdout } = execStrikerAccessDatabase(args, options); |
||||
|
||||
return { |
||||
stdout: stdout['sub_results'], |
||||
}; |
||||
}; |
||||
|
||||
const accessDB = { |
||||
dbJobAnvilSyncShared: ( |
||||
jobName, |
||||
jobData, |
||||
jobTitle, |
||||
jobDescription, |
||||
{ jobHostUUID } = { jobHostUUID: undefined }, |
||||
) => { |
||||
const subParams = { |
||||
file: __filename, |
||||
line: 0, |
||||
job_command: SERVER_PATHS.usr.sbin['anvil-sync-shared'].self, |
||||
job_data: jobData, |
||||
job_name: `storage::${jobName}`, |
||||
job_title: `job_${jobTitle}`, |
||||
job_description: `job_${jobDescription}`, |
||||
job_progress: 0, |
||||
}; |
||||
|
||||
if (jobHostUUID) { |
||||
subParams.job_host_uuid = jobHostUUID; |
||||
} |
||||
|
||||
console.log(JSON.stringify(subParams, null, 2)); |
||||
|
||||
return execDatabaseModuleSubroutine('insert_or_update_jobs', subParams) |
||||
.stdout; |
||||
}, |
||||
dbQuery: (query, options) => |
||||
execStrikerAccessDatabase(['--query', query], options), |
||||
dbSub: execDatabaseModuleSubroutine, |
||||
dbSubRefreshTimestamp: () => |
||||
execDatabaseModuleSubroutine('refresh_timestamp').stdout, |
||||
dbWrite: (query, options) => |
||||
execStrikerAccessDatabase(['--query', query, '--mode', 'write'], options), |
||||
}; |
||||
|
||||
module.exports = accessDB; |
@ -0,0 +1,114 @@ |
||||
import { spawnSync, SpawnSyncOptions } from 'child_process'; |
||||
|
||||
import SERVER_PATHS from './consts/SERVER_PATHS'; |
||||
|
||||
const execStrikerAccessDatabase = ( |
||||
args: string[], |
||||
options: SpawnSyncOptions = { |
||||
timeout: 10000, |
||||
encoding: 'utf-8', |
||||
}, |
||||
) => { |
||||
const { error, stdout, stderr } = spawnSync( |
||||
SERVER_PATHS.usr.sbin['striker-access-database'].self, |
||||
args, |
||||
options, |
||||
); |
||||
|
||||
if (error) { |
||||
throw error; |
||||
} |
||||
|
||||
if (stderr) { |
||||
throw new Error(stderr.toString()); |
||||
} |
||||
|
||||
let output; |
||||
|
||||
try { |
||||
output = JSON.parse(stdout.toString()); |
||||
} catch (stdoutParseError) { |
||||
output = stdout; |
||||
|
||||
console.warn( |
||||
`Failed to parse striker-access-database output [${output}]; error: [${stdoutParseError}]`, |
||||
); |
||||
} |
||||
|
||||
return { |
||||
stdout: output, |
||||
}; |
||||
}; |
||||
|
||||
const execDatabaseModuleSubroutine = ( |
||||
subName: string, |
||||
subParams?: Record<string, unknown>, |
||||
options?: SpawnSyncOptions, |
||||
) => { |
||||
const args = ['--sub', subName]; |
||||
|
||||
if (subParams) { |
||||
args.push('--sub-params', JSON.stringify(subParams)); |
||||
} |
||||
|
||||
const { stdout } = execStrikerAccessDatabase(args, options); |
||||
|
||||
return { |
||||
stdout: stdout['sub_results'], |
||||
}; |
||||
}; |
||||
|
||||
const dbJobAnvilSyncShared = ( |
||||
jobName: string, |
||||
jobData: string, |
||||
jobTitle: string, |
||||
jobDescription: string, |
||||
{ jobHostUUID }: DBJobAnvilSyncSharedOptions = { jobHostUUID: undefined }, |
||||
) => { |
||||
const subParams: { |
||||
file: string; |
||||
line: number; |
||||
job_command: string; |
||||
job_data: string; |
||||
job_name: string; |
||||
job_title: string; |
||||
job_description: string; |
||||
job_host_uuid?: string; |
||||
job_progress: number; |
||||
} = { |
||||
file: __filename, |
||||
line: 0, |
||||
job_command: SERVER_PATHS.usr.sbin['anvil-sync-shared'].self, |
||||
job_data: jobData, |
||||
job_name: `storage::${jobName}`, |
||||
job_title: `job_${jobTitle}`, |
||||
job_description: `job_${jobDescription}`, |
||||
job_progress: 0, |
||||
}; |
||||
|
||||
if (jobHostUUID) { |
||||
subParams.job_host_uuid = jobHostUUID; |
||||
} |
||||
|
||||
console.log(JSON.stringify(subParams, null, 2)); |
||||
|
||||
return execDatabaseModuleSubroutine('insert_or_update_jobs', subParams) |
||||
.stdout; |
||||
}; |
||||
|
||||
const dbQuery = (query: string, options?: SpawnSyncOptions) => |
||||
execStrikerAccessDatabase(['--query', query], options); |
||||
|
||||
const dbSubRefreshTimestamp = () => |
||||
execDatabaseModuleSubroutine('refresh_timestamp').stdout; |
||||
|
||||
const dbWrite = (query: string, options?: SpawnSyncOptions) => |
||||
execStrikerAccessDatabase(['--query', query, '--mode', 'write'], options); |
||||
|
||||
export { |
||||
dbJobAnvilSyncShared, |
||||
dbQuery, |
||||
execDatabaseModuleSubroutine as dbSub, |
||||
dbSubRefreshTimestamp, |
||||
dbWrite, |
||||
}; |
@ -1,3 +0,0 @@ |
||||
const API_ROOT_PATH = '/api'; |
||||
|
||||
module.exports = API_ROOT_PATH; |
@ -0,0 +1,3 @@ |
||||
const API_ROOT_PATH = '/api'; |
||||
|
||||
export default API_ROOT_PATH; |
@ -1,3 +1,3 @@ |
||||
const SERVER_PORT = process.env.SERVER_PORT ?? 8080; |
||||
|
||||
module.exports = SERVER_PORT; |
||||
export default SERVER_PORT; |
@ -1,29 +0,0 @@ |
||||
const { dbQuery } = require('../../accessDB'); |
||||
|
||||
const buildGetFiles = (query) => (request, response) => { |
||||
console.log('Calling CLI script to get data.'); |
||||
|
||||
let queryStdout; |
||||
|
||||
try { |
||||
({ stdout: queryStdout } = dbQuery( |
||||
typeof query === 'function' ? query(request) : query, |
||||
)); |
||||
} catch (queryError) { |
||||
console.log(`Query error: ${queryError}`); |
||||
|
||||
response.status(500).send(); |
||||
} |
||||
|
||||
console.log( |
||||
`Query stdout (type=[${typeof queryStdout}]): ${JSON.stringify( |
||||
queryStdout, |
||||
null, |
||||
2, |
||||
)}`,
|
||||
); |
||||
|
||||
response.json(queryStdout); |
||||
}; |
||||
|
||||
module.exports = buildGetFiles; |
@ -0,0 +1,33 @@ |
||||
import { Request, Response } from 'express'; |
||||
|
||||
import { dbQuery } from '../../accessDB'; |
||||
|
||||
const buildGetFiles = |
||||
(query: string | ((request: Request) => string)) => |
||||
(request: Request, response: Response) => { |
||||
console.log('Calling CLI script to get data.'); |
||||
|
||||
let queryStdout; |
||||
|
||||
try { |
||||
({ stdout: queryStdout } = dbQuery( |
||||
typeof query === 'function' ? query(request) : query, |
||||
)); |
||||
} catch (queryError) { |
||||
console.log(`Query error: ${queryError}`); |
||||
|
||||
response.status(500).send(); |
||||
} |
||||
|
||||
console.log( |
||||
`Query stdout (type=[${typeof queryStdout}]): ${JSON.stringify( |
||||
queryStdout, |
||||
null, |
||||
2, |
||||
)}`,
|
||||
); |
||||
|
||||
response.json(queryStdout); |
||||
}; |
||||
|
||||
export default buildGetFiles; |
@ -0,0 +1,3 @@ |
||||
type DBJobAnvilSyncSharedOptions = { |
||||
jobHostUUID?: string; |
||||
}; |
@ -0,0 +1,13 @@ |
||||
type ServerPathSelf = { |
||||
self?: string; |
||||
}; |
||||
|
||||
type ServerPath = { |
||||
[segment: string]: ServerPath; |
||||
} & ServerPathSelf; |
||||
|
||||
type FilledServerPath = { |
||||
[segment: string]: FilledServerPath; |
||||
} & Required<ServerPathSelf>; |
||||
|
||||
type ReadonlyServerPath = Readonly<FilledServerPath>; |
@ -0,0 +1,21 @@ |
||||
{ |
||||
"compilerOptions": { |
||||
"allowJs": true, |
||||
"esModuleInterop": true, |
||||
"forceConsistentCasingInFileNames": true, |
||||
"incremental": true, |
||||
"isolatedModules": true, |
||||
"lib": ["esnext"], |
||||
"module": "esnext", |
||||
"moduleResolution": "node", |
||||
"noImplicitAny": true, |
||||
"outDir": "ts_out", |
||||
"resolveJsonModule": true, |
||||
"strict": true, |
||||
"target": "es5", |
||||
"types": ["node"], |
||||
"typeRoots": ["src/types"] |
||||
}, |
||||
"exclude": ["node_modules"], |
||||
"include": ["src/**/*.ts"] |
||||
} |
Loading…
Reference in new issue