This repository has been archived by the owner on Jan 20, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompile.ts
executable file
·137 lines (119 loc) · 4 KB
/
compile.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { promises as fs } from 'fs'
import { relative, resolve, join, basename, dirname } from 'path'
import mkdirp = require('mkdirp')
import { compileFromFile } from 'json-schema-to-typescript'
import { dereference } from '@apidevtools/json-schema-ref-parser'
import Ajv from 'ajv'
import pack from 'ajv-pack'
import { loadSchema } from '@oada/formats/lib/ajv'
import formats, { schemas } from '@oada/formats'
// Where to put compiled types
const typesDir = resolve('./')
const compileStr = '`$ yarn build`'
// Create ajv for packing validation functions
// @ts-ignore
const ajv = new Ajv({ loadSchema, sourceCode: true })
// Compile the schema files to TypeScript types
async function doCompile () {
const metaSchema = await dereference(
'https://json-schema.org/draft/2019-09/schema'
)
ajv.addMetaSchema(metaSchema)
// Compile schemas to TS types
for (const { key, path, schema } of schemas()) {
const { $id } = schema
const file = key
.replace(/^https:\/\/formats\.openag\.io/, '')
.replace(/^\//, './')
const outfile = join(typesDir, file.replace(/\.schema\.json$/, '.ts'))
const name = basename(path, '.schema.json')
const cwd = dirname(path)
const typeName = `${name[0].toUpperCase()}${name.substr(1)}`
// Pack up validation function
const validate = await ajv.compileAsync(schema)
const packed = pack(ajv, validate)
const packedfile = join(
typesDir,
file.replace(/\.schema\.json$/, '-validate.js')
)
// Make the banner comment a bit more informative
// TODO: Figure out some TS magic to use instead of this code generation??
const bannerComment = `
/// <reference path="./${relative(
dirname(file),
typesDir
)}/types.d.ts" />
/* tslint:disable */
/**
* File was automatically generated using json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND.
* Instead, modify the source file ${key} of @oada/formats
* and run ${compileStr} to regenerate this file.
*/
// Import packed validation function
import validate from './${name}-validate.js'
/**
* $id of the source schema
* @see {@link ${$id}}
*/
export const $id = '${$id}'
/**
* Returns true if val is a @type ${typeName}, false otherwise
*/
export function is (val: any): val is ${typeName} {
return validate(val) as boolean
}
/**
* Asserts that val is a @type ${typeName}
*/
export function assert (val: any): asserts val is ${typeName} {
if (!validate(val) as boolean) {
throw {
errors: validate.errors,
input: val
}
}
}
// Augment module interface?
//declare module '@oada/formats' {
// /**
// * @todo Figure out how do type overrides for getSchema
// */
// interface OADAFormats {
// validate(ref: '${$id}' | '${key}', data: any): data is ${typeName}
// }
//}
export default ${typeName}
`
console.debug(`Compiling ${key} to TypeScript types`)
try {
const r = /^https:\/\/formats\.openag\.io/
const ts = await compileFromFile(path, {
bannerComment,
unreachableDefinitions: true,
$refOptions: {
// Use local versions of openag schemas
resolve: {
// @ts-ignore
oada: {
order: 0,
canRead: r,
async read ({ url }: { url: string }) {
const path = url.replace(r, '')
// @ts-ignore
return JSON.stringify(formats.getSchema(path)?.schema)
}
}
}
},
cwd
})
await mkdirp(dirname(outfile))
await fs.writeFile(packedfile, packed)
await fs.writeFile(outfile, ts)
} catch (err) {
console.error(`Error compiling ${key}: %O`, err)
}
}
}
doCompile()