@sentio/sdk 2.39.4-rc.1 → 2.39.4-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/eth/provider.d.ts.map +1 -1
- package/lib/eth/provider.js +3 -3
- package/lib/eth/provider.js.map +1 -1
- package/lib/store/codegen.d.ts +0 -2
- package/lib/store/codegen.d.ts.map +1 -1
- package/lib/store/codegen.js +137 -170
- package/lib/store/codegen.js.map +1 -1
- package/lib/store/convert.d.ts +10 -10
- package/lib/store/convert.d.ts.map +1 -1
- package/lib/store/convert.js +75 -31
- package/lib/store/convert.js.map +1 -1
- package/lib/store/convert.test.js.map +1 -1
- package/lib/store/decorators.d.ts +24 -7
- package/lib/store/decorators.d.ts.map +1 -1
- package/lib/store/decorators.js +160 -16
- package/lib/store/decorators.js.map +1 -1
- package/lib/store/index.d.ts +0 -1
- package/lib/store/index.d.ts.map +1 -1
- package/lib/store/index.js +0 -1
- package/lib/store/index.js.map +1 -1
- package/lib/store/schema.d.ts.map +1 -1
- package/lib/store/schema.js +39 -1
- package/lib/store/schema.js.map +1 -1
- package/lib/store/store.d.ts +11 -5
- package/lib/store/store.d.ts.map +1 -1
- package/lib/store/store.js +41 -19
- package/lib/store/store.js.map +1 -1
- package/lib/store/types.d.ts +22 -3
- package/lib/store/types.d.ts.map +1 -1
- package/lib/store/types.js +14 -1
- package/lib/store/types.js.map +1 -1
- package/package.json +4 -3
- package/src/eth/provider.ts +8 -3
- package/src/store/codegen.ts +171 -196
- package/src/store/convert.ts +84 -34
- package/src/store/decorators.ts +185 -16
- package/src/store/index.ts +0 -1
- package/src/store/schema.ts +41 -1
- package/src/store/store.ts +56 -25
- package/src/store/types.ts +25 -3
- package/lib/store/entity.d.ts +0 -23
- package/lib/store/entity.d.ts.map +0 -1
- package/lib/store/entity.js +0 -70
- package/lib/store/entity.js.map +0 -1
- package/src/store/entity.ts +0 -84
package/src/store/codegen.ts
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
import {
|
2
|
-
DirectiveNode,
|
3
2
|
GraphQLEnumType,
|
4
|
-
GraphQLField,
|
5
3
|
GraphQLInterfaceType,
|
6
4
|
GraphQLList,
|
7
5
|
GraphQLNonNull,
|
@@ -9,10 +7,9 @@ import {
|
|
9
7
|
GraphQLOutputType,
|
10
8
|
GraphQLScalarType,
|
11
9
|
GraphQLSchema,
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
isListType
|
10
|
+
isEnumType,
|
11
|
+
isListType,
|
12
|
+
isNonNullType
|
16
13
|
} from 'graphql'
|
17
14
|
import * as fs from 'node:fs'
|
18
15
|
import path from 'path'
|
@@ -20,6 +17,35 @@ import mkdirp from 'mkdirp'
|
|
20
17
|
import { schemaFromFile } from './schema.js'
|
21
18
|
import chalk from 'chalk'
|
22
19
|
|
20
|
+
interface Import {
|
21
|
+
module: string
|
22
|
+
types: string[]
|
23
|
+
importType?: boolean
|
24
|
+
}
|
25
|
+
|
26
|
+
interface Field {
|
27
|
+
name: string
|
28
|
+
type: string
|
29
|
+
annotations: string[]
|
30
|
+
}
|
31
|
+
|
32
|
+
interface Class {
|
33
|
+
name: string
|
34
|
+
fields: Field[]
|
35
|
+
annotations: string[]
|
36
|
+
interfaces: string[]
|
37
|
+
}
|
38
|
+
|
39
|
+
interface Interface {
|
40
|
+
name: string
|
41
|
+
fields: Field[]
|
42
|
+
}
|
43
|
+
|
44
|
+
interface Enum {
|
45
|
+
name: string
|
46
|
+
values: string[]
|
47
|
+
}
|
48
|
+
|
23
49
|
export async function codegen(srcDir: string, outputDir: string) {
|
24
50
|
for (const file of fs.readdirSync(srcDir)) {
|
25
51
|
const f = path.join(srcDir, file)
|
@@ -33,27 +59,78 @@ export async function codegen(srcDir: string, outputDir: string) {
|
|
33
59
|
}
|
34
60
|
}
|
35
61
|
|
62
|
+
function addTypeAnnotations(ty: GraphQLOutputType, annotations: string[]) {
|
63
|
+
if (isNonNullType(ty)) {
|
64
|
+
annotations.push('@Required')
|
65
|
+
addTypeAnnotations(ty.ofType, annotations)
|
66
|
+
return
|
67
|
+
}
|
68
|
+
|
69
|
+
if (isRelationType(ty)) {
|
70
|
+
if (isListType(ty)) {
|
71
|
+
annotations.push(`@Many("${ty.ofType}")`)
|
72
|
+
} else {
|
73
|
+
annotations.push(`@One("${ty}")`)
|
74
|
+
}
|
75
|
+
} else if (isEnumType(ty)) {
|
76
|
+
annotations.push(`@Column("String${isNonNullType(ty) ? '!' : ''}")`)
|
77
|
+
} else {
|
78
|
+
if (isListType(ty)) {
|
79
|
+
if (isListType(ty.ofType)) {
|
80
|
+
annotations.push(`@ListColumn()`)
|
81
|
+
addTypeAnnotations(ty.ofType, annotations)
|
82
|
+
} else {
|
83
|
+
annotations.push(`@ListColumn("${ty.ofType}")`)
|
84
|
+
}
|
85
|
+
} else {
|
86
|
+
annotations.push(`@Column("${ty}")`)
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
36
91
|
async function codegenInternal(schema: GraphQLSchema, source: string, target: string) {
|
37
|
-
const
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
92
|
+
const imports: Import[] = [
|
93
|
+
{
|
94
|
+
module: '@sentio/sdk/store',
|
95
|
+
types: ['String', 'Int', 'BigInt', 'Float', 'ID', 'Bytes', 'Timestamp', 'Boolean'],
|
96
|
+
importType: true
|
97
|
+
},
|
98
|
+
{
|
99
|
+
module: '@sentio/sdk/store',
|
100
|
+
types: ['Entity', 'Required', 'One', 'Many', 'Column', 'ListColumn']
|
101
|
+
},
|
102
|
+
{
|
103
|
+
module: '@sentio/bigdecimal',
|
104
|
+
types: ['BigDecimal']
|
105
|
+
},
|
106
|
+
{
|
107
|
+
module: '@sentio/sdk',
|
108
|
+
types: ['DatabaseSchema']
|
109
|
+
}
|
45
110
|
]
|
46
|
-
const
|
111
|
+
const enumns: Enum[] = []
|
112
|
+
const interfaces: Interface[] = []
|
113
|
+
const classes: Class[] = []
|
47
114
|
|
48
115
|
for (const t of Object.values(schema.getTypeMap())) {
|
49
116
|
if (t.name.startsWith('__')) {
|
50
117
|
continue
|
51
118
|
}
|
52
119
|
if (t instanceof GraphQLEnumType) {
|
53
|
-
|
120
|
+
enumns.push({
|
121
|
+
name: t.name,
|
122
|
+
values: t.getValues().map((v) => v.value)
|
123
|
+
})
|
54
124
|
}
|
55
125
|
if (t instanceof GraphQLInterfaceType) {
|
56
|
-
|
126
|
+
interfaces.push({
|
127
|
+
name: t.name,
|
128
|
+
fields: Object.values(t.getFields()).map((f) => ({
|
129
|
+
name: f.name,
|
130
|
+
type: genType(f.type),
|
131
|
+
annotations: []
|
132
|
+
}))
|
133
|
+
})
|
57
134
|
}
|
58
135
|
}
|
59
136
|
for (const t of Object.values(schema.getTypeMap())) {
|
@@ -62,20 +139,84 @@ async function codegenInternal(schema: GraphQLSchema, source: string, target: st
|
|
62
139
|
}
|
63
140
|
|
64
141
|
if (t instanceof GraphQLObjectType) {
|
65
|
-
const
|
66
|
-
|
67
|
-
|
142
|
+
const fields: Field[] = []
|
143
|
+
for (const f of Object.values(t.getFields())) {
|
144
|
+
const type = genType(f.type)
|
145
|
+
const annotations: string[] = []
|
146
|
+
addTypeAnnotations(f.type, annotations)
|
147
|
+
if (isRelationType(f.type)) {
|
148
|
+
fields.push({
|
149
|
+
name: f.name,
|
150
|
+
type: `Promise<${type}>`,
|
151
|
+
annotations
|
152
|
+
})
|
153
|
+
const isMany = type.startsWith('Array')
|
154
|
+
fields.push({
|
155
|
+
name: f.name + 'ID' + (isMany ? 's' : ''),
|
156
|
+
type: isMany ? `Array<ID | undefined>` : `ID`,
|
157
|
+
annotations: []
|
158
|
+
})
|
159
|
+
} else {
|
160
|
+
fields.push({
|
161
|
+
name: f.name,
|
162
|
+
type: type,
|
163
|
+
annotations
|
164
|
+
})
|
165
|
+
}
|
166
|
+
}
|
167
|
+
classes.push({
|
168
|
+
name: t.name,
|
169
|
+
fields,
|
170
|
+
annotations: [`@Entity("${t.name}")`],
|
171
|
+
interfaces: t.getInterfaces().map((i) => i.name)
|
172
|
+
})
|
68
173
|
}
|
69
174
|
}
|
70
175
|
|
176
|
+
const template = `
|
177
|
+
/* Autogenerated file. Do not edit manually. */
|
178
|
+
/* tslint:disable */
|
179
|
+
/* eslint-disable */
|
180
|
+
${imports.map((i) => `import ${i.importType ? 'type ' : ''}{ ${i.types.join(', ')} } from '${i.module}'`).join('\n')}
|
181
|
+
|
182
|
+
${enumns
|
183
|
+
.map(
|
184
|
+
(e) => `export enum ${e.name} {
|
185
|
+
${e.values.map((v) => `${v} = "${v}"`).join(', ')}
|
186
|
+
}`
|
187
|
+
)
|
188
|
+
.join('\n')}
|
189
|
+
|
190
|
+
${interfaces
|
191
|
+
.map(
|
192
|
+
(i) => `export interface ${i.name} {
|
193
|
+
${i.fields.map((f) => `\t${f.name}: ${f.type}`).join('\n')}
|
194
|
+
}`
|
195
|
+
)
|
196
|
+
.join('\n')}
|
197
|
+
|
198
|
+
${classes
|
199
|
+
.map(
|
200
|
+
(c) => `
|
201
|
+
${c.annotations.join('\n')}
|
202
|
+
export class ${c.name} ${c.interfaces.length > 0 ? `implements ${c.interfaces.join(', ')}` : ''} {
|
203
|
+
${c.fields.map((f) => `${f.annotations.map((a) => `\n\t${a}`).join('')}\n\t${f.name}: ${f.type}`).join('\n')}
|
204
|
+
|
205
|
+
constructor(data: Partial<${c.name}>) {}
|
206
|
+
|
207
|
+
}`
|
208
|
+
)
|
209
|
+
.join('\n')}
|
210
|
+
`
|
211
|
+
|
71
212
|
const contents =
|
72
|
-
|
213
|
+
template +
|
73
214
|
`\n
|
74
215
|
const source = \`${source.replaceAll('`', '`')}\`
|
75
216
|
DatabaseSchema.register({
|
76
217
|
source,
|
77
218
|
entities: {
|
78
|
-
${
|
219
|
+
${classes.map((e) => `"${e.name}": ${e.name}`).join(',\n\t\t')}
|
79
220
|
}
|
80
221
|
})
|
81
222
|
`
|
@@ -84,196 +225,30 @@ DatabaseSchema.register({
|
|
84
225
|
fs.writeFileSync(target, contents)
|
85
226
|
}
|
86
227
|
|
87
|
-
const JsTypes: Record<string, string> = {
|
88
|
-
ID: 'string',
|
89
|
-
String: 'string',
|
90
|
-
Int: 'number',
|
91
|
-
Float: 'number',
|
92
|
-
Boolean: 'boolean',
|
93
|
-
BigInt: 'bigint',
|
94
|
-
BigDecimal: 'BigDecimal',
|
95
|
-
DateTime: 'Date',
|
96
|
-
Json: 'any',
|
97
|
-
Bytes: 'Uint8Array'
|
98
|
-
}
|
99
|
-
const graphqlTypes = Object.entries(JsTypes).reduce(
|
100
|
-
(acc, [k, v]) => {
|
101
|
-
acc[v] = k
|
102
|
-
return acc
|
103
|
-
},
|
104
|
-
{} as Record<string, string>
|
105
|
-
)
|
106
|
-
|
107
228
|
function genType(type: GraphQLOutputType, required?: boolean): string {
|
108
229
|
if (type instanceof GraphQLNonNull) {
|
109
230
|
return genType(type.ofType, true)
|
110
231
|
} else if (type instanceof GraphQLScalarType) {
|
111
232
|
return required ? type.name : `${type.name} | undefined`
|
112
233
|
} else if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
|
113
|
-
return type.name
|
234
|
+
return required ? type.name : `${type.name} | undefined`
|
114
235
|
} else if (type instanceof GraphQLList) {
|
115
236
|
return `Array<${genType(type.ofType)}>`
|
116
237
|
} else if (type instanceof GraphQLEnumType) {
|
117
|
-
return type.name
|
238
|
+
return required ? type.name : `${type.name} | undefined`
|
118
239
|
} else {
|
119
240
|
throw new Error('Unsupported type: ' + type)
|
120
241
|
}
|
121
242
|
}
|
122
243
|
|
123
|
-
function
|
244
|
+
function isRelationType(type: GraphQLOutputType): boolean {
|
124
245
|
if (type instanceof GraphQLNonNull) {
|
125
|
-
return
|
126
|
-
} else if (type instanceof
|
127
|
-
return
|
128
|
-
}
|
129
|
-
return isObjectType(type) || isInterfaceType(type)
|
130
|
-
}
|
131
|
-
|
132
|
-
function isList(type: GraphQLOutputType) {
|
133
|
-
if (type instanceof GraphQLNonNull) {
|
134
|
-
return isListType(type.ofType)
|
135
|
-
} else {
|
136
|
-
return isListType(type)
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
function getElementType(type: GraphQLOutputType) {
|
141
|
-
if (type instanceof GraphQLNonNull) {
|
142
|
-
return getElementType(type.ofType)
|
246
|
+
return isRelationType(type.ofType)
|
247
|
+
} else if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
|
248
|
+
return true
|
143
249
|
} else if (type instanceof GraphQLList) {
|
144
|
-
return type.ofType
|
145
|
-
}
|
146
|
-
return type
|
147
|
-
}
|
148
|
-
|
149
|
-
const getConverter = (t: GraphQLOutputType): string => {
|
150
|
-
if (t instanceof GraphQLNonNull) {
|
151
|
-
return `required_(${getConverter(t.ofType)})`
|
152
|
-
}
|
153
|
-
if (t instanceof GraphQLList) {
|
154
|
-
return `array_(${getConverter(t.ofType)})`
|
155
|
-
}
|
156
|
-
if (t instanceof GraphQLEnumType) {
|
157
|
-
return `enumerate_<${t.name}>(${t.name})`
|
158
|
-
}
|
159
|
-
if (isObject(t)) {
|
160
|
-
return `objectId_<${genType(getElementType(t))}>()`
|
161
|
-
}
|
162
|
-
return `${t.name}Converter`
|
163
|
-
}
|
164
|
-
|
165
|
-
function genField(field: GraphQLField<any, any>) {
|
166
|
-
const isNonNull = field.type instanceof GraphQLNonNull
|
167
|
-
const directives = field.astNode?.directives?.map((d) => '\t' + directive2decorator(d) + '\n') || []
|
168
|
-
|
169
|
-
const type = genType(field.type)
|
170
|
-
|
171
|
-
if (isObject(field.type)) {
|
172
|
-
const t = getElementType(field.type)
|
173
|
-
const typeAsArg = isInterfaceType(t) ? `"${t}"` : genType(t)
|
174
|
-
|
175
|
-
if (isList(field.type)) {
|
176
|
-
const required = (field.type as GraphQLList<any>).ofType instanceof GraphQLNonNull
|
177
|
-
const converter = required ? `array_(required_(IDConverter))` : `array_(IDConverter)`
|
178
|
-
const returnType = required ? `ID[]` : `Array<ID | undefined>`
|
179
|
-
return `${directives.join()}\tget ${field.name}(): Promise<${genType(t)}[]> { return this.getFieldObjectArray(${typeAsArg}, "${field.name}") as Promise<${genType(t)}[]> }
|
180
|
-
set ${field.name}(value: ${type} | ID[]) { this.setObject("${field.name}", value) }
|
181
|
-
get ${field.name}Ids(): ${returnType} { return this.get("${field.name}", ${converter}) }`
|
182
|
-
}
|
183
|
-
|
184
|
-
return `${directives.join()}\tget ${field.name}(): Promise<${genType(t)} | undefined> { return this.getObject(${typeAsArg},"${field.name}") as Promise<${genType(t)} | undefined> }
|
185
|
-
set ${field.name}(value: ${type} | ID) { this.set("${field.name}", value, objectId_<${type}>()) }
|
186
|
-
get ${field.name}Id(): ID | undefined { return this.get("${field.name}", IDConverter) }`
|
187
|
-
}
|
188
|
-
|
189
|
-
return `${directives.join()}\tget ${field.name}(): ${type} { return this.get("${field.name}", ${getConverter(field.type)}) }
|
190
|
-
set ${field.name}(value: ${type}) { this.set("${field.name}", value, ${getConverter(field.type)}) }`
|
191
|
-
}
|
192
|
-
|
193
|
-
function genDataType(t: GraphQLObjectType<any, any>) {
|
194
|
-
let output = `type ${t.name}Data = `
|
195
|
-
const relationsFields = Object.values(t.getFields()).filter((f) => isObject(f.type))
|
196
|
-
if (relationsFields.length > 0) {
|
197
|
-
output += `Omit<${t.name}, ${relationsFields.map((f) => `"${f.name}"`).join(' | ')}>`
|
198
|
-
|
199
|
-
output +=
|
200
|
-
' & {' +
|
201
|
-
relationsFields
|
202
|
-
.map((f) => {
|
203
|
-
const type = genType(getElementType(f.type))
|
204
|
-
return `${f.name}?: ${isList(f.type) ? `Array<ID|${type}>` : `ID | ${type}`}`
|
205
|
-
})
|
206
|
-
.join(', ') +
|
207
|
-
'}'
|
250
|
+
return isRelationType(type.ofType)
|
208
251
|
} else {
|
209
|
-
|
210
|
-
}
|
211
|
-
return output
|
212
|
-
}
|
213
|
-
|
214
|
-
function genEntity(t: GraphQLObjectType<any, any>) {
|
215
|
-
const decorators = t.astNode?.directives?.filter((d) => d.name.value != 'entity').map(directive2decorator) || []
|
216
|
-
|
217
|
-
let impls = ''
|
218
|
-
if (t.getInterfaces().length > 0) {
|
219
|
-
impls +=
|
220
|
-
' implements ' +
|
221
|
-
t
|
222
|
-
.getInterfaces()
|
223
|
-
.map((i) => i.name)
|
224
|
-
.join(', ')
|
225
|
-
}
|
226
|
-
|
227
|
-
return `
|
228
|
-
${genDataType(t)}
|
229
|
-
${decorators.join('\n')}
|
230
|
-
@entity("${t.name}")
|
231
|
-
export class ${t.name} extends Entity${impls} {
|
232
|
-
${genConverters(t)}
|
233
|
-
constructor(data: Partial<${t.name}Data>) {
|
234
|
-
super(${t.name}.entityConverter.from(data))
|
235
|
-
}
|
236
|
-
${Object.values(t.getFields()).map(genField).join('\n')}
|
237
|
-
}`
|
238
|
-
}
|
239
|
-
|
240
|
-
function genConverters(t: GraphQLObjectType<any, any>) {
|
241
|
-
const fields = Object.values(t.getFields())
|
242
|
-
const converters = fields.map((f) => {
|
243
|
-
const type = genType(f.type)
|
244
|
-
const converter = getConverter(f.type)
|
245
|
-
return `\t\t${f.name}: ${converter},`
|
246
|
-
})
|
247
|
-
return `static entityConverter = new StructConverter({\n ${converters.join('\n')} \n})`
|
248
|
-
}
|
249
|
-
|
250
|
-
function genInterface(t: GraphQLInterfaceType) {
|
251
|
-
return `
|
252
|
-
export interface ${t.name} {
|
253
|
-
${Object.values(t.getFields())
|
254
|
-
.map((f) => `\t${f.name}: ${genType(f.type)}`)
|
255
|
-
.join('\n')}
|
256
|
-
}`
|
257
|
-
}
|
258
|
-
|
259
|
-
export function directive2decorator(directive: DirectiveNode) {
|
260
|
-
let s = `@${directive.name.value}`
|
261
|
-
if (directive.arguments?.length) {
|
262
|
-
s += `(${directive.arguments
|
263
|
-
?.map((arg) => {
|
264
|
-
return arg.value.kind === Kind.STRING ? `"${arg.value.value}"` : `${arg.value}`
|
265
|
-
})
|
266
|
-
.join(', ')})`
|
252
|
+
return false
|
267
253
|
}
|
268
|
-
return s
|
269
|
-
}
|
270
|
-
|
271
|
-
function genEnum(t: GraphQLEnumType) {
|
272
|
-
return `
|
273
|
-
export enum ${t.name} {
|
274
|
-
${t
|
275
|
-
.getValues()
|
276
|
-
.map((v) => `\t${v.name} = "${v.value}"`)
|
277
|
-
.join(', ')}
|
278
|
-
}`
|
279
254
|
}
|
package/src/store/convert.ts
CHANGED
@@ -1,27 +1,35 @@
|
|
1
|
-
import {
|
2
|
-
import { String, Int, Float, ID, Bytes,
|
3
|
-
import { Entity } from './entity.js'
|
1
|
+
import { RichValue, RichValue_NullValue } from '@sentio/protos'
|
2
|
+
import type { String, Int, Float, ID, Bytes, Timestamp, Boolean } from './types.js'
|
4
3
|
import { BigDecimal } from '@sentio/bigdecimal'
|
5
4
|
|
6
5
|
export interface ValueConverter<T> {
|
7
6
|
from: (value: T) => RichValue
|
8
7
|
to: (value: RichValue) => T
|
8
|
+
required?: boolean
|
9
|
+
isArray?: boolean
|
10
|
+
isRelation?: boolean
|
11
|
+
relationName?: string
|
9
12
|
}
|
10
13
|
|
14
|
+
export const ValueRequiredError = new Error('Value is required but received null or undefined')
|
15
|
+
|
11
16
|
export function required_<T>(converter: ValueConverter<T | undefined>): ValueConverter<T> {
|
17
|
+
const { from, to, ...rest } = converter
|
12
18
|
return {
|
13
19
|
from: (value: T | undefined) => {
|
14
20
|
if (value == null) {
|
15
|
-
throw
|
21
|
+
throw ValueRequiredError
|
16
22
|
}
|
17
|
-
return
|
23
|
+
return from(value)
|
18
24
|
},
|
19
25
|
to: (value: RichValue) => {
|
20
26
|
if (value == null || value.nullValue) {
|
21
|
-
throw
|
27
|
+
throw ValueRequiredError
|
22
28
|
}
|
23
|
-
return
|
24
|
-
}
|
29
|
+
return to(value)!
|
30
|
+
},
|
31
|
+
...rest,
|
32
|
+
required: true
|
25
33
|
}
|
26
34
|
}
|
27
35
|
|
@@ -36,7 +44,10 @@ export function array_<T>(converter: ValueConverter<T>): ValueConverter<T[]> {
|
|
36
44
|
},
|
37
45
|
to: (value: RichValue) => {
|
38
46
|
return value.listValue?.values.map(converter.to) || []
|
39
|
-
}
|
47
|
+
},
|
48
|
+
isArray: true,
|
49
|
+
isRelation: converter.isRelation,
|
50
|
+
relationName: converter.relationName
|
40
51
|
}
|
41
52
|
}
|
42
53
|
|
@@ -58,7 +69,7 @@ export function enumerate_<T extends string | number>(values: Record<T, string>)
|
|
58
69
|
}
|
59
70
|
}
|
60
71
|
|
61
|
-
export function objectId_<T>(): ValueConverter<T | ID> {
|
72
|
+
export function objectId_<T>(entityName: string): ValueConverter<T | ID> {
|
62
73
|
return {
|
63
74
|
from: (value: T | ID) => {
|
64
75
|
if (typeof value == 'string') {
|
@@ -66,9 +77,16 @@ export function objectId_<T>(): ValueConverter<T | ID> {
|
|
66
77
|
stringValue: value
|
67
78
|
}
|
68
79
|
}
|
69
|
-
if (value instanceof
|
80
|
+
if (value instanceof Uint8Array) {
|
81
|
+
return {
|
82
|
+
stringValue: `0x${Buffer.from(value).toString('hex')}`
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
if (typeof value == 'object') {
|
87
|
+
const entity = value as any
|
70
88
|
return {
|
71
|
-
stringValue:
|
89
|
+
stringValue: entity.id.toString()
|
72
90
|
}
|
73
91
|
}
|
74
92
|
return {
|
@@ -77,7 +95,9 @@ export function objectId_<T>(): ValueConverter<T | ID> {
|
|
77
95
|
},
|
78
96
|
to(v) {
|
79
97
|
return v.stringValue as T | ID
|
80
|
-
}
|
98
|
+
},
|
99
|
+
isRelation: true,
|
100
|
+
relationName: entityName
|
81
101
|
}
|
82
102
|
}
|
83
103
|
|
@@ -146,8 +166,8 @@ export const BooleanConverter: ValueConverter<Boolean | undefined> = {
|
|
146
166
|
}
|
147
167
|
}
|
148
168
|
|
149
|
-
export const
|
150
|
-
from: (value:
|
169
|
+
export const TimestampConverter: ValueConverter<Timestamp | undefined> = {
|
170
|
+
from: (value: Timestamp | undefined) => {
|
151
171
|
if (value == null) {
|
152
172
|
return {
|
153
173
|
nullValue: RichValue_NullValue.NULL_VALUE
|
@@ -178,7 +198,33 @@ export const BytesConverter: ValueConverter<Bytes | undefined> = {
|
|
178
198
|
}
|
179
199
|
}
|
180
200
|
|
181
|
-
export const IDConverter: ValueConverter<ID | undefined> =
|
201
|
+
export const IDConverter: ValueConverter<ID | undefined> = {
|
202
|
+
from(value: ID | undefined): RichValue {
|
203
|
+
if (typeof value == 'string') {
|
204
|
+
return {
|
205
|
+
stringValue: value
|
206
|
+
}
|
207
|
+
}
|
208
|
+
if (value instanceof Uint8Array) {
|
209
|
+
return {
|
210
|
+
stringValue: `0x${Buffer.from(value).toString('hex')}`
|
211
|
+
}
|
212
|
+
}
|
213
|
+
return {
|
214
|
+
nullValue: RichValue_NullValue.NULL_VALUE
|
215
|
+
}
|
216
|
+
},
|
217
|
+
to(value: RichValue): ID | undefined {
|
218
|
+
if (value.stringValue) {
|
219
|
+
return value.stringValue as ID
|
220
|
+
}
|
221
|
+
if (value.bytesValue) {
|
222
|
+
const v = `0x${Buffer.from(value.bytesValue).toString('hex')}`
|
223
|
+
return v as ID
|
224
|
+
}
|
225
|
+
return undefined
|
226
|
+
}
|
227
|
+
}
|
182
228
|
|
183
229
|
export const BigDecimalConverter: ValueConverter<BigDecimal | undefined> = {
|
184
230
|
from: (value?: BigDecimal): RichValue => {
|
@@ -187,9 +233,8 @@ export const BigDecimalConverter: ValueConverter<BigDecimal | undefined> = {
|
|
187
233
|
nullValue: RichValue_NullValue.NULL_VALUE
|
188
234
|
}
|
189
235
|
}
|
190
|
-
|
191
|
-
const exp = value.
|
192
|
-
const s = value.multipliedBy(new BigDecimal(10).pow(exp)).toFixed()
|
236
|
+
const s = (value.c || []).join('')
|
237
|
+
const exp = -(s.length - (value.e ?? 0) - 1)
|
193
238
|
|
194
239
|
return {
|
195
240
|
bigdecimalValue: {
|
@@ -202,7 +247,13 @@ export const BigDecimalConverter: ValueConverter<BigDecimal | undefined> = {
|
|
202
247
|
const d = v.bigdecimalValue
|
203
248
|
if (d) {
|
204
249
|
const i = bytesToBigInt(d.value!.data)
|
205
|
-
|
250
|
+
let ret = new BigDecimal(i.toString())
|
251
|
+
if (d.exp < 0) {
|
252
|
+
ret = ret.dividedBy(new BigDecimal(10).pow(-d.exp))
|
253
|
+
} else {
|
254
|
+
ret = ret.multipliedBy(new BigDecimal(10).pow(d.exp))
|
255
|
+
}
|
256
|
+
return ret.multipliedBy(d.value?.negative ? -1 : 1)
|
206
257
|
}
|
207
258
|
return undefined
|
208
259
|
}
|
@@ -231,20 +282,6 @@ export const BigIntConverter: ValueConverter<bigint | undefined> = {
|
|
231
282
|
}
|
232
283
|
}
|
233
284
|
|
234
|
-
export class StructConverter<T extends Entity> {
|
235
|
-
constructor(private converters: Record<string, ValueConverter<any>>) {}
|
236
|
-
|
237
|
-
from(data: any): RichStruct {
|
238
|
-
const fields: Record<string, RichValue> = {}
|
239
|
-
for (const [field, value] of Object.entries(data)) {
|
240
|
-
if (this.converters[field] !== undefined) {
|
241
|
-
fields[field] = this.converters[field].from(value)
|
242
|
-
}
|
243
|
-
}
|
244
|
-
return { fields }
|
245
|
-
}
|
246
|
-
}
|
247
|
-
|
248
285
|
export function bytesToBigInt(bytes: Uint8Array) {
|
249
286
|
let intValue = BigInt(0)
|
250
287
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -269,3 +306,16 @@ export function toBigInteger(a: bigint) {
|
|
269
306
|
data: new Uint8Array(buffer)
|
270
307
|
}
|
271
308
|
}
|
309
|
+
|
310
|
+
export const TypeConverters: Record<string, ValueConverter<any>> = {
|
311
|
+
BigDecimal: BigDecimalConverter,
|
312
|
+
BigInt: BigIntConverter,
|
313
|
+
String: StringConverter,
|
314
|
+
Boolean: BooleanConverter,
|
315
|
+
Uint8Array: BytesConverter,
|
316
|
+
ID: IDConverter,
|
317
|
+
Bytes: BytesConverter,
|
318
|
+
Int: IntConverter,
|
319
|
+
Float: FloatConverter,
|
320
|
+
Timestamp: TimestampConverter
|
321
|
+
}
|