-
Notifications
You must be signed in to change notification settings - Fork 26
/
file-schema-manager.ts
79 lines (69 loc) · 2.35 KB
/
file-schema-manager.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
import path from 'node:path';
import type ts from 'typescript';
import { buildSchema, buildClientSchema } from 'graphql';
import { SchemaManager } from './schema-manager';
import type { SchemaManagerHost } from './types';
function extractIntrospectionContentFromJson(jsonObject: any) {
if (jsonObject.data) {
return jsonObject.data;
} else {
return jsonObject;
}
}
export interface FileSchemaManagerOptions {
path: string;
}
export class FileSchemaManager extends SchemaManager {
private _schemaPath: string;
private _watcher?: ts.FileWatcher;
constructor(
protected _host: SchemaManagerHost,
options: FileSchemaManagerOptions,
) {
super(_host);
this._schemaPath = options.path;
}
getBaseSchema() {
if (!this._schemaPath || typeof this._schemaPath !== 'string') return null;
try {
const resolvedSchmaPath = this.getAbsoluteSchemaPath(this._host.getProjectRootPath(), this._schemaPath);
this.log('Read schema from ' + resolvedSchmaPath);
const isExists = this._host.fileExists(resolvedSchmaPath);
if (!isExists) return null;
if (this._schemaPath.endsWith('.graphql') || this._schemaPath.endsWith('.gql')) {
const sdl = this._host.readFile(resolvedSchmaPath, 'utf-8');
return sdl ? buildSchema(sdl) : null;
} else {
const introspectionContents = this._host.readFile(resolvedSchmaPath, 'utf-8');
return introspectionContents
? buildClientSchema(extractIntrospectionContentFromJson(JSON.parse(introspectionContents)))
: null;
}
} catch (err) {
this.log('Fail to read schema file...');
this.log(err instanceof Error ? err.message : `Unknown error: ${err}`);
return null;
}
}
async waitBaseSchema() {
return this.getBaseSchema();
}
getAbsoluteSchemaPath(projectRootPath: string, schemaPath: string) {
if (path.isAbsolute(schemaPath)) return schemaPath;
return path.resolve(projectRootPath, schemaPath);
}
startWatch(interval: number = 100) {
const resolvedSchmaPath = this.getAbsoluteSchemaPath(this._host.getProjectRootPath(), this._schemaPath);
this._watcher = this._host.watchFile(
resolvedSchmaPath,
() => {
this.log('Change schema file.');
this.emitChange();
},
interval,
);
}
closeWatch() {
if (this._watcher) this._watcher.close();
}
}