@sentio/cli 1.0.0

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 (69) hide show
  1. package/lib/build.d.ts +2 -0
  2. package/lib/build.js +78 -0
  3. package/lib/build.js.map +1 -0
  4. package/lib/cli +47 -0
  5. package/lib/cli.d.ts +2 -0
  6. package/lib/cli.js +186 -0
  7. package/lib/cli.js.map +1 -0
  8. package/lib/commands/login-server.d.ts +7 -0
  9. package/lib/commands/login-server.js +133 -0
  10. package/lib/commands/login-server.js.map +1 -0
  11. package/lib/commands/run-create.d.ts +1 -0
  12. package/lib/commands/run-create.js +111 -0
  13. package/lib/commands/run-create.js.map +1 -0
  14. package/lib/commands/run-login.d.ts +1 -0
  15. package/lib/commands/run-login.js +136 -0
  16. package/lib/commands/run-login.js.map +1 -0
  17. package/lib/commands/run-version.d.ts +1 -0
  18. package/lib/commands/run-version.js +39 -0
  19. package/lib/commands/run-version.js.map +1 -0
  20. package/lib/config.d.ts +14 -0
  21. package/lib/config.js +64 -0
  22. package/lib/config.js.map +1 -0
  23. package/lib/key.d.ts +2 -0
  24. package/lib/key.js +44 -0
  25. package/lib/key.js.map +1 -0
  26. package/lib/upload.d.ts +2 -0
  27. package/lib/upload.js +189 -0
  28. package/lib/upload.js.map +1 -0
  29. package/lib/utils.d.ts +1 -0
  30. package/lib/utils.js +16 -0
  31. package/lib/utils.js.map +1 -0
  32. package/package.json +64 -0
  33. package/src/build.ts +93 -0
  34. package/src/cli.ts +184 -0
  35. package/src/commands/login-server.ts +119 -0
  36. package/src/commands/run-create.ts +116 -0
  37. package/src/commands/run-login.ts +111 -0
  38. package/src/commands/run-version.ts +32 -0
  39. package/src/config.ts +72 -0
  40. package/src/key.ts +43 -0
  41. package/src/upload.ts +214 -0
  42. package/src/utils.ts +10 -0
  43. package/src/webpack.config.js +47 -0
  44. package/templates/aptos/.gitignore +107 -0
  45. package/templates/aptos/abis/aptos/souffle.json +389 -0
  46. package/templates/aptos/jest.config.js +7 -0
  47. package/templates/aptos/package.json +20 -0
  48. package/templates/aptos/sentio.yaml +1 -0
  49. package/templates/aptos/src/processor.test.ts +14 -0
  50. package/templates/aptos/src/processor.ts +13 -0
  51. package/templates/aptos/tsconfig.json +20 -0
  52. package/templates/evm/.gitignore +107 -0
  53. package/templates/evm/abis/evm/x2y2.json +296 -0
  54. package/templates/evm/jest.config.js +7 -0
  55. package/templates/evm/package.json +20 -0
  56. package/templates/evm/sentio.yaml +3 -0
  57. package/templates/evm/src/processor.test.ts +29 -0
  58. package/templates/evm/src/processor.ts +29 -0
  59. package/templates/evm/tsconfig.json +20 -0
  60. package/templates/raw/.gitignore +107 -0
  61. package/templates/raw/jest.config.js +7 -0
  62. package/templates/raw/package.json +20 -0
  63. package/templates/raw/sentio.yaml +3 -0
  64. package/templates/raw/src/processor.test.ts +14 -0
  65. package/templates/raw/src/processor.ts +0 -0
  66. package/templates/raw/tsconfig.json +20 -0
  67. package/templates/raw/yarn.lock +4095 -0
  68. package/tsconfig.json +13 -0
  69. package/yarn.lock +7037 -0
