-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
JsonProtocolEncoder.ts
99 lines (84 loc) · 2.73 KB
/
JsonProtocolEncoder.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
95
96
97
98
99
import { EngineBatchQuery, JsonQuery, JsonQueryAction } from '@prisma/engine-core'
import { DMMFDatamodelHelper } from '../../../dmmf'
import { ErrorFormat } from '../../../getPrismaClient'
import { deepGet } from '../../../utils/deep-set'
import { CreateMessageOptions, ProtocolEncoder, ProtocolMessage } from '../common'
import { deserializeJsonResponse } from './deserialize'
import { serializeJsonQuery } from './serialize'
export class JsonProtocolEncoder implements ProtocolEncoder<JsonQuery> {
constructor(private baseDmmf: DMMFDatamodelHelper, private errorFormat: ErrorFormat) {}
createMessage(createOptions: CreateMessageOptions): JsonProtocolMessage {
const query = serializeJsonQuery({ ...createOptions, baseDmmf: this.baseDmmf, errorFormat: this.errorFormat })
return new JsonProtocolMessage(query)
}
createBatch(messages: JsonProtocolMessage[]): EngineBatchQuery {
return messages.map((message) => message.toEngineQuery())
}
}
const isWrite: Record<JsonQueryAction, boolean> = {
aggregate: false,
aggregateRaw: false,
createMany: true,
createOne: true,
deleteMany: true,
deleteOne: true,
executeRaw: true,
findFirst: false,
findFirstOrThrow: false,
findMany: false,
findRaw: false,
findUnique: false,
findUniqueOrThrow: false,
groupBy: false,
queryRaw: false,
runCommandRaw: true,
updateMany: true,
updateOne: true,
upsertOne: true,
}
export class JsonProtocolMessage implements ProtocolMessage<JsonQuery> {
constructor(readonly query: JsonQuery) {}
isWrite(): boolean {
return isWrite[this.query.action]
}
getBatchId(): string | undefined {
if (this.query.action !== 'findUnique') {
return undefined
}
const parts: string[] = []
if (this.query.modelName) {
parts.push(this.query.modelName)
}
if (this.query.query.arguments) {
parts.push(buildKeysString(this.query.query.arguments))
}
parts.push(buildKeysString(this.query.query.selection))
return parts.join('')
}
toDebugString(): string {
return JSON.stringify(this.query, null, 2)
}
toEngineQuery(): JsonQuery {
return this.query
}
deserializeResponse(data: unknown, dataPath: string[]): unknown {
if (!data) {
return data
}
const response = Object.values(data)[0]
const pathForGet = dataPath.filter((key) => key !== 'select' && key !== 'include')
return deserializeJsonResponse(deepGet(response, pathForGet))
}
}
function buildKeysString(obj: object): string {
const keysArray = Object.keys(obj)
.sort()
.map((key) => {
const value = obj[key]
if (typeof value === 'object' && value !== null) {
return `(${key} ${buildKeysString(value)})`
}
return key
})
return `(${keysArray.join(' ')})`
}