-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprismaMetaMapper.ts
More file actions
91 lines (82 loc) · 3.05 KB
/
Copy pathprismaMetaMapper.ts
File metadata and controls
91 lines (82 loc) · 3.05 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
import _ from 'lodash';
import pi from '@prisma/internals';
import { DMMF, ReadonlyDeep } from '@prisma/client/runtime/client';
import { readFile } from 'fs/promises';
const { getDMMF } = pi
export interface PrismaMapperEntity {
name: string;
dbName: string | null;
fields: DMMF.Field[];
uniqueFields: string[][];
uniqueIndexes: DMMF.uniqueIndex[];
documentation?: string;
primaryKey: DMMF.PrimaryKey | null;
isGenerated?: boolean;
}
export interface PrismaMapperEntityField {
kind: DMMF.FieldKind;
name: string;
isRequired: boolean;
isList: boolean;
isUnique: boolean;
isId: boolean;
isReadOnly: boolean;
isGenerated?: boolean;
isUpdatedAt?: boolean;
/**
* Describes the data type in the same the way it is defined in the Prisma schema:
* BigInt, Boolean, Bytes, DateTime, Decimal, Float, Int, JSON, String, $ModelName
*/
type: string;
dbName?: string | null;
hasDefaultValue: boolean;
default?: DMMF.FieldDefault | DMMF.FieldDefaultScalar | DMMF.FieldDefaultScalar[];
relationFromFields?: string[];
relationToFields?: string[];
relationOnDelete?: string;
relationName?: string;
documentation?: string;
}
export class PrismaMetaMapper {
static relativePrismaFilePath: string = "./prisma/schema.prisma"
private static cache: Record<string, PrismaMapperEntity> | null = null;
static invalidateCache() {
PrismaMetaMapper.cache = null;
}
static normalizeEntityName(entityName: string) {
return _.upperFirst(_.camelCase(entityName.replace(/Model$/, ''))) as string
}
static async getDMMF(overrideRelativePrismaFilePath?: string): Promise<ReadonlyDeep<{
datamodel: DMMF.Datamodel;
schema: DMMF.Schema;
mappings: DMMF.Mappings;
}>> {
const dmmf = await getDMMF({
datamodel: await readFile(overrideRelativePrismaFilePath ?? this.relativePrismaFilePath, 'utf-8')
})
return dmmf
}
static async getEntity(entityName: string) {
const tablesInfo = await this.getTablesInfo()
const exactEntityName = _.upperFirst(_.camelCase(entityName))
const entity = tablesInfo[entityName] ?? tablesInfo[exactEntityName] ?? tablesInfo[this.normalizeEntityName(entityName)]
if (!entity) {
throw new Error(`Unknown Prisma entity "${entityName}"`)
}
return entity
}
static async getEntityFieldMapping(entityName: string) {
const { fields } = await this.getEntity(entityName)
return _.transform(fields, (result, field) => {
result[field.name] = field;
}, {}) as Promise<Record<string, PrismaMapperEntityField>>
}
static async getTablesInfo() {
if (PrismaMetaMapper.cache) return PrismaMetaMapper.cache;
const dmmf = await this.getDMMF()
PrismaMetaMapper.cache = _.transform(dmmf.datamodel.models, (finalInfoMap, value) => {
finalInfoMap[value.name] = value
}, {}) as Record<string, PrismaMapperEntity>;
return PrismaMetaMapper.cache;
}
}