@@ -0,0 +1,32 @@
1
+ import commandLineArgs from 'command-line-args'
2
+ import commandLineUsage from 'command-line-usage'
3
+ import { getCliVersion } from '../utils'
4
+
5
+ export function runVersion(argv: string[]) {
6
+ const optionDefinitions = [
7
+ {
8
+ name: 'help',
9
+ alias: 'h',
10
+ type: Boolean,
11
+ description: 'Display this usage guide.',
12
+ },
13
+ ]
14
+ const options = commandLineArgs(optionDefinitions, { argv })
15
+
16
+ if (options.help) {
17
+ const usage = commandLineUsage([
18
+ {
19
+ header: 'Show current version',
20
+ content: 'sentio version',
21
+ },
22
+ {
23
+ header: 'Options',
24
+ optionList: optionDefinitions,
25
+ },
26
+ ])
27
+ console.log(usage)
28
+ } else {
29
+ console.log('CLI Version: ', getCliVersion())
30
+ // TODO show SDK version for current package
31
+ }
32
+ }
package/src/config.ts ADDED
@@ -0,0 +1,72 @@
1
+ const HostMap: { [host: string]: string } = {
2
+ local: 'http://localhost:10000',
3
+ test: 'https://test.sentio.xyz',
4
+ staging: 'https://staging.sentio.xyz',
5
+ prod: 'https://app.sentio.xyz',
6
+ }
7
+
8
+ export interface SentioProjectConfig {
9
+ project: string
10
+ host: string
11
+ // source: string
12
+ build: boolean
13
+ // targets: Target[]
14
+ debug: boolean
15
+ }
16
+
17
+ export function getFinalizedHost(host: string): string {
18
+ if (host === undefined || host === '') {
19
+ host = 'prod'
20
+ }
21
+ return HostMap[host] ?? host
22
+ }
23
+
24
+ export function getAuthConfig(host: string): { domain: string; clientId: string; audience: string } {
25
+ let domain = '',
26
+ clientId = '',
27
+ audience = ''
28
+ switch (host) {
29
+ case HostMap['local']:
30
+ domain = 'https://sentio-dev.us.auth0.com'
31
+ clientId = 'qGDisObqQbcPeRA8k02POPZ2Df4KVCna'
32
+ audience = 'http://localhost:8080/v1'
33
+ break
34
+ case HostMap['prod']:
35
+ domain = 'https://auth.sentio.xyz'
36
+ clientId = 'xd80PeuvuZVHpBFh7yEdlSZdtE5mTpGe'
37
+ audience = 'https://app.sentio.xyz/api/v1'
38
+ break
39
+ case HostMap['test']:
40
+ case HostMap['staging']:
41
+ domain = 'https://auth.test.sentio.xyz'
42
+ clientId = 'qXVvovHaOE37SndxTZJxCKgZjw1axPax'
43
+ audience = 'https://test.sentio.xyz/api/v1'
44
+ break
45
+ default:
46
+ break
47
+ }
48
+ return { domain, clientId, audience }
49
+ }
50
+
51
+ export function finalizeHost(config: SentioProjectConfig) {
52
+ config.host = getFinalizedHost(config.host)
53
+ }
54
+
55
+ export function FinalizeProjectName(config: SentioProjectConfig, owner: string | undefined) {
56
+ if (owner) {
57
+ let name = config.project
58
+ if (name.includes('/')) {
59
+ name = config.project.split('/')[1]
60
+ }
61
+ config.project = [owner, name].join('/')
62
+ }
63
+ }
64
+
65
+ // export interface Target {
66
+ // chain: string
67
+ // abisDir?: string
68
+ // }
69
+ //
70
+ // // Supported target chain, lower case
71
+ // export const EVM = 'evm'
72
+ // export const SOLANA = 'solana'
package/src/key.ts ADDED
@@ -0,0 +1,43 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import os from 'os'
4
+
5
+ const homeDir = os.homedir()
6
+ const sentioDir = path.join(homeDir, '.sentio')
7
+ const configFile = path.join(sentioDir, 'config.json')
8
+
9
+ interface SentioKeyConfig {
10
+ [key: string]: {
11
+ api_keys: string
12
+ }
13
+ }
14
+
15
+ export function WriteKey(host: string, api_key: string) {
16
+ const sentioDir = path.join(homeDir, '.sentio')
17
+ if (!fs.existsSync(sentioDir)) {
18
+ fs.mkdirSync(sentioDir, { recursive: true })
19
+ }
20
+ let config: SentioKeyConfig = {}
21
+ if (fs.existsSync(configFile)) {
22
+ const content = fs.readFileSync(configFile, 'utf8')
23
+ config = JSON.parse(content)
24
+ }
25
+ const hostConfig = config[host] || { api_keys: {} }
26
+ hostConfig.api_keys = api_key
27
+ config[host] = hostConfig
28
+ fs.writeFileSync(configFile, JSON.stringify(config, null, 2))
29
+ }
30
+
31
+ export function ReadKey(host: string): string | undefined {
32
+ if (!fs.existsSync(sentioDir)) {
33
+ return undefined
34
+ }
35
+ const configFile = path.join(sentioDir, 'config.json')
36
+ if (fs.existsSync(configFile)) {
37
+ const content = fs.readFileSync(configFile, 'utf8')
38
+ const config = JSON.parse(content)
39
+ return config[host]?.api_keys
40
+ } else {
41
+ return undefined
42
+ }
43
+ }
package/src/upload.ts ADDED
@@ -0,0 +1,214 @@
1
+ import { execSync } from 'child_process'
2
+ import { createHash } from 'crypto'
3
+ import fs from 'fs'
4
+ import readline from 'readline'
5
+ import { SentioProjectConfig } from './config'
6
+ import { ReadKey } from './key'
7
+ import path from 'path'
8
+ import chalk from 'chalk'
9
+ import { buildProcessor } from './build'
10
+ import fetch from 'node-fetch'
11
+ import { getCliVersion } from './utils'
12
+ import { URL } from 'url'
13
+
14
+ async function createProject(options: SentioProjectConfig, apiKey: string) {
15
+ const url = new URL('/api/v1/projects', options.host)
16
+ const [ownerName, slug] = options.project.includes('/') ? options.project.split('/') : [undefined, options.project]
17
+ return fetch(url, {
18
+ method: 'POST',
19
+ headers: {
20
+ 'api-key': apiKey,
21
+ },
22
+ body: JSON.stringify({ slug, ownerName, visibility: 'PRIVATE' }),
23
+ })
24
+ }
25
+
26
+ export async function uploadFile(options: SentioProjectConfig, apiKeyOverride: string) {
27
+ if (options.build) {
28
+ await buildProcessor(false)
29
+ }
30
+
31
+ console.log(chalk.blue('Prepare to upload'))
32
+
33
+ const PROCESSOR_FILE = path.join(process.cwd(), 'dist/lib.js')
34
+
35
+ const apiKey = apiKeyOverride || ReadKey(options.host)
36
+
37
+ const isProd = options.host === 'https://app.sentio.xyz'
38
+ if (!apiKey) {
39
+ const cmd = isProd ? 'sentio login' : 'sentio login --host=' + options.host
40
+ console.error(chalk.red('No Credential found for', options.host, '. Please run `' + cmd + '`.'))
41
+ process.exit(1)
42
+ }
43
+
44
+ if (!fs.existsSync(PROCESSOR_FILE)) {
45
+ console.error(chalk.red('File not existed ', PROCESSOR_FILE, "don't use --nobuild"))
46
+ process.exit(1)
47
+ }
48
+
49
+ const stat = fs.statSync(PROCESSOR_FILE)
50
+ console.log('Packed processor file size', Math.floor(stat.size / 1024) + 'K, last modified', stat.mtime)
51
+ const content = fs.readFileSync(PROCESSOR_FILE)
52
+ const hash = createHash('sha256')
53
+ hash.update(content)
54
+ const digest = hash.digest('hex')
55
+
56
+ let triedCount = 0
57
+ const upload = async () => {
58
+ let commitSha = ''
59
+ let gitUrl = ''
60
+ const sha256 = digest
61
+ try {
62
+ commitSha = execSync('git rev-parse HEAD').toString().trim()
63
+ } catch (e) {
64
+ chalk.yellow(e)
65
+ }
66
+ try {
67
+ gitUrl = execSync('git remote get-url origin').toString().trim()
68
+ } catch (e) {
69
+ // skip errors
70
+ }
71
+ console.log(chalk.blue(triedCount > 1 ? 'Retry uploading' : 'Uploading'))
72
+
73
+ // get gcs upload url
74
+ const initUploadResRaw = await initUpload(options.host, apiKey, options.project, getCliVersion())
75
+ if (!initUploadResRaw.ok) {
76
+ console.error(chalk.red('Failed to get upload url'))
77
+ console.error(chalk.red((await initUploadResRaw.json()).message))
78
+
79
+ if (initUploadResRaw.status === 404) {
80
+ // create project if not exist
81
+ const rl = readline.createInterface({
82
+ input: process.stdin,
83
+ output: process.stdout,
84
+ })
85
+ const prompt = async () => {
86
+ const answer: string = await new Promise((resolve) =>
87
+ rl.question(`Do you want to create it and continue the uploading process? (yes/no) `, resolve)
88
+ )
89
+ if (['y', 'yes'].includes(answer.toLowerCase())) {
90
+ rl.close()
91
+ const res = await createProject(options, apiKey)
92
+ if (!res.ok) {
93
+ console.error(chalk.red('Create Project Failed'))
94
+ console.error(chalk.red((await res.json()).message))
95
+ return
96
+ }
97
+ console.log(chalk.green('Project created'))
98
+ await upload()
99
+ } else if (['n', 'no'].includes(answer.toLowerCase())) {
100
+ rl.close()
101
+ } else {
102
+ await prompt()
103
+ }
104
+ }
105
+ await prompt()
106
+ }
107
+ return
108
+ }
109
+ const initUploadRes = await initUploadResRaw.json()
110
+ const uploadUrl = initUploadRes['url'] as string
111
+
112
+ // do actual uploading
113
+ const file = fs.createReadStream(PROCESSOR_FILE)
114
+ const uploadResRaw = await fetch(uploadUrl, {
115
+ method: 'PUT',
116
+ headers: {
117
+ 'Content-Type': 'application/octet-stream',
118
+ },
119
+ body: file,
120
+ })
121
+ if (!uploadResRaw.ok) {
122
+ console.error(chalk.red('Failed to upload'))
123
+ console.error(chalk.red(await uploadResRaw.text()))
124
+ return
125
+ }
126
+
127
+ // finish uploading
128
+ const finishUploadResRaw = await finishUpload(
129
+ options.host,
130
+ apiKey,
131
+ options.project,
132
+ getCliVersion(),
133
+ sha256,
134
+ commitSha,
135
+ gitUrl,
136
+ options.debug
137
+ )
138
+ if (!finishUploadResRaw.ok) {
139
+ console.error(chalk.red('Failed to finish uploading'))
140
+ console.error(chalk.red(await finishUploadResRaw.text()))
141
+ return
142
+ }
143
+
144
+ console.log(chalk.green('Upload success: '))
145
+ console.log('\t', chalk.blue('sha256:'), digest)
146
+ if (commitSha) {
147
+ console.log('\t', chalk.blue('Git commit SHA:'), commitSha)
148
+ }
149
+ const { projectFullSlug } = await finishUploadResRaw.json()
150
+ console.log('\t', chalk.blue('Check status:'), `${options.host}/${projectFullSlug}/datasource`)
151
+ }
152
+
153
+ let error: Error
154
+ const tryUploading = async () => {
155
+ if (triedCount++ >= 5) {
156
+ console.error(error)
157
+ return
158
+ }
159
+ try {
160
+ await upload()
161
+ } catch (e) {
162
+ if (e.constructor.name === 'FetchError' && e.type === 'system' && e.code === 'EPIPE') {
163
+ error = e
164
+ await new Promise((resolve) => setTimeout(resolve, 1000))
165
+ await tryUploading()
166
+ } else {
167
+ console.error(e)
168
+ }
169
+ }
170
+ }
171
+
172
+ await tryUploading()
173
+ }
174
+
175
+ async function initUpload(host: string, apiKey: string, projectSlug: string, sdkVersion: string) {
176
+ const initUploadUrl = new URL(`/api/v1/processors/init_upload`, host)
177
+ return fetch(initUploadUrl, {
178
+ method: 'POST',
179
+ headers: {
180
+ 'api-key': apiKey,
181
+ },
182
+ body: JSON.stringify({
183
+ project_slug: projectSlug,
184
+ sdk_version: sdkVersion,
185
+ }),
186
+ })
187
+ }
188
+
189
+ async function finishUpload(
190
+ host: string,
191
+ apiKey: string,
192
+ projectSlug: string,
193
+ sdkVersion: string,
194
+ sha256: string,
195
+ commitSha: string,
196
+ gitUrl: string,
197
+ debug: boolean
198
+ ) {
199
+ const finishUploadUrl = new URL(`/api/v1/processors/finish_upload`, host)
200
+ return fetch(finishUploadUrl, {
201
+ method: 'POST',
202
+ headers: {
203
+ 'api-key': apiKey,
204
+ },
205
+ body: JSON.stringify({
206
+ project_slug: projectSlug,
207
+ sdk_version: sdkVersion,
208
+ sha256: sha256,
209
+ commit_sha: commitSha,
210
+ git_url: gitUrl,
211
+ debug: debug,
212
+ }),
213
+ })
214
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,10 @@
1
+ import fs from 'fs-extra'
2
+ import path from 'path'
3
+
4
+ export function getCliVersion() {
5
+ const packageJsonPath = path.resolve(__dirname, '../../package.json')
6
+ const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8')
7
+ const packageJson = JSON.parse(packageJsonContent)
8
+
9
+ return packageJson.version
10
+ }
@@ -0,0 +1,47 @@
1
+ /* eslint-disable */
2
+ const path = require('path')
3
+
4
+ module.exports = {
5
+ entry: {
6
+ lib: './src/processor.ts',
7
+ },
8
+ devtool: 'inline-source-map',
9
+ module: {
10
+ rules: [
11
+ {
12
+ test: /\.tsx?$/,
13
+ use: 'ts-loader',
14
+ exclude: /node_modules/,
15
+ },
16
+ ],
17
+ },
18
+ resolve: {
19
+ extensions: ['.ts', '.js'],
20
+ },
21
+ output: {
22
+ filename: '[name].js',
23
+ path: path.resolve(process.cwd(), 'dist'),
24
+ },
25
+ target: 'node',
26
+ mode: 'production',
27
+ externals: [
28
+ {
29
+ protobufjs: 'commonjs2 protobufjs',
30
+ aptos: 'commonjs2 aptos-sdk',
31
+ ethers: 'commonjs2 ethers',
32
+ bs58: 'commonjs2 bs58',
33
+ "bignumber.js": 'commonjs2 bignumber.js',
34
+ 'bn.js': 'commonjs2 bn.js',
35
+ 'csv-parse': 'commonjs2 csv-parse',
36
+ },
37
+ function ({ context, request }, callback) {
38
+ if (/^@(ethersproject|solana|project-serum|nice-grpc).*$/.test(request)) {
39
+ return callback(null, 'commonjs ' + request)
40
+ }
41
+ if (request.startsWith("@sentio/sdk")) {
42
+ return callback(null, 'commonjs2 ' + request)
43
+ }
44
+ callback()
45
+ },
46
+ ],
47
+ }
@@ -0,0 +1,107 @@
1
+ .idea
2
+ src/types
3
+
4
+ # Logs
5
+ logs
6
+ *.log
7
+ npm-debug.log*
8
+ yarn-debug.log*
9
+ yarn-error.log*
10
+ lerna-debug.log*
11
+
12
+ # Diagnostic reports (https://nodejs.org/api/report.html)
13
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
14
+
15
+ # Runtime data
16
+ pids
17
+ *.pid
18
+ *.seed
19
+ *.pid.lock
20
+
21
+ # Directory for instrumented libs generated by jscoverage/JSCover
22
+ lib-cov
23
+
24
+ # Coverage directory used by tools like istanbul
25
+ coverage
26
+ *.lcov
27
+
28
+ # nyc test coverage
29
+ .nyc_output
30
+
31
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
32
+ .grunt
33
+
34
+ # Bower dependency directory (https://bower.io/)
35
+ bower_components
36
+
37
+ # node-waf configuration
38
+ .lock-wscript
39
+
40
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
41
+ build/Release
42
+
43
+ # Dependency directories
44
+ node_modules/
45
+ jspm_packages/
46
+
47
+ # TypeScript v1 declaration files
48
+ typings/
49
+
50
+ # TypeScript cache
51
+ *.tsbuildinfo
52
+
53
+ # Optional npm cache directory
54
+ .npm
55
+
56
+ # Optional eslint cache
57
+ .eslintcache
58
+
59
+ # Microbundle cache
60
+ .rpt2_cache/
61
+ .rts2_cache_cjs/
62
+ .rts2_cache_es/
63
+ .rts2_cache_umd/
64
+
65
+ # Optional REPL history
66
+ .node_repl_history
67
+
68
+ # Output of 'npm pack'
69
+ *.tgz
70
+
71
+ # Yarn Integrity file
72
+ .yarn-integrity
73
+
74
+ # dotenv environment variables file
75
+ .env
76
+ .env.test
77
+
78
+ # parcel-bundler cache (https://parceljs.org/)
79
+ .cache
80
+
81
+ # Next.js build output
82
+ .next
83
+
84
+ # Nuxt.js build / generate output
85
+ .nuxt
86
+ dist
87
+
88
+ # Gatsby files
89
+ .cache/
90
+ # Comment in the public line in if your project uses Gatsby and *not* Next.js
91
+ # https://nextjs.org/blog/next-9-1#public-directory-support
92
+ # public
93
+
94
+ # vuepress build output
95
+ .vuepress/dist
96
+
97
+ # Serverless directories
98
+ .serverless/
99
+
100
+ # FuseBox cache
101
+ .fusebox/
102
+
103
+ # DynamoDB Local files
104
+ .dynamodb/
105
+
106
+ # TernJS port file
107
+ .tern-port