This repository has been archived by the owner on Jan 9, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 650
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement cli for generate couchdb's design documents
- Loading branch information
Showing
7 changed files
with
203 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
module.exports = { | ||
ignorePatterns: ['bin'], | ||
extends: [ | ||
'plugin:@typescript-eslint/recommended', | ||
'prettier', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#!/usr/bin/env node | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const path_1 = __importDefault(require("path")); | ||
const fs_1 = __importDefault(require("fs")); | ||
const util_1 = require("util"); | ||
const sade_1 = __importDefault(require("sade")); | ||
const typescript_1 = __importDefault(require("typescript")); | ||
const require_from_string_1 = __importDefault(require("require-from-string")); | ||
const glob_1 = __importDefault(require("glob")); | ||
const mkdirp_1 = __importDefault(require("mkdirp")); | ||
const stat = util_1.promisify(fs_1.default.stat); | ||
const readFile = util_1.promisify(fs_1.default.readFile); | ||
const writeFile = util_1.promisify(fs_1.default.writeFile); | ||
const glob = util_1.promisify(glob_1.default); | ||
const prog = sade_1.default('ddoc'); | ||
prog.version('0.1.0'); | ||
prog | ||
.command('build <src>', 'Build design document(s) from TypeScript soruce directory or file.', { | ||
default: true, | ||
}) | ||
.option('-c, --config', 'Provide path to custom tsconfig.json', './tsconfig.json') | ||
.example('build src/db/designs') | ||
.example('build src/db/designs/patient.ts -c src/db/tsconfig.json') | ||
.action(async (src, opts) => { | ||
var _a; | ||
try { | ||
const cwd = process.cwd(); | ||
const tsconfigPath = path_1.default.isAbsolute(opts.config) ? opts.config : path_1.default.join(cwd, opts.config); | ||
console.log(`> using ${tsconfigPath} config`); | ||
const tsconfig = require(tsconfigPath); | ||
src = path_1.default.isAbsolute(src) ? path_1.default.normalize(src) : path_1.default.join(cwd, src); | ||
const srcStats = await stat(src); | ||
let dest = ((_a = tsconfig === null || tsconfig === void 0 ? void 0 : tsconfig.compilerOptions) === null || _a === void 0 ? void 0 : _a.outDir) ? path_1.default.join(path_1.default.dirname(tsconfigPath), tsconfig.compilerOptions.outDir) | ||
: ''; | ||
let ddocs; | ||
if (srcStats.isDirectory()) { | ||
dest = dest || src; | ||
ddocs = await glob(path_1.default.join(src, '**/*.ts')); | ||
} | ||
else { | ||
dest = dest || path_1.default.dirname(src); | ||
ddocs = [src]; | ||
} | ||
console.log(`> src directory is ${src}`); | ||
await mkdirp_1.default(dest); | ||
console.log(`> destination directory is ${dest}`); | ||
const errors = []; | ||
await Promise.all(ddocs.map(async (srcPath) => { | ||
try { | ||
const sourceFile = (await readFile(srcPath)).toString(); | ||
const output = typescript_1.default.transpileModule(sourceFile, tsconfig); | ||
const ddoc = require_from_string_1.default(output.outputText); | ||
const filename = path_1.default.basename(srcPath, '.ts'); | ||
const stringifiedDesign = JSON.stringify(ddoc, (_, val) => { | ||
if (typeof val === 'function') { | ||
return val.toString(); | ||
} | ||
return val; | ||
}, 1); | ||
await writeFile(path_1.default.join(dest, `${filename}.json`), stringifiedDesign); | ||
} | ||
catch (err) { | ||
errors.push(err); | ||
} | ||
})); | ||
if (errors.length > 0) { | ||
errors.forEach(err => { | ||
console.error(err); | ||
}); | ||
throw new Error(`Compilation failed. Resolve errors in your code and try again.`); | ||
} | ||
} | ||
catch (err) { | ||
console.error(err); | ||
process.exit(1); | ||
} | ||
}); | ||
prog.parse(process.argv); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,11 @@ | |
"url": "https://github.com/HospitalRun/hospitalrun-server.git" | ||
}, | ||
"scripts": { | ||
"ddoc": "npm run build:bin && node bin/ddoc", | ||
"commit": "npx git-cz", | ||
"build": "npm run clean && tsc -p ./tsconfig.json && npm run build:designs", | ||
"build:designs": "tsc -p ./src/db/tsconfig.json", | ||
"build:bin": "rimraf bin && tsc -p ./src/bin/tsconfig.json", | ||
"start": "node dist", | ||
"clean": "rimraf dist", | ||
"dev:db": "pouchdb-server --config ./db/config.json", | ||
|
@@ -30,7 +32,6 @@ | |
"author": "Maksim Sinik <[email protected]>", | ||
"license": "MIT", | ||
"dependencies": { | ||
"cross-env": "~7.0.0", | ||
"fastify": "~2.12.0", | ||
"fastify-autoload": "~1.2.2", | ||
"fastify-blipp": "~2.1.0", | ||
|
@@ -41,14 +42,18 @@ | |
"fastify-plugin": "~1.6.1", | ||
"make-promises-safe": "~5.1.0", | ||
"nano": "~8.2.1", | ||
"qs": "~6.9.1" | ||
"qs": "~6.9.1", | ||
"require-from-string": "~2.0.2" | ||
}, | ||
"devDependencies": { | ||
"@commitlint/cli": "8.3.5", | ||
"@commitlint/config-conventional": "8.3.4", | ||
"@commitlint/prompt": "8.3.5", | ||
"@types/mkdirp": "~1.0.0", | ||
"@types/node": "~13.7.0", | ||
"@types/qs": "~6.9.0", | ||
"@types/require-from-string": "~1.2.0", | ||
"@types/sade": "~1.6.0", | ||
"@typescript-eslint/eslint-plugin": "~2.21.0", | ||
"@typescript-eslint/parser": "~2.21.0", | ||
"commitizen": "~4.0.3", | ||
|
@@ -61,14 +66,17 @@ | |
"eslint-config-prettier": "~6.10.0", | ||
"eslint-plugin-import": "~2.20.0", | ||
"eslint-plugin-prettier": "~3.1.0", | ||
"glob": "~7.1.6", | ||
"husky": "~4.2.0", | ||
"lint-staged": "~10.0.7", | ||
"mkdirp": "~1.0.3", | ||
"nodemon": "~2.0.0", | ||
"npm-run-all": "~4.1.5", | ||
"pino-colada": "~1.5.0", | ||
"pouchdb-server": "~4.2.0", | ||
"prettier": "~1.19.1", | ||
"rimraf": "~3.0.0", | ||
"sade": "~1.7.3", | ||
"source-map-support": "~0.5.16", | ||
"tap": "~14.10.5", | ||
"tap-mocha-reporter": "~5.0.0", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#!/usr/bin/env node | ||
|
||
import path from 'path' | ||
import fs from 'fs' | ||
import { promisify } from 'util' | ||
import sade from 'sade' | ||
import ts from 'typescript' | ||
import requireFromString from 'require-from-string' | ||
import originalGlob from 'glob' | ||
import mkdirp from 'mkdirp' | ||
|
||
const stat = promisify(fs.stat) | ||
const readFile = promisify(fs.readFile) | ||
const writeFile = promisify(fs.writeFile) | ||
const glob = promisify(originalGlob) | ||
|
||
const prog = sade('ddoc') | ||
|
||
prog.version('0.1.0') | ||
|
||
prog | ||
.command('build <src>', 'Build design document(s) from TypeScript soruce directory or file.', { | ||
default: true, | ||
}) | ||
// .describe('Build design documents from TypeScript soruce directory or file.') | ||
.option('-c, --config', 'Provide path to custom tsconfig.json', './tsconfig.json') | ||
.example('build src/db/designs') | ||
.example('build src/db/designs/patient.ts -c src/db/tsconfig.json') | ||
.action(async (src, opts) => { | ||
try { | ||
const cwd = process.cwd() | ||
const tsconfigPath = path.isAbsolute(opts.config) ? opts.config : path.join(cwd, opts.config) | ||
|
||
console.log(`> using ${tsconfigPath} config`) | ||
const tsconfig = require(tsconfigPath) // eslint-disable-line | ||
|
||
src = path.isAbsolute(src) ? path.normalize(src) : path.join(cwd, src) // eslint-disable-line | ||
|
||
const srcStats = await stat(src) | ||
// use outDir if specified inside tsconfig, otherwise build json alongside ts files | ||
let dest: string = tsconfig?.compilerOptions?.outDir | ||
? path.join(path.dirname(tsconfigPath), tsconfig.compilerOptions.outDir) | ||
: '' | ||
let ddocs: string[] | ||
if (srcStats.isDirectory()) { | ||
dest = dest || src | ||
ddocs = await glob(path.join(src, '**/*.ts')) | ||
} else { | ||
dest = dest || path.dirname(src) | ||
ddocs = [src] | ||
} | ||
|
||
console.log(`> src directory is ${src}`) | ||
await mkdirp(dest) | ||
console.log(`> destination directory is ${dest}`) | ||
|
||
const errors: Error[] = [] | ||
await Promise.all( | ||
ddocs.map(async srcPath => { | ||
try { | ||
const sourceFile = (await readFile(srcPath)).toString() | ||
const output = ts.transpileModule(sourceFile, tsconfig) | ||
const ddoc = requireFromString(output.outputText) | ||
const filename = path.basename(srcPath, '.ts') | ||
const stringifiedDesign = JSON.stringify( | ||
ddoc, | ||
(_, val) => { | ||
if (typeof val === 'function') { | ||
return val.toString() | ||
} | ||
return val | ||
}, | ||
1, | ||
) | ||
await writeFile(path.join(dest, `${filename}.json`), stringifiedDesign) | ||
} catch (err) { | ||
errors.push(err) | ||
} | ||
}), | ||
) | ||
if (errors.length > 0) { | ||
errors.forEach(err => { | ||
console.error(err) | ||
}) | ||
throw new Error(`Compilation failed. Resolve errors in your code and try again.`) | ||
} | ||
} catch (err) { | ||
console.error(err) | ||
process.exit(1) | ||
} | ||
}) | ||
|
||
prog.parse(process.argv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// we need this custom tsconfig.json to handle CouchDB Javascript Context locally to this folder | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"include": [ | ||
"." | ||
], | ||
"exclude": [ | ||
"node_modules", | ||
], | ||
"compilerOptions": { | ||
"outDir": "../../bin", | ||
"sourceMap": false | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,16 @@ | ||
// we need this custom tsconfig.json to handle CouchDB Javascript Context locally to this folder | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"include": [ | ||
"." | ||
], | ||
"exclude": [ | ||
"node_modules", | ||
"node_modules" | ||
], | ||
"compilerOptions": { | ||
"typeRoots": [ | ||
"../../node_modules/@types", | ||
"./design-functions-context.d.ts" | ||
], | ||
"outDir": "../../dist/db", | ||
"outDir": "../../db/designs", | ||
"sourceMap": false | ||
} | ||
} |