@sentio/sdk 2.39.3 → 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.
Files changed (47) hide show
  1. package/lib/eth/provider.d.ts.map +1 -1
  2. package/lib/eth/provider.js +3 -3
  3. package/lib/eth/provider.js.map +1 -1
  4. package/lib/store/codegen.d.ts +0 -2
  5. package/lib/store/codegen.d.ts.map +1 -1
  6. package/lib/store/codegen.js +147 -158
  7. package/lib/store/codegen.js.map +1 -1
  8. package/lib/store/convert.d.ts +32 -0
  9. package/lib/store/convert.d.ts.map +1 -0
  10. package/lib/store/convert.js +293 -0
  11. package/lib/store/convert.js.map +1 -0
  12. package/lib/store/convert.test.d.ts +2 -0
  13. package/lib/store/convert.test.d.ts.map +1 -0
  14. package/lib/store/convert.test.js.map +1 -0
  15. package/lib/store/decorators.d.ts +24 -7
  16. package/lib/store/decorators.d.ts.map +1 -1
  17. package/lib/store/decorators.js +160 -16
  18. package/lib/store/decorators.js.map +1 -1
  19. package/lib/store/index.d.ts +1 -1
  20. package/lib/store/index.d.ts.map +1 -1
  21. package/lib/store/index.js +1 -1
  22. package/lib/store/index.js.map +1 -1
  23. package/lib/store/schema.d.ts.map +1 -1
  24. package/lib/store/schema.js +39 -1
  25. package/lib/store/schema.js.map +1 -1
  26. package/lib/store/store.d.ts +23 -4
  27. package/lib/store/store.d.ts.map +1 -1
  28. package/lib/store/store.js +119 -59
  29. package/lib/store/store.js.map +1 -1
  30. package/lib/store/types.d.ts +22 -5
  31. package/lib/store/types.d.ts.map +1 -1
  32. package/lib/store/types.js +14 -1
  33. package/lib/store/types.js.map +1 -1
  34. package/package.json +4 -3
  35. package/src/eth/provider.ts +8 -3
  36. package/src/store/codegen.ts +183 -185
  37. package/src/store/convert.ts +321 -0
  38. package/src/store/decorators.ts +185 -16
  39. package/src/store/index.ts +1 -1
  40. package/src/store/schema.ts +41 -1
  41. package/src/store/store.ts +157 -56
  42. package/src/store/types.ts +25 -6
  43. package/lib/store/entity.d.ts +0 -17
  44. package/lib/store/entity.d.ts.map +0 -1
  45. package/lib/store/entity.js +0 -61
  46. package/lib/store/entity.js.map +0 -1
  47. package/src/store/entity.ts +0 -71
@@ -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
- Kind,
13
- isObjectType,
14
- isInterfaceType,
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,41 +59,164 @@ 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 results: string[] = [
38
- '/* Autogenerated file. Do not edit manually. */\n',
39
- '/* tslint:disable */',
40
- '/* eslint-disable */',
41
- "import {entity, derivedFrom, DateTime, Int, Float, String, Json, Bytes, ID, Entity, Store} from '@sentio/sdk/store'",
42
- `import { DatabaseSchema, BigDecimal } from "@sentio/sdk"`
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
+ }
43
110
  ]
44
- const entities: string[] = []
111
+ const enumns: Enum[] = []
112
+ const interfaces: Interface[] = []
113
+ const classes: Class[] = []
114
+
45
115
  for (const t of Object.values(schema.getTypeMap())) {
46
116
  if (t.name.startsWith('__')) {
47
117
  continue
48
118
  }
49
-
50
- if (t instanceof GraphQLObjectType) {
51
- const entityContent = genEntity(t)
52
- results.push(entityContent)
53
- entities.push(t.name)
54
- }
55
119
  if (t instanceof GraphQLEnumType) {
56
- results.push(genEnum(t))
120
+ enumns.push({
121
+ name: t.name,
122
+ values: t.getValues().map((v) => v.value)
123
+ })
57
124
  }
58
125
  if (t instanceof GraphQLInterfaceType) {
59
- results.push(genInterface(t))
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
+ })
134
+ }
135
+ }
136
+ for (const t of Object.values(schema.getTypeMap())) {
137
+ if (t.name.startsWith('__')) {
138
+ continue
139
+ }
140
+
141
+ if (t instanceof GraphQLObjectType) {
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
+ })
60
173
  }
