/
cached-literal-parser.ts
94 lines (82 loc) · 2.61 KB
/
cached-literal-parser.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
import ts from 'typescript/lib/tsserverlibrary';
import { ErrorCatcher } from '../create-error-catcher';
import { generateTypeFromLiteral } from '../generators/generate-type-from-literal';
import { DocumentInfos } from '../generators/generate-bottom-content';
import { createCacheSystem } from '../utils/cache-system';
import {
CachedSchemaLoader,
defaultProjectName,
getProjectNameIfNotDefault,
} from './cached-schema-loader';
type CreateCachedLiteralParserOptions = {
cachedSchemaLoader: CachedSchemaLoader;
projectNameRegex: string | undefined;
errorCatcher: ErrorCatcher;
};
export type CachedLiteralParserValue<D extends DocumentInfos = DocumentInfos> =
{
documentInfos: D;
staticGlobals: string[];
} | null;
type CachedLiteralParserInput = {
literal: string;
sourceFile: ts.SourceFile;
};
export type CachedLiteralParser = ReturnType<typeof createCachedLiteralParser>;
export const createCachedLiteralParser = ({
cachedSchemaLoader,
projectNameRegex,
errorCatcher,
}: CreateCachedLiteralParserOptions) => {
const getProjectNameFromLiteral = (literal: string) =>
projectNameRegex
? (new RegExp(projectNameRegex).exec(literal) ?? [])[0]
: defaultProjectName;
const getProjectFromLiteral = async (literal: string) => {
const projectName = getProjectNameFromLiteral(literal);
const project = await cachedSchemaLoader.getItemOrCreate({
projectName,
});
if (!project) {
throw new Error(
`Project not defined for name "${projectName}", or there is an issue on schema file`
);
}
return { ...project, projectName };
};
const parser = createCacheSystem<
CachedLiteralParserValue,
CachedLiteralParserInput
>({
getKeyFromInput: (input) => input.literal.replaceAll(/\s/gi, ''),
create: async ({ literal, sourceFile }) => {
try {
const project = await getProjectFromLiteral(literal);
return {
documentInfos: await generateTypeFromLiteral(
literal,
project.schemaDocument,
getProjectNameIfNotDefault(project.projectName),
project.extension.codegenConfig
),
staticGlobals: project.staticGlobals,
};
} catch (error) {
errorCatcher(
error,
sourceFile,
sourceFile.text.indexOf(literal),
literal.length
);
return null;
}
},
checkValidity: async ({ input }) => {
const projectName = getProjectNameFromLiteral(input.literal);
return await cachedSchemaLoader.checkItemValidity({
projectName,
});
},
});
return parser;
};