create-eclesia-indexer 1.1.0 → 1.2.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.
- package/dist/index.cjs +4 -0
- package/dist/{index.js → index.mjs} +5 -1
- package/dist/index.mjs.map +1 -0
- package/package.json +26 -10
- package/templates/basic/docker-compose.yml.template +2 -1
- package/templates/basic/tsconfig.json.template +2 -2
- package/templates/basic/tsdown.config.ts +2 -2
- package/dist/index.js.map +0 -1
- /package/dist/{index.d.ts → index.d.mts} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -255,6 +255,8 @@ async function copyTemplateFiles(config, targetDir) {
|
|
|
255
255
|
}
|
|
256
256
|
async function processTemplates(config, targetDir) {
|
|
257
257
|
let polling = false;
|
|
258
|
+
config.enableHealthcheck = false;
|
|
259
|
+
config.healthCheckPort = 8888;
|
|
258
260
|
config.enablePrometheus = false;
|
|
259
261
|
config.prometheusPort = 9090;
|
|
260
262
|
const url = new URL(config.rpcEndpoint);
|
|
@@ -273,6 +275,8 @@ async function processTemplates(config, targetDir) {
|
|
|
273
275
|
MINIMAL: config.minimal ? "true" : "false",
|
|
274
276
|
START_HEIGHT: config.startHeight.toString(),
|
|
275
277
|
CHAIN_PREFIX: config.chainPrefix,
|
|
278
|
+
ENABLE_HEALTHCHECK: config.enableHealthcheck ? "true" : "false",
|
|
279
|
+
HEALTH_CHECK_PORT: config.healthCheckPort.toString(),
|
|
276
280
|
ENABLE_PROMETHEUS: config.enablePrometheus ? "true" : "false",
|
|
277
281
|
PROMETHEUS_PORT: config.prometheusPort.toString(),
|
|
278
282
|
MODULES_IMPORT: generateModulesImport(config),
|
|
@@ -228,6 +228,8 @@ async function copyTemplateFiles(config, targetDir) {
|
|
|
228
228
|
}
|
|
229
229
|
async function processTemplates(config, targetDir) {
|
|
230
230
|
let polling = false;
|
|
231
|
+
config.enableHealthcheck = false;
|
|
232
|
+
config.healthCheckPort = 8888;
|
|
231
233
|
config.enablePrometheus = false;
|
|
232
234
|
config.prometheusPort = 9090;
|
|
233
235
|
const url = new URL(config.rpcEndpoint);
|
|
@@ -246,6 +248,8 @@ async function processTemplates(config, targetDir) {
|
|
|
246
248
|
MINIMAL: config.minimal ? "true" : "false",
|
|
247
249
|
START_HEIGHT: config.startHeight.toString(),
|
|
248
250
|
CHAIN_PREFIX: config.chainPrefix,
|
|
251
|
+
ENABLE_HEALTHCHECK: config.enableHealthcheck ? "true" : "false",
|
|
252
|
+
HEALTH_CHECK_PORT: config.healthCheckPort.toString(),
|
|
249
253
|
ENABLE_PROMETHEUS: config.enablePrometheus ? "true" : "false",
|
|
250
254
|
PROMETHEUS_PORT: config.prometheusPort.toString(),
|
|
251
255
|
MODULES_IMPORT: generateModulesImport(config),
|
|
@@ -353,4 +357,4 @@ main().catch((error) => {
|
|
|
353
357
|
|
|
354
358
|
//#endregion
|
|
355
359
|
export { };
|
|
356
|
-
//# sourceMappingURL=index.
|
|
360
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["imports: string[]","instantiations: string[]","moduleNames: string[]"],"sources":["../src/create-indexer.ts","../src/index.ts"],"sourcesContent":["import enquirer from \"enquirer\";\nconst {\n prompt,\n} = enquirer;\nimport fse from \"fs-extra\";\nconst {\n ensureDirSync, copySync, writeFileSync, readFileSync,\n} = fse;\nimport path, {\n resolve,\n} from \"node:path\";\nimport {\n dirname,\n} from \"node:path\";\nimport {\n fileURLToPath,\n} from \"node:url\";\n\nimport colors from \"picocolors\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface ProjectConfig {\n projectName: string\n chainName: string\n description: string\n rpcEndpoint: string\n chainPrefix: string\n minimal: boolean\n startHeight: number\n queueSize: number\n logLevel: string\n processGenesis: boolean\n genesisPath: string | null\n enableHealthcheck: boolean\n healthCheckPort: number\n enablePrometheus: boolean\n prometheusPort: number\n modules: string[]\n packageManager: \"npm\" | \"yarn\" | \"pnpm\"\n}\n\nconst availableModules = [\n {\n name: \"Auth\",\n value: \"auth\",\n hint: \"Account and authentication data\",\n },\n {\n name: \"Bank\",\n value: \"bank\",\n hint: \"Token transfers and balances\",\n },\n {\n name: \"Staking\",\n value: \"staking\",\n hint: \"Validator and delegation data\",\n },\n];\n\nconst minimalAvailableModules = [\n {\n name: \"Auth\",\n value: \"auth\",\n hint: \"Account and authentication data\",\n },\n {\n name: \"Bank\",\n value: \"bank\",\n hint: \"Token transfers and balances\",\n },\n];\n\nexport async function createIndexer(initialProjectName?: string): Promise<void> {\n const config = await gatherProjectInfo(initialProjectName);\n const targetDir = resolve(process.cwd(), config.projectName);\n\n console.log(colors.blue(\"📁 Creating project directory...\"));\n ensureDirSync(targetDir);\n\n console.log(colors.blue(\"📋 Copying files...\"));\n await copyTemplateFiles(config, targetDir);\n\n console.log(colors.blue(\"🔧 Processing template variables...\"));\n await processTemplates(config, targetDir);\n\n console.log(colors.blue(\"📦 Installing dependencies...\"));\n await installDependencies(config, targetDir);\n\n console.log(colors.blue(\"📦 Building...\"));\n await buildProject(config, targetDir);\n\n console.log();\n console.log(colors.green(\"🎉 Your indexer is ready!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(colors.cyan(` cd ${config.projectName}`));\n console.log(colors.cyan(` ${config.packageManager} local-dev:start # To run a self-contained local development environment with Postgres`));\n console.log();\n console.log(\"If you want to run the indexer against an external Postgres database instead of the local development environment, set the database connection string in the .env file.\");\n console.log();\n console.log(colors.cyan(` ${config.packageManager} start # To run the indexer`));\n console.log();\n console.log(\"Happy indexing!\");\n console.log();\n}\n\nasync function gatherProjectInfo(initialProjectName?: string): Promise<ProjectConfig> {\n const questions1 = [\n {\n type: \"input\",\n name: \"projectName\",\n message: \"Project name:\",\n initial: initialProjectName || \"my-indexer\",\n skip: !!initialProjectName,\n },\n {\n type: \"input\",\n name: \"chainName\",\n message: \"Chain name:\",\n initial: \"cosmos-hub\",\n },\n {\n type: \"input\",\n name: \"chainPrefix\",\n message: \"Chain address prefix:\",\n initial: \"cosmos\",\n },\n {\n type: \"input\",\n name: \"description\",\n message: \"Description:\",\n initial: \"A custom Cosmos SDK chain indexer\",\n },\n {\n type: \"input\",\n name: \"rpcEndpoint\",\n message: \"RPC endpoint:\",\n initial: \"https://rpc.cosmos.network\",\n validate: (value: string) => {\n try {\n const url = new URL(value);\n if (url.protocol === \"http:\" || url.protocol === \"https:\" || url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return true;\n }\n return \"Please enter a valid HTTP/HTTPS/WS/WSS URL.\";\n }\n catch (err) {\n return \"Please enter a valid URL: \" + err;\n }\n },\n },\n {\n type: \"toggle\",\n name: \"minimal\",\n message: \"Minimal block indexing? (Only stores heights)\",\n enabled: \"Yes\",\n disabled: \"No\",\n initial: false,\n },\n {\n type: \"number\",\n name: \"queueSize\",\n message: \"Number of blocks to keep prefetched (queue size):\",\n initial: 200,\n },\n {\n type: \"number\",\n name: \"startHeight\",\n message: \"Height to start indexing from (>1 not compatible with standard modules):\",\n initial: 1,\n },\n ];\n const answers1 = await prompt(questions1) as ProjectConfig;\n if (answers1.startHeight == 1) {\n const genesisQuestion = await prompt([\n {\n type: \"toggle\",\n name: \"processGenesis\",\n message: \"Process genesis file?\",\n enabled: \"Yes\",\n disabled: \"No\",\n },\n ]) as ProjectConfig;\n answers1.processGenesis = genesisQuestion.processGenesis;\n }\n else {\n answers1.processGenesis = false;\n }\n if (answers1.processGenesis) {\n const genesisPathQuestion = await prompt([\n {\n type: \"input\",\n name: \"genesisPath\",\n message: \"Path to genesis file:\",\n initial: \"./genesis.json\",\n validate: (value: string) => {\n try {\n fse.accessSync(value, fse.constants.R_OK);\n return true;\n }\n catch (err) {\n return \"File not found or not readable. Please enter a valid path: \" + err;\n }\n },\n },\n ]) as ProjectConfig;\n answers1.genesisPath = genesisPathQuestion.genesisPath ? path.resolve(genesisPathQuestion.genesisPath) : null;\n }\n else {\n answers1.genesisPath = null;\n }\n const questions2 = [\n {\n type: \"multiselect\",\n name: \"modules\",\n message: \"Select modules to include:\",\n choices: answers1.startHeight == 1 && !answers1.minimal && answers1.processGenesis ? availableModules : minimalAvailableModules,\n initial: answers1.startHeight == 1 && !answers1.minimal && answers1.processGenesis ? [0, 1, 2] : [0, 1],\n },\n {\n type: \"select\",\n name: \"packageManager\",\n message: \"Package manager:\",\n choices: [\n {\n name: \"pnpm\",\n hint: \"recommended\",\n },\n {\n name: \"npm\",\n },\n {\n name: \"yarn\",\n },\n ],\n initial: 0,\n },\n {\n type: \"select\",\n name: \"logLevel\",\n message: \"Log level:\",\n choices: [\"error\", \"warn\", \"info\", \"verbose\", \"debug\", \"silly\"],\n initial: 4,\n },\n ];\n const answers2 = await prompt(questions2) as ProjectConfig;\n return {\n ...answers1,\n ...answers2,\n };\n}\n\nasync function copyTemplateFiles(config: ProjectConfig, targetDir: string): Promise<void> {\n const templatesDir = resolve(__dirname, \"..\", \"templates\", \"basic\");\n if (config.genesisPath) {\n console.log(colors.blue(\"📋 Copying genesis file...\"));\n copySync(config.genesisPath, targetDir + \"/genesis.json\");\n }\n\n console.log(colors.blue(\"📋 Copying template files...\"));\n copySync(templatesDir, targetDir, {\n filter: (src) => {\n if (src.includes(\".template\")) {\n return false;\n }\n if (config.packageManager !== \"pnpm\" && src.includes(\"pnpm-workspace\")) {\n return false;\n }\n if (src.includes(\"Dockerfile\")) {\n return false;\n }\n return true;\n },\n });\n copySync(resolve(templatesDir, \"Dockerfile.\" + config.packageManager), targetDir + \"/Dockerfile\");\n // Copy template files\n const templateFiles = [\"package.json.template\", \"src/index.ts.template\", \"tsconfig.json.template\", \"docker-compose.yml.template\", \"README.md.template\", \".env.template\"];\n\n templateFiles.forEach((templateFile) => {\n const srcPath = resolve(templatesDir, templateFile);\n const destPath = resolve(targetDir, templateFile.replace(\".template\", \"\"));\n\n try {\n copySync(srcPath, destPath);\n }\n catch (_error) {\n // Template file might not exist, that's okay\n }\n });\n}\n\nasync function processTemplates(config: ProjectConfig, targetDir: string): Promise<void> {\n let polling = false;\n config.enableHealthcheck = false;\n config.healthCheckPort = 8888;\n config.enablePrometheus = false;\n config.prometheusPort = 9090;\n const url = new URL(config.rpcEndpoint);\n if (url.protocol === \"http:\" || url.protocol === \"https:\") {\n polling = true;\n }\n const templateVars = {\n PROJECT_NAME: config.projectName,\n CHAIN_NAME: config.chainName,\n DESCRIPTION: config.description,\n RPC_ENDPOINT: config.rpcEndpoint,\n PG_CONNECTION_STRING: \"postgres://postgres:password@postgres:5432/indexer\",\n LOG_LEVEL: config.logLevel,\n QUEUE_SIZE: config.queueSize.toString(),\n USE_POLLING: polling ? \"true\" : \"false\",\n PROCESS_GENESIS: config.processGenesis + \"\",\n GENESIS_PATH: path.resolve(targetDir, \"genesis.json\"),\n MINIMAL: config.minimal ? \"true\" : \"false\",\n START_HEIGHT: config.startHeight.toString(),\n CHAIN_PREFIX: config.chainPrefix,\n ENABLE_HEALTHCHECK: config.enableHealthcheck ? \"true\" : \"false\",\n HEALTH_CHECK_PORT: config.healthCheckPort.toString(),\n ENABLE_PROMETHEUS: config.enablePrometheus ? \"true\" : \"false\",\n PROMETHEUS_PORT: config.prometheusPort.toString(),\n MODULES_IMPORT: generateModulesImport(config),\n PACKAGE_MANAGER: config.packageManager,\n MODULES_INSTANTIATION: generateModulesInstantiation(config),\n MODULES_ARRAY: generateModulesArray(config),\n };\n\n const filesToProcess = [\"package.json\", \"src/index.ts\", \"tsconfig.json\", \"docker-compose.yml\", \"README.md\", \"pnpm-workspace.yaml\", \".env\"];\n\n filesToProcess.forEach((file) => {\n const filePath = resolve(targetDir, file);\n\n try {\n let content = readFileSync(filePath, \"utf-8\");\n\n Object.entries(templateVars).forEach(([key, value]) => {\n const regex = new RegExp(`{{${key}}}`, \"g\");\n content = content.replace(regex, value);\n });\n\n writeFileSync(filePath, content);\n }\n catch (_error) {\n // File might not exist, that's okay\n }\n });\n}\n\nfunction generateModulesImport(config: ProjectConfig): string {\n const imports: string[] = [];\n\n imports.push(\" Blocks\");\n if (config.modules.includes(\"Auth\")) {\n imports.push(\" AuthModule\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n imports.push(\" BankModule\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n imports.push(\" StakingModule\");\n }\n\n return `import {\\n${imports.join(\",\")}\\n} from \"@eclesia/core-modules-pg\";\\n`;\n}\n\nfunction generateModulesInstantiation(config: ProjectConfig): string {\n const instantiations: string[] = [];\n\n if (config.minimal) {\n instantiations.push(\"const blocksModule = new Blocks.MinimalBlocksModule(registry);\");\n }\n else {\n instantiations.push(\"const blocksModule = new Blocks.FullBlocksModule(registry);\");\n }\n if (config.modules.includes(\"Auth\")) {\n instantiations.push(\"const authModule = new AuthModule(registry);\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n instantiations.push(\"const bankModule = new BankModule(registry);\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n instantiations.push(\"const stakingModule = new StakingModule(registry);\");\n }\n\n return instantiations.join(\"\\n\");\n}\n\nfunction generateModulesArray(config: ProjectConfig): string {\n const moduleNames: string[] = [];\n\n moduleNames.push(\"blocksModule\");\n\n if (config.modules.includes(\"Auth\")) {\n moduleNames.push(\"authModule\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n moduleNames.push(\"bankModule\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n moduleNames.push(\"stakingModule\");\n }\n return `[${moduleNames.filter(m => !m.includes(\"//\")).join(\", \")}]`;\n}\n\nasync function installDependencies(config: ProjectConfig, targetDir: string): Promise<void> {\n const {\n spawn,\n } = await import(\"node:child_process\");\n\n return new Promise((resolve, reject) => {\n const child = spawn(config.packageManager, [\"install\"], {\n cwd: targetDir,\n stdio: \"inherit\",\n });\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`Package installation failed with code ${code}`));\n }\n else {\n resolve();\n }\n });\n });\n}\n\nasync function buildProject(config: ProjectConfig, targetDir: string): Promise<void> {\n const {\n spawn,\n } = await import(\"node:child_process\");\n\n return new Promise((resolve, reject) => {\n const child = spawn(config.packageManager, [\"run\", \"build\"], {\n cwd: targetDir,\n stdio: \"inherit\",\n });\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`Package installation failed with code ${code}`));\n }\n else {\n resolve();\n }\n });\n });\n}\n","import {\n existsSync,\n} from \"node:fs\";\nimport {\n dirname, resolve,\n} from \"node:path\";\nimport {\n fileURLToPath,\n} from \"node:url\";\n\nimport colors from \"picocolors\";\n\nimport {\n createIndexer,\n} from \"./create-indexer.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nasync function main() {\n console.log();\n console.log(colors.cyan(\"🚀 Welcome to create-eclesia-indexer!\"));\n console.log(colors.gray(\"Scaffolding a new Cosmos SDK chain indexer...\"));\n console.log();\n\n try {\n const projectName = process.argv[2];\n\n if (projectName && existsSync(resolve(process.cwd(), projectName))) {\n console.log(colors.red(`❌ Directory '${projectName}' already exists.`));\n process.exit(1);\n }\n\n await createIndexer(projectName);\n\n console.log();\n console.log(colors.green(\"✅ Indexer created successfully!\"));\n console.log();\n }\n catch (error) {\n console.error(colors.red(\"❌ Error creating indexer:\"), error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-eclesia-indexer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "CLI tool to scaffold Cosmos SDK chain indexers using eclesia-indexer-core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"enquirer": "^2.4.1",
|
|
36
|
-
"fs-extra": "^11.2
|
|
36
|
+
"fs-extra": "^11.3.2",
|
|
37
37
|
"picocolors": "^1.1.1"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
@@ -41,13 +41,29 @@
|
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/fs-extra": "^11.0.4",
|
|
44
|
-
"@types/node": "^
|
|
45
|
-
"@eslint/js": "^9.
|
|
46
|
-
"@stylistic/eslint-plugin": "^5.
|
|
47
|
-
"eslint": "^9.
|
|
44
|
+
"@types/node": "^24.10.0",
|
|
45
|
+
"@eslint/js": "^9.39.1",
|
|
46
|
+
"@stylistic/eslint-plugin": "^5.5.0",
|
|
47
|
+
"eslint": "^9.39.1",
|
|
48
48
|
"eslint-plugin-simple-import-sort": "^12.1.1",
|
|
49
|
-
"tsdown": "^0.
|
|
50
|
-
"typescript": "^5.9.
|
|
51
|
-
"typescript-eslint": "^8.
|
|
52
|
-
}
|
|
49
|
+
"tsdown": "^0.16.0",
|
|
50
|
+
"typescript": "^5.9.3",
|
|
51
|
+
"typescript-eslint": "^8.46.3"
|
|
52
|
+
},
|
|
53
|
+
"exports": {
|
|
54
|
+
".": {
|
|
55
|
+
"import": {
|
|
56
|
+
"types": "./dist/index.d.ts",
|
|
57
|
+
"default": "./dist/index.js"
|
|
58
|
+
},
|
|
59
|
+
"require": {
|
|
60
|
+
"types": "./dist/index.d.cts",
|
|
61
|
+
"default": "./dist/index.cjs"
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"./package.json": "./package.json"
|
|
65
|
+
},
|
|
66
|
+
"main": "dist/index.cjs",
|
|
67
|
+
"module": "dist/index.js",
|
|
68
|
+
"types": "dist/index.d.ts"
|
|
53
69
|
}
|
|
@@ -31,6 +31,7 @@ services:
|
|
|
31
31
|
- {{GENESIS_PATH}}:/usr/src/app/genesis.json
|
|
32
32
|
ports:
|
|
33
33
|
- "9090:9090"
|
|
34
|
+
- "8888:8888"
|
|
34
35
|
depends_on:
|
|
35
36
|
postgres:
|
|
36
37
|
condition: service_healthy
|
|
@@ -38,7 +39,7 @@ services:
|
|
|
38
39
|
graphql-engine:
|
|
39
40
|
image: hasura/graphql-engine:v2.38.0
|
|
40
41
|
ports:
|
|
41
|
-
- "
|
|
42
|
+
- "8888:8888"
|
|
42
43
|
restart: always
|
|
43
44
|
environment:
|
|
44
45
|
## postgres database to store Hasura metadata
|
|
@@ -9,7 +9,7 @@ export default defineConfig([
|
|
|
9
9
|
attw: true,
|
|
10
10
|
platform: "node",
|
|
11
11
|
nodeProtocol: "strip",
|
|
12
|
-
target: "
|
|
12
|
+
target: "es2022",
|
|
13
13
|
outDir: "./dist",
|
|
14
14
|
clean: true,
|
|
15
15
|
sourcemap: true,
|
|
@@ -21,7 +21,7 @@ export default defineConfig([
|
|
|
21
21
|
unbundle: true,
|
|
22
22
|
attw: true,
|
|
23
23
|
platform: "node",
|
|
24
|
-
target: "
|
|
24
|
+
target: "es2022",
|
|
25
25
|
outDir: "./dist",
|
|
26
26
|
clean: true,
|
|
27
27
|
sourcemap: true,
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["imports: string[]","instantiations: string[]","moduleNames: string[]"],"sources":["../src/create-indexer.ts","../src/index.ts"],"sourcesContent":["import enquirer from \"enquirer\";\nconst {\n prompt,\n} = enquirer;\nimport fse from \"fs-extra\";\nconst {\n ensureDirSync, copySync, writeFileSync, readFileSync,\n} = fse;\nimport path, {\n resolve,\n} from \"node:path\";\nimport {\n dirname,\n} from \"node:path\";\nimport {\n fileURLToPath,\n} from \"node:url\";\n\nimport colors from \"picocolors\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\ninterface ProjectConfig {\n projectName: string\n chainName: string\n description: string\n rpcEndpoint: string\n chainPrefix: string\n minimal: boolean\n startHeight: number\n queueSize: number\n logLevel: string\n processGenesis: boolean\n genesisPath: string | null\n enablePrometheus: boolean\n prometheusPort: number\n modules: string[]\n packageManager: \"npm\" | \"yarn\" | \"pnpm\"\n}\n\nconst availableModules = [\n {\n name: \"Auth\",\n value: \"auth\",\n hint: \"Account and authentication data\",\n },\n {\n name: \"Bank\",\n value: \"bank\",\n hint: \"Token transfers and balances\",\n },\n {\n name: \"Staking\",\n value: \"staking\",\n hint: \"Validator and delegation data\",\n },\n];\n\nconst minimalAvailableModules = [\n {\n name: \"Auth\",\n value: \"auth\",\n hint: \"Account and authentication data\",\n },\n {\n name: \"Bank\",\n value: \"bank\",\n hint: \"Token transfers and balances\",\n },\n];\n\nexport async function createIndexer(initialProjectName?: string): Promise<void> {\n const config = await gatherProjectInfo(initialProjectName);\n const targetDir = resolve(process.cwd(), config.projectName);\n\n console.log(colors.blue(\"📁 Creating project directory...\"));\n ensureDirSync(targetDir);\n\n console.log(colors.blue(\"📋 Copying files...\"));\n await copyTemplateFiles(config, targetDir);\n\n console.log(colors.blue(\"🔧 Processing template variables...\"));\n await processTemplates(config, targetDir);\n\n console.log(colors.blue(\"📦 Installing dependencies...\"));\n await installDependencies(config, targetDir);\n\n console.log(colors.blue(\"📦 Building...\"));\n await buildProject(config, targetDir);\n\n console.log();\n console.log(colors.green(\"🎉 Your indexer is ready!\"));\n console.log();\n console.log(\"Next steps:\");\n console.log(colors.cyan(` cd ${config.projectName}`));\n console.log(colors.cyan(` ${config.packageManager} local-dev:start # To run a self-contained local development environment with Postgres`));\n console.log();\n console.log(\"If you want to run the indexer against an external Postgres database instead of the local development environment, set the database connection string in the .env file.\");\n console.log();\n console.log(colors.cyan(` ${config.packageManager} start # To run the indexer`));\n console.log();\n console.log(\"Happy indexing!\");\n console.log();\n}\n\nasync function gatherProjectInfo(initialProjectName?: string): Promise<ProjectConfig> {\n const questions1 = [\n {\n type: \"input\",\n name: \"projectName\",\n message: \"Project name:\",\n initial: initialProjectName || \"my-indexer\",\n skip: !!initialProjectName,\n },\n {\n type: \"input\",\n name: \"chainName\",\n message: \"Chain name:\",\n initial: \"cosmos-hub\",\n },\n {\n type: \"input\",\n name: \"chainPrefix\",\n message: \"Chain address prefix:\",\n initial: \"cosmos\",\n },\n {\n type: \"input\",\n name: \"description\",\n message: \"Description:\",\n initial: \"A custom Cosmos SDK chain indexer\",\n },\n {\n type: \"input\",\n name: \"rpcEndpoint\",\n message: \"RPC endpoint:\",\n initial: \"https://rpc.cosmos.network\",\n validate: (value: string) => {\n try {\n const url = new URL(value);\n if (url.protocol === \"http:\" || url.protocol === \"https:\" || url.protocol === \"ws:\" || url.protocol === \"wss:\") {\n return true;\n }\n return \"Please enter a valid HTTP/HTTPS/WS/WSS URL.\";\n }\n catch (err) {\n return \"Please enter a valid URL: \" + err;\n }\n },\n },\n {\n type: \"toggle\",\n name: \"minimal\",\n message: \"Minimal block indexing? (Only stores heights)\",\n enabled: \"Yes\",\n disabled: \"No\",\n initial: false,\n },\n {\n type: \"number\",\n name: \"queueSize\",\n message: \"Number of blocks to keep prefetched (queue size):\",\n initial: 200,\n },\n {\n type: \"number\",\n name: \"startHeight\",\n message: \"Height to start indexing from (>1 not compatible with standard modules):\",\n initial: 1,\n },\n ];\n const answers1 = await prompt(questions1) as ProjectConfig;\n if (answers1.startHeight == 1) {\n const genesisQuestion = await prompt([\n {\n type: \"toggle\",\n name: \"processGenesis\",\n message: \"Process genesis file?\",\n enabled: \"Yes\",\n disabled: \"No\",\n },\n ]) as ProjectConfig;\n answers1.processGenesis = genesisQuestion.processGenesis;\n }\n else {\n answers1.processGenesis = false;\n }\n if (answers1.processGenesis) {\n const genesisPathQuestion = await prompt([\n {\n type: \"input\",\n name: \"genesisPath\",\n message: \"Path to genesis file:\",\n initial: \"./genesis.json\",\n validate: (value: string) => {\n try {\n fse.accessSync(value, fse.constants.R_OK);\n return true;\n }\n catch (err) {\n return \"File not found or not readable. Please enter a valid path: \" + err;\n }\n },\n },\n ]) as ProjectConfig;\n answers1.genesisPath = genesisPathQuestion.genesisPath ? path.resolve(genesisPathQuestion.genesisPath) : null;\n }\n else {\n answers1.genesisPath = null;\n }\n const questions2 = [\n {\n type: \"multiselect\",\n name: \"modules\",\n message: \"Select modules to include:\",\n choices: answers1.startHeight == 1 && !answers1.minimal && answers1.processGenesis ? availableModules : minimalAvailableModules,\n initial: answers1.startHeight == 1 && !answers1.minimal && answers1.processGenesis ? [0, 1, 2] : [0, 1],\n },\n {\n type: \"select\",\n name: \"packageManager\",\n message: \"Package manager:\",\n choices: [\n {\n name: \"pnpm\",\n hint: \"recommended\",\n },\n {\n name: \"npm\",\n },\n {\n name: \"yarn\",\n },\n ],\n initial: 0,\n },\n {\n type: \"select\",\n name: \"logLevel\",\n message: \"Log level:\",\n choices: [\"error\", \"warn\", \"info\", \"verbose\", \"debug\", \"silly\"],\n initial: 4,\n },\n ];\n const answers2 = await prompt(questions2) as ProjectConfig;\n return {\n ...answers1,\n ...answers2,\n };\n}\n\nasync function copyTemplateFiles(config: ProjectConfig, targetDir: string): Promise<void> {\n const templatesDir = resolve(__dirname, \"..\", \"templates\", \"basic\");\n if (config.genesisPath) {\n console.log(colors.blue(\"📋 Copying genesis file...\"));\n copySync(config.genesisPath, targetDir + \"/genesis.json\");\n }\n\n console.log(colors.blue(\"📋 Copying template files...\"));\n copySync(templatesDir, targetDir, {\n filter: (src) => {\n if (src.includes(\".template\")) {\n return false;\n }\n if (config.packageManager !== \"pnpm\" && src.includes(\"pnpm-workspace\")) {\n return false;\n }\n if (src.includes(\"Dockerfile\")) {\n return false;\n }\n return true;\n },\n });\n copySync(resolve(templatesDir, \"Dockerfile.\" + config.packageManager), targetDir + \"/Dockerfile\");\n // Copy template files\n const templateFiles = [\"package.json.template\", \"src/index.ts.template\", \"tsconfig.json.template\", \"docker-compose.yml.template\", \"README.md.template\", \".env.template\"];\n\n templateFiles.forEach((templateFile) => {\n const srcPath = resolve(templatesDir, templateFile);\n const destPath = resolve(targetDir, templateFile.replace(\".template\", \"\"));\n\n try {\n copySync(srcPath, destPath);\n }\n catch (_error) {\n // Template file might not exist, that's okay\n }\n });\n}\n\nasync function processTemplates(config: ProjectConfig, targetDir: string): Promise<void> {\n let polling = false;\n config.enablePrometheus = false;\n config.prometheusPort = 9090;\n const url = new URL(config.rpcEndpoint);\n if (url.protocol === \"http:\" || url.protocol === \"https:\") {\n polling = true;\n }\n const templateVars = {\n PROJECT_NAME: config.projectName,\n CHAIN_NAME: config.chainName,\n DESCRIPTION: config.description,\n RPC_ENDPOINT: config.rpcEndpoint,\n PG_CONNECTION_STRING: \"postgres://postgres:password@postgres:5432/indexer\",\n LOG_LEVEL: config.logLevel,\n QUEUE_SIZE: config.queueSize.toString(),\n USE_POLLING: polling ? \"true\" : \"false\",\n PROCESS_GENESIS: config.processGenesis + \"\",\n GENESIS_PATH: path.resolve(targetDir, \"genesis.json\"),\n MINIMAL: config.minimal ? \"true\" : \"false\",\n START_HEIGHT: config.startHeight.toString(),\n CHAIN_PREFIX: config.chainPrefix,\n ENABLE_PROMETHEUS: config.enablePrometheus ? \"true\" : \"false\",\n PROMETHEUS_PORT: config.prometheusPort.toString(),\n MODULES_IMPORT: generateModulesImport(config),\n PACKAGE_MANAGER: config.packageManager,\n MODULES_INSTANTIATION: generateModulesInstantiation(config),\n MODULES_ARRAY: generateModulesArray(config),\n };\n\n const filesToProcess = [\"package.json\", \"src/index.ts\", \"tsconfig.json\", \"docker-compose.yml\", \"README.md\", \"pnpm-workspace.yaml\", \".env\"];\n\n filesToProcess.forEach((file) => {\n const filePath = resolve(targetDir, file);\n\n try {\n let content = readFileSync(filePath, \"utf-8\");\n\n Object.entries(templateVars).forEach(([key, value]) => {\n const regex = new RegExp(`{{${key}}}`, \"g\");\n content = content.replace(regex, value);\n });\n\n writeFileSync(filePath, content);\n }\n catch (_error) {\n // File might not exist, that's okay\n }\n });\n}\n\nfunction generateModulesImport(config: ProjectConfig): string {\n const imports: string[] = [];\n\n imports.push(\" Blocks\");\n if (config.modules.includes(\"Auth\")) {\n imports.push(\" AuthModule\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n imports.push(\" BankModule\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n imports.push(\" StakingModule\");\n }\n\n return `import {\\n${imports.join(\",\")}\\n} from \"@eclesia/core-modules-pg\";\\n`;\n}\n\nfunction generateModulesInstantiation(config: ProjectConfig): string {\n const instantiations: string[] = [];\n\n if (config.minimal) {\n instantiations.push(\"const blocksModule = new Blocks.MinimalBlocksModule(registry);\");\n }\n else {\n instantiations.push(\"const blocksModule = new Blocks.FullBlocksModule(registry);\");\n }\n if (config.modules.includes(\"Auth\")) {\n instantiations.push(\"const authModule = new AuthModule(registry);\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n instantiations.push(\"const bankModule = new BankModule(registry);\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n instantiations.push(\"const stakingModule = new StakingModule(registry);\");\n }\n\n return instantiations.join(\"\\n\");\n}\n\nfunction generateModulesArray(config: ProjectConfig): string {\n const moduleNames: string[] = [];\n\n moduleNames.push(\"blocksModule\");\n\n if (config.modules.includes(\"Auth\")) {\n moduleNames.push(\"authModule\");\n }\n if (config.modules.includes(\"Bank\") && config.startHeight === 1 && config.processGenesis) {\n moduleNames.push(\"bankModule\");\n }\n if (config.modules.includes(\"Staking\") && !config.minimal) {\n moduleNames.push(\"stakingModule\");\n }\n return `[${moduleNames.filter(m => !m.includes(\"//\")).join(\", \")}]`;\n}\n\nasync function installDependencies(config: ProjectConfig, targetDir: string): Promise<void> {\n const {\n spawn,\n } = await import(\"node:child_process\");\n\n return new Promise((resolve, reject) => {\n const child = spawn(config.packageManager, [\"install\"], {\n cwd: targetDir,\n stdio: \"inherit\",\n });\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`Package installation failed with code ${code}`));\n }\n else {\n resolve();\n }\n });\n });\n}\n\nasync function buildProject(config: ProjectConfig, targetDir: string): Promise<void> {\n const {\n spawn,\n } = await import(\"node:child_process\");\n\n return new Promise((resolve, reject) => {\n const child = spawn(config.packageManager, [\"run\", \"build\"], {\n cwd: targetDir,\n stdio: \"inherit\",\n });\n\n child.on(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`Package installation failed with code ${code}`));\n }\n else {\n resolve();\n }\n });\n });\n}\n","import {\n existsSync,\n} from \"node:fs\";\nimport {\n dirname, resolve,\n} from \"node:path\";\nimport {\n fileURLToPath,\n} from \"node:url\";\n\nimport colors from \"picocolors\";\n\nimport {\n createIndexer,\n} from \"./create-indexer.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nasync function main() {\n console.log();\n console.log(colors.cyan(\"🚀 Welcome to create-eclesia-indexer!\"));\n console.log(colors.gray(\"Scaffolding a new Cosmos SDK chain indexer...\"));\n console.log();\n\n try {\n const projectName = process.argv[2];\n\n if (projectName && existsSync(resolve(process.cwd(), projectName))) {\n console.log(colors.red(`❌ Directory '${projectName}' already exists.`));\n process.exit(1);\n }\n\n await createIndexer(projectName);\n\n console.log();\n console.log(colors.green(\"✅ Indexer created successfully!\"));\n console.log();\n }\n catch (error) {\n console.error(colors.red(\"❌ Error creating indexer:\"), error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
File without changes
|