61
174
  }
62
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
+
63
212
  const contents =
64
- results.join('\n') +
213
+ template +
65
214
  `\n
66
215
  const source = \`${source.replaceAll('`', '`')}\`
67
216
  DatabaseSchema.register({
68
217
  source,
69
218
  entities: {
70
- ${entities.map((e) => `"${e}": ${e}`).join(',\n\t\t')}
219
+ ${classes.map((e) => `"${e.name}": ${e.name}`).join(',\n\t\t')}
71
220
  }
72
221
  })
73
222
  `
@@ -76,181 +225,30 @@ DatabaseSchema.register({
76
225
  fs.writeFileSync(target, contents)
77
226
  }
78
227
 
79
- const JsTypes: Record<string, string> = {
80
- ID: 'string',
81
- String: 'string',
82
- Int: 'number',
83
- Float: 'number',
84
- Boolean: 'boolean',
85
- BigInt: 'bigint',
86
- BigDecimal: 'BigDecimal',
87
- DateTime: 'Date',
88
- Json: 'any',
89
- Bytes: 'Uint8Array'
90
- }
91
- const graphqlTypes = Object.entries(JsTypes).reduce(
92
- (acc, [k, v]) => {
93
- acc[v] = k
94
- return acc
95
- },
96
- {} as Record<string, string>
97
- )
98
-
99
- function genType(type: GraphQLOutputType): string {
228
+ function genType(type: GraphQLOutputType, required?: boolean): string {
100
229
  if (type instanceof GraphQLNonNull) {
101
- return genType(type.ofType)
230
+ return genType(type.ofType, true)
102
231
  } else if (type instanceof GraphQLScalarType) {
103
- return type.name
232
+ return required ? type.name : `${type.name} | undefined`
104
233
  } else if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
105
- return type.name
234
+ return required ? type.name : `${type.name} | undefined`
106
235
  } else if (type instanceof GraphQLList) {
107
236
  return `Array<${genType(type.ofType)}>`
108
237
  } else if (type instanceof GraphQLEnumType) {
109
- return type.name
238
+ return required ? type.name : `${type.name} | undefined`
110
239
  } else {
111
240
  throw new Error('Unsupported type: ' + type)
112
241
  }
113
242
  }
114
243
 
115
- function isObject(type: GraphQLOutputType) {
116
- if (type instanceof GraphQLNonNull) {
117
- return isObject(type.ofType)
118
- } else if (type instanceof GraphQLList) {
119
- return isObject(type.ofType)
120
- }
121
- return isObjectType(type) || isInterfaceType(type)
122
- }
123
-
124
- function isList(type: GraphQLOutputType) {
244
+ function isRelationType(type: GraphQLOutputType): boolean {
125
245
  if (type instanceof GraphQLNonNull) {
126
- return isListType(type.ofType)
127
- } else {
128
- return isListType(type)
129
- }
130
- }
131
-
132
- function getElementType(type: GraphQLOutputType) {
133
- if (type instanceof GraphQLNonNull) {
134
- return getElementType(type.ofType)
246
+ return isRelationType(type.ofType)
247
+ } else if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
248
+ return true
135
249
  } else if (type instanceof GraphQLList) {
136
- return type.ofType
137
- }
138
- return type
139
- }
140
-
141
- function genField(field: GraphQLField<any, any>) {
142
- const isNonNull = field.type instanceof GraphQLNonNull
143
- const directives = field.astNode?.directives?.map((d) => '\t' + directive2decorator(d) + '\n') || []
144
-
145
- const type = genType(field.type)
146
- const returnType = isNonNull ? type : `${type} | undefined`
147
-
148
- if (isObject(field.type)) {
149
- const t = getElementType(field.type)
150
- const typeAsArg = isInterfaceType(t) ? `"${t}"` : genType(t)
151
-
152
- if (isList(field.type)) {
153
- return `${directives.join()}\tget ${field.name}(): Promise<${genType(t)}[]> { return this.getFieldObjectArray(${typeAsArg}, "${field.name}") as Promise<${genType(t)}[]> }
154
- set ${field.name}(value: ${type} | ID[]) { this.set("${field.name}", value) }
155
- get ${field.name}Ids(): ID[] { return this.get("${field.name}") }`
156
- }
157
-
158
- return `${directives.join()}\tget ${field.name}(): Promise<${genType(t)} | undefined> { return this.getFieldObject(${typeAsArg},"${field.name}") as Promise<${genType(t)} | undefined> }
159
- set ${field.name}(value: ${type} | ID) { this.set("${field.name}", value) }
160
- get ${field.name}Id(): ID | undefined { return this.get("${field.name}") }`
161
- }
162
-
163
- if (returnType == 'BigInt') {
164
- return `${directives.join()}\tget ${field.name}(): bigint { return BigInt(this.get("${field.name}")) }
165
- set ${field.name}(value: ${type}) { this.set("${field.name}", value.toString()) }`
166
- }
167
- if (returnType == 'BigDecimal') {
168
- return `${directives.join()}\tget ${field.name}(): ${returnType} { return new BigDecimal(this.get("${field.name}")) }
169
- set ${field.name}(value: ${type}) { this.set("${field.name}", value.toString()) }`
170
- }
171
-
172
- if (returnType == 'Bytes') {
173
- return `${directives.join()}\tget ${field.name}(): ${returnType} { return Uint8Array.from(Buffer.from(this.get<string>("${field.name}"), 'hex')) ) }
174
- set ${field.name}(value: ${type}) { this.set("${field.name}", Buffer.from(value).toString('hex')) }`
175
- }
176
-
177
- return `${directives.join()}\tget ${field.name}(): ${returnType} { return this.get("${field.name}") }
178
- set ${field.name}(value: ${type}) { this.set("${field.name}", value) }`
179
- }
180
-
181
- function genDataType(t: GraphQLObjectType<any, any>) {
182
- let output = `type ${t.name}Data = `
183
- const relationsFields = Object.values(t.getFields()).filter((f) => isObject(f.type))
184
- if (relationsFields.length > 0) {
185
- output += `Omit<${t.name}, ${relationsFields.map((f) => `"${f.name}"`).join(' | ')}>`
186
-
187
- output +=
188
- ' & {' +
189
- relationsFields
190
- .map((f) => {
191
- const type = genType(getElementType(f.type))
192
- return `${f.name}?: ${isList(f.type) ? `Array<ID|${type}>` : `ID | ${type}`}`
193
- })
194
- .join(', ') +
195
- '}'
250
+ return isRelationType(type.ofType)
196
251
  } else {
197
- output += `${t.name}`
198
- }
199
- return output
200
- }
201
-
202
- function genEntity(t: GraphQLObjectType<any, any>) {
203
- const decorators = t.astNode?.directives?.filter((d) => d.name.value != 'entity').map(directive2decorator) || []
204
-
205
- let impls = ''
206
- if (t.getInterfaces().length > 0) {
207
- impls +=
208
- ' implements ' +
209
- t
210
- .getInterfaces()
211
- .map((i) => i.name)
212
- .join(', ')
213
- }
214
-
215
- return `
216
- ${genDataType(t)}
217
- ${decorators.join('\n')}
218
- @entity("${t.name}")
219
- export class ${t.name} extends Entity${impls} {
220
- constructor(data: Partial<${t.name}Data>) {
221
- super(data)
252
+ return false
222
253
  }
223
- ${Object.values(t.getFields()).map(genField).join('\n')}
224
- }`
225
- }
226
-
227
- function genInterface(t: GraphQLInterfaceType) {
228
- return `
229
- export interface ${t.name} {
230
- ${Object.values(t.getFields())
231
- .map((f) => `\t${f.name}: ${genType(f.type)}`)
232
- .join('\n')}
233
- }`
234
- }
235
-
236
- export function directive2decorator(directive: DirectiveNode) {
237
- let s = `@${directive.name.value}`
238
- if (directive.arguments?.length) {
239
- s += `(${directive.arguments
240
- ?.map((arg) => {
241
- return arg.value.kind === Kind.STRING ? `"${arg.value.value}"` : `${arg.value}`
242
- })
243
- .join(', ')})`
244
- }
245
- return s
246
- }
247
-
248
- function genEnum(t: GraphQLEnumType) {
249
- return `
250
- export enum ${t.name} {
251
- ${t
252
- .getValues()
253
- .map((v) => `\t${v.name}`)
254
- .join(', ')}
255
- }`
256
254
  }