forked from sourcegraph/sourcegraph-public-snapshot
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgulpfile.ts
More file actions
90 lines (83 loc) · 3.96 KB
/
gulpfile.ts
File metadata and controls
90 lines (83 loc) · 3.96 KB
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
import { generateNamespace } from '@gql2ts/from-schema'
import { DEFAULT_OPTIONS, DEFAULT_TYPE_MAP } from '@gql2ts/language-typescript'
import { buildSchema, graphql, introspectionQuery, IntrospectionQuery } from 'graphql'
import gulp from 'gulp'
import $RefParser from 'json-schema-ref-parser'
import { compile as compileJSONSchema } from 'json-schema-to-typescript'
import mkdirp from 'mkdirp-promise'
import { readFile, writeFile } from 'mz/fs'
import path from 'path'
import { format, resolveConfig } from 'prettier'
import { draftV7resolver } from './draftV7Resolver'
const GRAPHQL_SCHEMA_PATH = path.join(__dirname, '../cmd/frontend/graphqlbackend/schema.graphql')
export async function watchGraphQLTypes(): Promise<void> {
await new Promise<never>((resolve, reject) => {
gulp.watch(GRAPHQL_SCHEMA_PATH, graphQLTypes).on('error', reject)
})
}
/** Generates the TypeScript types for the GraphQL schema */
export async function graphQLTypes(): Promise<void> {
const schemaStr = await readFile(GRAPHQL_SCHEMA_PATH, 'utf8')
const schema = buildSchema(schemaStr)
const result = (await graphql(schema, introspectionQuery)) as { data: IntrospectionQuery }
const formatOptions = (await resolveConfig(__dirname, { config: __dirname + '/../prettier.config.js' }))!
const typings =
'export type ID = string\n\n' +
generateNamespace(
'',
result,
{
typeMap: {
...DEFAULT_TYPE_MAP,
ID: 'ID',
},
},
{
generateNamespace: (name: string, interfaces: string) => interfaces,
interfaceBuilder: (name: string, body: string) =>
'export ' + DEFAULT_OPTIONS.interfaceBuilder(name, body),
enumTypeBuilder: (name: string, values: string) =>
'export ' + DEFAULT_OPTIONS.enumTypeBuilder(name, values).replace(/^const enum/, 'enum'),
typeBuilder: (name: string, body: string) => 'export ' + DEFAULT_OPTIONS.typeBuilder(name, body),
wrapList: (type: string) => `${type}[]`,
postProcessor: (code: string) => format(code, { ...formatOptions, parser: 'typescript' }),
}
)
await writeFile(__dirname + '/src/graphql/schema.ts', typings)
}
/**
* Generates the TypeScript types for the JSON schemas.
*/
export async function schema(): Promise<void> {
const outputDir = path.join(__dirname, '..', 'web', 'src', 'schema')
await mkdirp(outputDir)
const schemaDir = path.join(__dirname, '..', 'schema')
await Promise.all(
['json-schema-draft-07', 'settings', 'critical', 'site'].map(async file => {
let schema = await readFile(path.join(schemaDir, `${file}.schema.json`), 'utf8')
// HACK: Rewrite absolute $refs to be relative. They need to be absolute for Monaco to resolve them
// when the schema is in a oneOf (to be merged with extension schemas).
schema = schema.replace(
/https:\/\/sourcegraph\.com\/v1\/settings\.schema\.json#\/definitions\//g,
'#/definitions/'
)
const types = await compileJSONSchema(JSON.parse(schema), 'settings.schema', {
cwd: schemaDir,
$refOptions: {
resolve: {
draftV7resolver,
// there should be no reason to make network calls during this process,
// and if there are we've broken env for offline devs/increased dev startup time
http: false,
} as $RefParser.Options['resolve'],
},
})
await writeFile(path.join(outputDir, `${file}.schema.d.ts`), types)
})
)
}
export async function watchSchema(): Promise<void> {
await new Promise<never>((_resolve, reject) => {
gulp.watch(__dirname + '/../schema/*.schema.json', schema).on('error', reject)
})
}