-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathprovider.ts
More file actions
98 lines (90 loc) · 3.61 KB
/
Copy pathprovider.ts
File metadata and controls
98 lines (90 loc) · 3.61 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
91
92
93
94
95
96
97
98
import { readFile } from 'node:fs/promises';
import type { ContractConfig, ContractSourceDiagnostic } from '@prisma-next/config/config-types';
import { buildSymbolTable, rangeToPslSpan } from '@prisma-next/psl-parser';
import type { ParseDiagnostic, SourceFile } from '@prisma-next/psl-parser/syntax';
import { parse } from '@prisma-next/psl-parser/syntax';
import { ifDefined } from '@prisma-next/utils/defined';
import { notOk, ok } from '@prisma-next/utils/result';
import { interpretPslDocumentToMongoContract } from './interpreter';
export interface MongoContractOptions {
readonly output?: string;
/**
* Overrides the codec ids an `enum` block that omits `@@type` infers. When omitted,
* the interpreter defaults them to the target's PSL `String`/`Int` scalar type
* descriptors, so bare-member enums work without explicit wiring.
*/
readonly enumInferenceCodecs?: { readonly text: string; readonly int: string };
}
function mapParseDiagnostics(
diagnostics: readonly ParseDiagnostic[],
sourceFile: SourceFile,
sourceId: string,
): ContractSourceDiagnostic[] {
return diagnostics.map((diagnostic) => ({
code: diagnostic.code,
message: diagnostic.message,
sourceId,
span: rangeToPslSpan(diagnostic.range, sourceFile),
}));
}
export function mongoContract(schemaPath: string, options?: MongoContractOptions): ContractConfig {
return {
source: {
sourceFormat: 'psl',
inputs: [schemaPath],
load: async (context) => {
const [absoluteSchemaPath] = context.resolvedInputs;
if (absoluteSchemaPath === undefined) {
throw new Error(
'mongoContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',
);
}
let schema: string;
try {
schema = await readFile(absoluteSchemaPath, 'utf-8');
} catch (error) {
const message = String(error);
return notOk({
summary: `Failed to read Prisma schema at "${schemaPath}"`,
diagnostics: [
{
code: 'PSL_SCHEMA_READ_FAILED',
message,
sourceId: schemaPath,
},
],
meta: { schemaPath, absoluteSchemaPath, cause: message },
});
}
const { document, sourceFile, diagnostics: parseDiagnostics } = parse(schema);
const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({
document,
sourceFile,
scalarTypes: [...context.scalarTypeDescriptors.keys()],
pslBlockDescriptors: context.authoringContributions.pslBlockDescriptors,
});
// Do not short-circuit on provider-level diagnostics; recovered CST can
// still produce interpreter diagnostics in the same response.
const seedDiagnostics = [
...mapParseDiagnostics(parseDiagnostics, sourceFile, schemaPath),
...mapParseDiagnostics(symbolTableDiagnostics, sourceFile, schemaPath),
];
const interpreted = interpretPslDocumentToMongoContract({
symbolTable,
sourceFile,
sourceId: schemaPath,
seedDiagnostics,
scalarTypeDescriptors: context.scalarTypeDescriptors,
codecLookup: context.codecLookup,
authoringContributions: context.authoringContributions,
...ifDefined('enumInferenceCodecs', options?.enumInferenceCodecs),
});
if (!interpreted.ok) {
return interpreted;
}
return ok(interpreted.value);
},
},
...ifDefined('output', options?.output),
};
}