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 637
/
ddoc.ts
106 lines (94 loc) · 3.48 KB
/
ddoc.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/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'
import chalk from 'chalk'
const stat = promisify(fs.stat)
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const unlink = promisify(fs.unlink)
const glob = promisify(originalGlob)
async function deleteOldDdocs(dest: string) {
const oldDdocs = await glob(path.join(dest, '**/*.json'))
return Promise.all(oldDdocs.map(file => unlink(file)))
}
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)
await deleteOldDdocs(dest)
console.log(`> destination directory is ${dest}`)
const errors: { file: string; error: Error }[] = []
await Promise.all(
ddocs.map(async srcPath => {
try {
const sourceFile = (await readFile(srcPath)).toString()
const output = ts.transpileModule(sourceFile, tsconfig)
const filename = path.basename(srcPath, '.ts')
await writeFile(path.join(src, `${filename}.js`), output.outputText)
const ddoc = requireFromString(output.outputText)
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 (error) {
errors.push({ file: srcPath, error })
}
}),
)
if (errors.length > 0) {
errors.forEach(err => {
console.log(
`\n${chalk.red('ddoc error')} - ${chalk.cyan(
err.file,
)}${err.error.stack?.toString()}\n`,
)
})
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)