Skip to content

Commit cdce060

Browse files
committed
impl
1 parent 0d466b5 commit cdce060

File tree

7 files changed

+325
-0
lines changed

7 files changed

+325
-0
lines changed

deno.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"tasks": {
3+
"check": "deno check scripts",
4+
"verify": "deno fmt --check && deno lint",
5+
"build": "deno run -A scripts/build.ts"
6+
},
7+
"nodeModulesDir": "auto",
8+
"imports": {
9+
"@leawind/inventory": "jsr:@leawind/inventory@^0.19.4",
10+
"@std/assert": "jsr:@std/assert@^1",
11+
"commander": "npm:commander@^14.0.3",
12+
"ts-json-schema-generator": "npm:ts-json-schema-generator@^2.9.0"
13+
},
14+
"lint": {
15+
"include": [
16+
"scripts/",
17+
"src"
18+
],
19+
"rules": {
20+
"exclude": [
21+
"ban-types",
22+
"no-explicit-any",
23+
"no-import-prefix",
24+
"require-await"
25+
]
26+
}
27+
},
28+
"fmt": {
29+
"bracePosition": "sameLine",
30+
"lineWidth": 80,
31+
"newLineKind": "lf",
32+
"nextControlFlowPosition": "sameLine",
33+
"operatorPosition": "nextLine",
34+
"proseWrap": "preserve",
35+
"quoteProps": "asNeeded",
36+
"semiColons": false,
37+
"singleBodyPosition": "sameLine",
38+
"useBraces": "always",
39+
"useTabs": true,
40+
"singleQuote": true,
41+
"spaceAround": false,
42+
"spaceSurroundingProperties": true,
43+
"trailingCommas": "onlyMultiLine",
44+
"typeLiteral.separatorKind": "semiColon",
45+
"include": [
46+
"**/*.md",
47+
"**/*.json",
48+
".github/",
49+
"scripts/",
50+
"src"
51+
],
52+
"exclude": []
53+
}
54+
}

deno.lock

Lines changed: 136 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/build.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as fs from '@leawind/inventory/fs'
2+
import { Path } from '@leawind/inventory/fs'
3+
import { INPUT, OUTPUT, OUTPUT_KEEP } from './env.ts'
4+
import { Schema } from 'ts-json-schema-generator'
5+
import { SchemaUtils } from './lib/schemas.ts'
6+
7+
// Clean output directory
8+
if (await fs.exists(OUTPUT)) {
9+
const toRemove = OUTPUT.listSync()
10+
.filter((item) => {
11+
const rel = item.relative(OUTPUT).str
12+
for (const keep of OUTPUT_KEEP) {
13+
if (keep instanceof RegExp) {
14+
if (keep.test(rel)) {
15+
return false
16+
}
17+
} else if (keep === rel) {
18+
return false
19+
}
20+
}
21+
return true
22+
})
23+
toRemove.forEach((item) => item.removeSync({ recursive: true }))
24+
}
25+
26+
// Copy static files
27+
{
28+
fs.copySync(INPUT.join('copied'), OUTPUT)
29+
}
30+
31+
// Build schemas
32+
{
33+
const inputDir = INPUT.join('schemas')
34+
const outputDir = OUTPUT.join('schema')
35+
36+
const schemas: Record<string, Schema> = {}
37+
38+
// Parse schemas
39+
for await (const file of fs.walkFile(inputDir.str, /.*\.ts$/)) {
40+
const src = fs.Path.from(file)
41+
42+
const relative = src.relative(inputDir).noExt
43+
schemas[relative] = SchemaUtils.parse(src, inputDir)
44+
}
45+
46+
// Write schemas
47+
for (const [relative, schema] of Object.entries(schemas)) {
48+
const dst = outputDir.join(relative + '.json')
49+
Path.from(dst).write(JSON.stringify(schema, null, 2))
50+
}
51+
52+
// Write index
53+
{
54+
const indexFile = outputDir.join('index.html')
55+
const html = `<!DOCTYPE html>
56+
<html lang="en">
57+
<head>
58+
<meta charset="UTF-8">
59+
<title>Schemas</title>
60+
</head>
61+
<body>
62+
<h1>Schemas</h1>
63+
<ul>
64+
${
65+
Object.keys(schemas).map((rel) => {
66+
rel += '.json'
67+
return `<li><a href="${rel}">${rel}</a></li>`
68+
}).join('\n')
69+
}
70+
</ul>
71+
</body>
72+
</html>
73+
`
74+
indexFile.write(html)
75+
}
76+
}

scripts/env.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import * as fs from '@leawind/inventory/fs'
2+
3+
export const INPUT = fs.P`src`
4+
export const OUTPUT = fs.P`dist`
5+
export const OUTPUT_KEEP: (string | RegExp)[] = [/docs.*/]
6+
7+
export const DOMAIN = `git-parcel.github.io`

scripts/lib/schemas.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import tsj, { Schema } from 'ts-json-schema-generator'
2+
import { Path } from '@leawind/inventory/fs'
3+
import { DOMAIN, OUTPUT } from '../env.ts'
4+
5+
export class SchemaUtils {
6+
/**
7+
* @param src .ts 文件路径。必须导出一个 default interface Type,Type 是要生成的 schema 类型。
8+
*/
9+
public static parse(src: Path, base: Path): Schema {
10+
const typeName = src.relative(base).noExt
11+
const schemaId = `https://${DOMAIN}/schema/${typeName}.json`
12+
13+
const config: tsj.Config = {
14+
path: src.str,
15+
type: 'Type',
16+
schemaId,
17+
discriminatorType: 'open-api',
18+
encodeRefs: false,
19+
expose: 'export',
20+
functions: 'comment',
21+
jsDoc: 'extended',
22+
markdownDescription: true,
23+
skipTypeCheck: true,
24+
sortProps: true,
25+
topRef: true,
26+
additionalProperties: true,
27+
}
28+
29+
const generator = tsj.createGenerator(config)
30+
return generator.createSchema(config.type)
31+
}
32+
}

src/copied/index.html

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en-US">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="refresh" content="0; url=/docs/" />
6+
<title>Redirecting</title>
7+
<script>
8+
location.href = '/docs/'
9+
</script>
10+
</head>
11+
12+
<body>
13+
<p><a href="/docs/">Redirecting, click here if it doesn't work</a></p>
14+
</body>
15+
</html>

src/schemas/debug/DebugType.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default interface Type {
2+
note: 'This type is only used for debug.'
3+
field: string
4+
list: { key: string }[]
5+
}

0 commit comments

Comments
 (0)