Skip to content

Autoload from src/handlers#824

Merged
DZakh merged 18 commits into
mainfrom
dz/src-handlers
Nov 20, 2025
Merged

Autoload from src/handlers#824
DZakh merged 18 commits into
mainfrom
dz/src-handlers

Conversation

@DZakh

@DZakh DZakh commented Nov 12, 2025

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Handlers are optional and will be auto-discovered from src/handlers when not specified.
    • Per-contract handler files are generated during import; handler registration is now awaited during initialization.
  • Chores

    • CI and package Node engine requirements tightened to Node 22.x (>=22.0.0 <=22.10.0).
    • Worktree setup now runs npm install as part of setup.
    • Persisted state no longer stores a handler file checksum.

@coderabbitai

coderabbitai Bot commented Nov 12, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Makes contract handler paths optional with filesystem auto-loading, converts handler registration and indexer initialization to async, removes handler_files_hash from persisted state and DB flows, tightens Node.js engine/workflow versions to 22.10.0, removes language-derived handler path resolution and the HandlerPathsTemplate, and adds per-contract handler generation in templates.

Changes

Cohort / File(s) Summary
CI & package engines
​.github/workflows/build_and_test.yml, ​.github/workflows/release.yml, ​.github/workflows/templates_integration_test.yml, codegenerator/cli/npm/envio/package.json, codegenerator/cli/npm/envio/package.json.tmpl, codegenerator/cli/templates/dynamic/codegen/package.json.hbs, codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs, scenarios/*/package.json
Bumped Node.js versions in workflows to 22.10.0 and added/updated engines.node ranges to ">=22.0.0 <=22.10.0" across package templates and scenario manifests
Schema: handler optionality
codegenerator/cli/npm/envio/evm.schema.json, codegenerator/cli/npm/envio/fuel.schema.json
Added top-level handlers property; changed per-contract handler to optional (string or null) and removed it from required lists; updated descriptions to mention auto-loading from src/handlers when omitted
Config types: handler -> Option
codegenerator/cli/src/config_parsing/human_config.rs, codegenerator/cli/src/config_parsing/system_config.rs, codegenerator/cli/src/cli_args/init_config.rs
Converted contract handler fields to Option<String>, added handlers: Option<String> to HumanConfig/SystemConfig, removed language-derived handler path resolution
Removed HandlerPathsTemplate
codegenerator/cli/src/project_paths/handler_paths.rs, codegenerator/cli/src/project_paths/mod.rs
Deleted HandlerPathsTemplate module, its path-derivation helpers and tests, and removed its public export
Persisted state: drop handler_files_hash
codegenerator/cli/src/db/InternalTable.res, codegenerator/cli/src/persisted_state/db.rs, codegenerator/cli/src/persisted_state/mod.rs, codegenerator/cli/templates/static/codegen/src/PersistedState.res, scenarios/test_codegen/test/lib_tests/PgStorage_test.res
Removed handler_files_hash from types, DB schema/queries (upsert/select), persisted-state comparison logic, tests, and expected SQL/JSON fixtures
Async registration & auto-load runtime
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs, codegenerator/cli/templates/static/codegen/src/Index.res, codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs, scenarios/**/tests, codegenerator/cli/npm/envio/src/Utils.res
Made registerAllHandlers and getIndexer async; changed registerContractHandlers to accept optional handler; added autoLoadFromSrcHandlers that uses a glob async iterator; added Utils.asyncIterator and fromAsyncIterator; updated call sites to await registrations
Per-contract handler generation & templating
codegenerator/cli/src/hbs_templating/contract_import_templates.rs, codegenerator/cli/src/hbs_templating/codegen_templates.rs
Added per-contract handler file generation (TypeScript/ReScript), changed ContractTemplate.handler to Option<String>, removed HandlerPathsTemplate usage, updated ProjectTemplate fields (added relative path fields, removed has_typescript)
Template / generated start & handlers
codegenerator/cli/templates/dynamic/codegen/package.json.hbs, codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs, removed dynamic EventHandlers templates (JS/Rescript/TS)
Updated start script to run from project root and include ts-node unconditionally; added auto-load logic and async handler registration to generated runtime; deleted legacy EventHandlers templates
Project templates: removed explicit handlers
codegenerator/cli/templates/static/*/config.yaml (erc20, greeter, greeteronfuel)
Removed explicit handler entries from example contract configs to rely on optional handlers/auto-loading
Tests: imports & async updates
multiple codegenerator/cli/templates/static/*/test/*, scenarios/test_codegen/test/*, scenarios/test_codegen/test/helpers/Mock.res
Converted some runtime imports to type-only imports, updated tests to await async getIndexer/registerAllHandlers, adjusted callsites to makeGeneratedConfig where applicable, and updated fixtures
Misc: utils, DB internals & worktree
codegenerator/cli/npm/envio/src/Utils.res, codegenerator/cli/src/db/InternalTable.res, .cursor/worktrees.json
Added asyncIterator type and fromAsyncIterator helper; removed persisted handler_files_hash field in InternalTable; added a worktree setup step running npm install and rescript in codegenerator/cli/npm/envio

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Index as Index.res
    participant Generated as Generated.res (runtime)
    participant AutoLoad as autoLoadFromSrcHandlers
    participant FS as node:fs/promises glob
    participant ContractReg as registerContractHandlers

    Index->>Generated: await getIndexer()
    activate Generated
    Generated->>Generated: await registerAllHandlers()
    Generated->>AutoLoad: await autoLoadFromSrcHandlers()
    activate AutoLoad
    AutoLoad->>FS: glob("src/handlers/**/*.{js,ts,res,res.js}")
    FS-->>AutoLoad: async iterator<filePath>
    AutoLoad->>AutoLoad: import/require each found file
    deactivate AutoLoad
    Generated->>ContractReg: for each contract, registerContractHandlers(~handler: Some(path) | None)
    alt handler provided
        ContractReg->>Generated: require(specific handler file
    else no handler
        ContractReg->>Generated: rely on auto-loaded registrations
    end
    deactivate Generated
    Generated-->>Index: return initialized indexer
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • async/await correctness and error propagation across Generated.getIndexer, registerAllHandlers, and updated call sites
    • consistency of optional handler / top-level handlers across parsing, templates, and runtime generation
    • DB query and migration impacts due to removal of handler_files_hash
    • correctness of glob async iterator usage and generated import/require paths
    • template placeholders for relative paths and start-script cwd handling

Possibly related PRs

Suggested labels

codex

Suggested reviewers

  • JonoPrest
  • moose-code

Poem

🐰 I nibble paths and make handlers small,

Optional now, and auto-loaded from a hall.
Promises awaited — indexer wakes with cheer,
Hash dropped from the state, Node twenty-two draws near.
A rabbit claps its paws — async spring is here.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 64.71% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Autoload from src/handlers' accurately and concisely describes the main change: adding autoload functionality for handlers from the src/handlers directory.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dz/src-handlers

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bdfef00 and af83a82.

📒 Files selected for processing (1)
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
codegenerator/cli/src/hbs_templating/codegen_templates.rs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

hbs_templating/codegen_templates.rs feeds templates

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (5)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/hbs_templating/codegen_templates.rs : hbs_templating/codegen_templates.rs feeds templates

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/lib.rs : CLI entry point is codegenerator/cli/src/lib.rs

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/** : The Rust CLI lives in codegenerator/cli

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/human_config.rs : human_config.rs reads user files and JSON schemas

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧬 Code graph analysis (1)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (1)
codegenerator/cli/src/project_paths/path_utils.rs (1)
  • add_trailing_relative_dot (93-97)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (4)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (4)

803-808: LGTM: Handler field simplified to optional string.

The change from a complex HandlerPathsTemplate to Option<String> simplifies the representation and aligns with the PR's auto-loading feature where handler paths are now optional.


811-816: LGTM: Function signature updated to support optional handler paths.

The signature change removes the project_paths dependency and directly uses contract.handler_path, which is consistent with the auto-loading approach where handler paths are optional and no longer derived from project structure.


1283-1286: LGTM: New fields support optional handler paths and path metadata.

The new fields relative_path_to_generated_from_root and handlers_path are properly initialized (lines 1407, 1410) and align with the PR's goal of supporting auto-loaded handlers and providing necessary path metadata for template generation.


1309-1309: LGTM: Call site correctly updated for new signature.

The call to ContractTemplate::from_config_contract properly passes cfg_contract and cfg, matching the updated function signature.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scenarios/test_codegen/test/lib_tests/PgStorage_test.res (1)

182-184: Eliminate duplicated index DDL in the initializer.

The updated expectation shows two identical CREATE INDEX IF NOT EXISTS "A_b_id" statements for the same table. That means PgStorage.makeInitializeTransaction now emits duplicate DDL. Even with IF NOT EXISTS, we still pay the extra parse/execute cost and the duplication signals a regression in how indices are assembled. Please adjust the generator to emit each index only once (e.g., ensure makeCreateTableIndicesQuery isn’t invoked twice for the same table or dedupe the collected statements) and revert this expectation back to a single statement.

🧹 Nitpick comments (5)
codegenerator/cli/npm/envio/package.json (1)

22-24: Verify the upper bound constraint on Node version.

The engines constraint ">=22.0.0 <=22.10.0" includes a strict upper bound that will prevent the package from running on Node versions newer than 22.10.0. This may require frequent updates as new Node versions are released.

Consider whether the upper bound is necessary, or if a more permissive constraint like ">=22.0.0 <23.0.0" would be more appropriate unless there's a specific compatibility issue with newer 22.x versions.

codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs (1)

44-44: Verify the upper bound constraint matches project requirements.

The Node engine constraint has been updated to ">=22.0.0 <=22.10.0", which drops support for Node 18 and 20 and adds a strict upper bound at 22.10.0.

Ensure this breaking change is:

  1. Documented in release notes for users
  2. Intentional regarding the upper bound constraint (which will require updates as new Node 22.x versions are released)
codegenerator/cli/npm/envio/package.json.tmpl (1)

27-29: Verify the upper bound constraint is appropriate for distribution.

The engines constraint ">=22.0.0 <=22.10.0" includes a strict upper bound. Since this is a template file that will be used in the distributed package, the upper bound will affect all users and may prevent the package from running on newer Node 22.x versions (e.g., 22.11.0, 22.12.0) when they're released.

Consider using a more permissive upper bound unless there's a specific known incompatibility with newer Node 22.x versions.

codegenerator/cli/npm/envio/src/Utils.res (1)

362-371: Consider adding a documentation comment.

The implementation correctly converts an async iterator to an array. However, adding a docstring would improve maintainability by documenting the function's purpose, parameters, and return type.

Apply this diff to add documentation:

+  /**
+  Converts an async iterator to an array by iterating through all values.
+  Useful for consuming async generators or other async iterables.
+  
+  Example:
+  ```rescript
+  let values = await iterator->Array.fromAsyncIterator
+  ```
+  */
   let fromAsyncIterator = %raw(`async (iterator) => {
     const result = [];
     for await (const item of iterator) {
       result.push(item);
     }
     return result;
   }`)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (1)

460-487: Consider more robust template file discovery.

The manual directory iteration to find the EventHandlers template file is fragile and depends on a specific directory structure (src/EventHandlers.{ts|res}.hbs). If the template location changes, this could fail silently until runtime.

Consider one of these approaches:

Option 1: Use a well-known path

let template_path = lang_dir.get_file(format!("src/{}", template_file_name));

Option 2: Add a helper method to TemplateDirs

// In template_dirs.rs
impl TemplateDirs {
    pub fn get_event_handlers_template(&self, lang: &Language, template_type: &str) -> Result<&'static str> {
        // Encapsulate the lookup logic here
    }
}

This would make the code more maintainable and provide clearer error messages when templates are missing.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd3d6a0 and 08a944a.

⛔ Files ignored due to path filters (1)
  • scenarios/test_codegen/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (47)
  • .cursor/worktrees.json (1 hunks)
  • .github/workflows/build_and_test.yml (1 hunks)
  • .github/workflows/release.yml (2 hunks)
  • .github/workflows/templates_integration_test.yml (1 hunks)
  • codegenerator/cli/npm/envio/evm.schema.json (2 hunks)
  • codegenerator/cli/npm/envio/fuel.schema.json (2 hunks)
  • codegenerator/cli/npm/envio/package.json (1 hunks)
  • codegenerator/cli/npm/envio/package.json.tmpl (1 hunks)
  • codegenerator/cli/npm/envio/src/Utils.res (1 hunks)
  • codegenerator/cli/npm/envio/src/db/InternalTable.res (0 hunks)
  • codegenerator/cli/src/cli_args/init_config.rs (2 hunks)
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs (3 hunks)
  • codegenerator/cli/src/config_parsing/human_config.rs (6 hunks)
  • codegenerator/cli/src/config_parsing/system_config.rs (2 hunks)
  • codegenerator/cli/src/executor/init.rs (0 hunks)
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs (6 hunks)
  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs (2 hunks)
  • codegenerator/cli/src/persisted_state/db.rs (1 hunks)
  • codegenerator/cli/src/persisted_state/mod.rs (1 hunks)
  • codegenerator/cli/src/project_paths/handler_paths.rs (0 hunks)
  • codegenerator/cli/src/project_paths/mod.rs (0 hunks)
  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs (1 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (3 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (1 hunks)
  • codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/Index.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/PersistedState.res (0 hunks)
  • codegenerator/cli/templates/static/erc20_template/typescript/config.yaml (0 hunks)
  • codegenerator/cli/templates/static/erc20_template/typescript/src/handlers/ERC20.ts (1 hunks)
  • codegenerator/cli/templates/static/erc20_template/typescript/test/test.ts (3 hunks)
  • codegenerator/cli/templates/static/greeter_template/typescript/config.yaml (0 hunks)
  • codegenerator/cli/templates/static/greeter_template/typescript/src/handlers/Greeter.ts (1 hunks)
  • codegenerator/cli/templates/static/greeter_template/typescript/test/test.ts (1 hunks)
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml (0 hunks)
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/src/handlers/Greeter.ts (1 hunks)
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/test/test.ts (1 hunks)
  • scenarios/erc20_multichain_factory/package.json (1 hunks)
  • scenarios/fuel_test/package.json (1 hunks)
  • scenarios/helpers/package.json (1 hunks)
  • scenarios/test_codegen/.mocharc.json (1 hunks)
  • scenarios/test_codegen/package.json (1 hunks)
  • scenarios/test_codegen/test/E2EEthNode_test.res (1 hunks)
  • scenarios/test_codegen/test/EventHandler_test.ts (1 hunks)
  • scenarios/test_codegen/test/helpers/Mock.res (1 hunks)
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res (3 hunks)
  • scenarios/test_codegen/test/rollback/ChainDataHelpers.res (1 hunks)
  • scenarios/test_codegen/test/rollback/MockChainData_test.res (1 hunks)
💤 Files with no reviewable changes (8)
  • codegenerator/cli/src/project_paths/mod.rs
  • codegenerator/cli/src/project_paths/handler_paths.rs
  • codegenerator/cli/src/executor/init.rs
  • codegenerator/cli/templates/static/codegen/src/PersistedState.res
  • codegenerator/cli/npm/envio/src/db/InternalTable.res
  • codegenerator/cli/templates/static/greeter_template/typescript/config.yaml
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/config.yaml
  • codegenerator/cli/templates/static/erc20_template/typescript/config.yaml
🧰 Additional context used
📓 Path-based instructions (7)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/npm/envio/package.json.tmpl
  • codegenerator/cli/templates/static/erc20_template/typescript/src/handlers/ERC20.ts
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/src/handlers/Greeter.ts
  • codegenerator/cli/src/persisted_state/mod.rs
  • codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs
  • codegenerator/cli/npm/envio/fuel.schema.json
  • codegenerator/cli/npm/envio/evm.schema.json
  • codegenerator/cli/src/persisted_state/db.rs
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/npm/envio/package.json
  • codegenerator/cli/templates/static/greeter_template/typescript/src/handlers/Greeter.ts
  • codegenerator/cli/src/cli_args/init_config.rs
  • codegenerator/cli/templates/static/greeteronfuel_template/typescript/test/test.ts
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • codegenerator/cli/src/config_parsing/human_config.rs
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs
  • codegenerator/cli/npm/envio/src/Utils.res
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs
  • codegenerator/cli/templates/static/greeter_template/typescript/test/test.ts
  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/templates/static/erc20_template/typescript/test/test.ts
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
codegenerator/cli/npm/envio/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Shared library-fied runtime lives in codegenerator/cli/npm/envio

Files:

  • codegenerator/cli/npm/envio/package.json.tmpl
  • codegenerator/cli/npm/envio/fuel.schema.json
  • codegenerator/cli/npm/envio/evm.schema.json
  • codegenerator/cli/npm/envio/package.json
  • codegenerator/cli/npm/envio/src/Utils.res
**/*.res

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Prefer reading ReScript .res modules directly

Files:

  • scenarios/test_codegen/test/helpers/Mock.res
  • scenarios/test_codegen/test/rollback/ChainDataHelpers.res
  • scenarios/test_codegen/test/rollback/MockChainData_test.res
  • scenarios/test_codegen/test/E2EEthNode_test.res
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • codegenerator/cli/npm/envio/src/Utils.res
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
codegenerator/cli/templates/dynamic/**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Files:

  • codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs
{codegenerator/cli/templates/static/codegen/src/**,codegenerator/cli/templates/dynamic/codegen/src/**}

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Template versions of runtime live under templates/{static,dynamic}/codegen/src and are the recommended editing targets

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs
codegenerator/cli/templates/static/**/*.res

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Files:

  • codegenerator/cli/templates/static/codegen/src/Index.res
codegenerator/cli/src/hbs_templating/codegen_templates.rs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

hbs_templating/codegen_templates.rs feeds templates

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (14)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/npm/envio/** : Shared library-fied runtime lives in codegenerator/cli/npm/envio

Applied to files:

  • codegenerator/cli/npm/envio/package.json.tmpl
  • .cursor/worktrees.json
  • codegenerator/cli/npm/envio/package.json
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/lib.rs : CLI entry point is codegenerator/cli/src/lib.rs

Applied to files:

  • codegenerator/cli/src/persisted_state/mod.rs
  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/** : The Rust CLI lives in codegenerator/cli

Applied to files:

  • codegenerator/cli/src/persisted_state/mod.rs
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/commands.rs : Command dispatcher is codegenerator/cli/src/commands.rs

Applied to files:

  • codegenerator/cli/src/persisted_state/mod.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/static/**/*.res : Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Applied to files:

  • scenarios/helpers/package.json
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/dynamic/**/*.hbs : Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Applied to files:

  • codegenerator/cli/templates/dynamic/init_templates/shared/package.json.hbs
  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to generated/src/ChainManager.res : In generated runtime, ChainManager.res is part of the fetch side

Applied to files:

  • scenarios/test_codegen/test/rollback/ChainDataHelpers.res
  • scenarios/test_codegen/test/E2EEthNode_test.res
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Verify tests by running `pnpm rescript` then `pnpm mocha`; use `_only` to focus tests

Applied to files:

  • .cursor/worktrees.json
  • scenarios/test_codegen/.mocharc.json
📚 Learning: 2025-05-27T17:07:12.878Z
Learnt from: JonoPrest
Repo: enviodev/hyperindex PR: 555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.878Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.

Applied to files:

  • scenarios/test_codegen/test/rollback/MockChainData_test.res
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/hbs_templating/codegen_templates.rs : hbs_templating/codegen_templates.rs feeds templates

Applied to files:

  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/human_config.rs : human_config.rs reads user files and JSON schemas

Applied to files:

  • codegenerator/cli/src/config_parsing/human_config.rs
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/config_parsing/human_config.rs
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: ReScript sources compile with `pnpm rescript -w` for live reload

Applied to files:

  • codegenerator/cli/templates/dynamic/codegen/package.json.hbs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to generated/src/PgStorage.res : In generated runtime, PgStorage.res is part of the persistence stack

Applied to files:

  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
🧬 Code graph analysis (4)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (1)
codegenerator/cli/src/template_dirs.rs (2)
  • new (63-65)
  • new (155-159)
codegenerator/cli/src/cli_args/init_config.rs (3)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (1)
  • config (377-387)
codegenerator/cli/src/cli_args/interactive_init/shared_prompts.rs (1)
  • events (42-46)
codegenerator/cli/src/utils/unique_hashmap.rs (1)
  • try_insert (4-17)
codegenerator/cli/src/config_parsing/system_config.rs (1)
codegenerator/cli/src/project_paths/path_utils.rs (1)
  • get_config_path_relative_to_root (12-29)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (2)
codegenerator/cli/src/project_paths/path_utils.rs (1)
  • add_trailing_relative_dot (93-97)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (3)
  • from_config_contract (222-241)
  • contract (227-231)
  • config (377-387)
🪛 Biome (2.1.2)
scenarios/test_codegen/.mocharc.json

[error] 3-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)


[error] 3-3: End of file expected

Use an array for a sequence of values: [1, 2]

(parse)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (37)
codegenerator/cli/templates/static/erc20_template/typescript/src/handlers/ERC20.ts (1)

72-72: LGTM!

Adding a trailing blank line is a minor formatting improvement that aligns with code style consistency across template files. No functional changes to the handlers.

codegenerator/cli/templates/static/greeteronfuel_template/typescript/test/test.ts (1)

2-3: LGTM! Proper use of type-only import.

The refactor correctly separates the User entity type into a type-only import, as it's only used for type annotations and never as a runtime value. This follows TypeScript best practices and can help reduce bundle size.

codegenerator/cli/templates/static/greeter_template/typescript/test/test.ts (1)

2-3: LGTM! Proper use of type-only import.

The refactor correctly separates the User entity type into a type-only import, consistent with the same pattern applied across other template test files. This is a TypeScript best practice for symbols used only as types.

codegenerator/cli/templates/static/erc20_template/typescript/test/test.ts (2)

2-3: LGTM! Proper use of type-only import.

The refactor correctly separates the Account entity type into a type-only import, following the same best practice pattern applied across all template test files.


50-50: LGTM! Improved assertion error messages.

The enhanced error messages provide clear context about the expected calculations, making test failures easier to understand and debug.

Also applies to: 61-61

codegenerator/cli/templates/static/greeter_template/typescript/src/handlers/Greeter.ts (1)

41-41: Trailing newline keeps the file POSIX-friendly.
No behavioral change; happy to see consistent formatting.

codegenerator/cli/templates/static/greeteronfuel_template/typescript/src/handlers/Greeter.ts (1)

40-40: Consistent trailing newline looks good.
Formatting-only addition, keeps parity across templates.

scenarios/test_codegen/test/EventHandler_test.ts (1)

4-4: LGTM!

The addition of a blank line after imports improves code formatting and readability.

.github/workflows/templates_integration_test.yml (1)

63-63: LGTM!

The Node.js version upgrade to 22.10.0 is consistent with the PR objectives and ensures reproducible CI builds by using an exact version.

scenarios/test_codegen/.mocharc.json (1)

3-3: Verify ts-node loader compatibility with Node 22.

The change from "ts-node/register" to "ts-node/require" aligns with modern ts-node usage for CommonJS environments and is likely required for Node 22 compatibility. However, please verify that:

  1. Tests run successfully with this configuration on Node 22.10.0
  2. The ts-node version in package.json supports this loader path

Note: The Biome static analysis errors are false positives—the JSON syntax is valid.

scenarios/test_codegen/package.json (1)

64-66: LGTM!

The engines field addition is consistent with the repository-wide Node 22 upgrade. The same upper bound consideration mentioned in other files applies here, though it's less critical for a test scenario package.

scenarios/fuel_test/package.json (1)

37-39: LGTM!

The engines field addition completes the consistent Node 22 upgrade across all scenario test packages in the repository.

scenarios/erc20_multichain_factory/package.json (1)

24-26: LGTM!

The Node.js engine constraint aligns with the repository-wide upgrade to Node.js 22.x. The version range allows flexibility while ensuring compatibility.

scenarios/helpers/package.json (1)

20-22: LGTM!

The Node.js engine constraint is consistent with the repository-wide upgrade to Node.js 22.x.

codegenerator/cli/src/hbs_templating/contract_import_templates.rs (2)

411-418: LGTM!

The refactoring to separate schema generation from per-contract handler generation is clean and maintains good separation of concerns.


423-432: LGTM!

The new subgraph migration template generation reuses the per-contract handler generation logic effectively.

.github/workflows/build_and_test.yml (1)

128-128: LGTM!

The Node.js version update is consistent with other workflow files and supports the repository-wide upgrade to Node.js 22.x.

scenarios/test_codegen/test/rollback/ChainDataHelpers.res (1)

17-17: No issues found—config access patterns are consistent.

All usages of makeGeneratedConfig() follow a consistent pattern across the codebase:

  • scenarios/test_codegen/test/rollback/MockChainData_test.res:6
  • scenarios/test_codegen/test/rollback/ChainDataHelpers.res:17
  • scenarios/test_codegen/test/helpers/Mock.res:262

No remaining usages of the old getIndexer().config pattern exist. The migration is complete and consistent.

codegenerator/cli/templates/static/codegen/src/Index.res (1)

232-232: All getIndexer() call sites are properly awaiting the async function.

Verification confirms 2 total call sites across the codebase, both correctly using await: the one under review at Index.res:232 and a test site at E2EEthNode_test.res:72. No missing await patterns detected.

.github/workflows/release.yml (1)

225-225: Node.js 22.10.0 verified as available and secure.

Node.js v22 officially transitioned into Long Term Support (LTS) on October 29, 2024, and Node.js 22.10.0 was released on October 30, 2024. The version is fully available across multiple platforms. Node.js v22 will remain in Active LTS until October 2025, then transitions to Maintenance LTS continuing until April 2027. No known security vulnerabilities exist for this specific point release; later patch versions (22.15.1+) address vulnerabilities from May 2025 onwards. Official Node.js 22.x binaries include OpenSSL 3.0.x, which is supported until September 7, 2026—within the expected lifetime of Node.js 22.x.

codegenerator/cli/src/cli_args/init_config.rs (2)

64-94: LGTM! Consistent removal of language-based handler paths.

The changes correctly implement the no-handler approach for multi-chain contracts. The logic properly distinguishes between global and local contracts, setting handler: None in both cases while preserving events configuration.


283-287: LGTM! Fuel contract config aligned with EVM changes.

The Fuel contract configuration consistently sets handler: None, matching the pattern used in EVM configs. This ensures uniform behavior across both ecosystems.

codegenerator/cli/src/persisted_state/db.rs (1)

34-65: LGTM! Database operations correctly updated.

The removal of handler_files_hash is consistently applied across the upsert operation:

  • Column list reduced from 5 to 4 entries
  • VALUES bindings updated accordingly ($5 is now the last parameter)
  • ON CONFLICT UPDATE no longer references handler_files_hash

The change aligns with the broader refactoring to remove handler file tracking from persisted state.

codegenerator/cli/src/config_parsing/human_config.rs (2)

507-513: LGTM! EVM handler field properly made optional.

The changes correctly implement optional handler semantics:

  • Type changed to Option<String>
  • skip_serializing_if = "Option::is_none" prevents serializing absent handlers
  • Description accurately reflects auto-loading behavior

652-658: LGTM! Fuel handler field consistently made optional.

The Fuel configuration mirrors the EVM changes, ensuring consistent behavior across both ecosystems. The description properly documents the auto-loading feature.

codegenerator/cli/src/config_parsing/graph_migration/mod.rs (2)

350-360: LGTM! Contract config correctly sets handler to None.

The generated contract configuration properly sets handler: None, which aligns with the optional handler approach and enables auto-loading from the filesystem.


234-237: All call sites verified and correctly updated.

Both occurrences of generate_config_from_subgraph_id have been properly migrated:

  • Call site in codegenerator/cli/src/executor/init.rs:82-85 passes 2 arguments
  • Test call site in codegenerator/cli/src/config_parsing/graph_migration/mod.rs:452 passes 2 arguments

The language parameter removal has been consistently applied. No call sites remain with the old signature.

codegenerator/cli/npm/envio/fuel.schema.json (2)

92-97: LGTM! Schema correctly reflects optional handler.

The GlobalContract schema properly updates the handler field:

  • Type changed to union of string and null
  • Description updated to document auto-loading behavior
  • Field no longer required

This aligns with the Rust code changes in human_config.rs.


242-247: LGTM! NetworkContract schema consistently updated.

The NetworkContract schema mirrors the GlobalContract changes, ensuring consistent handler behavior across both contract definition types.

codegenerator/cli/src/persisted_state/mod.rs (3)

16-22: LGTM! PersistedState struct correctly updated.

The handler_files_hash field has been removed from the struct, which aligns with the broader refactoring to eliminate handler file tracking from persisted state.


26-33: LGTM! StateField enum consistently updated.

The HandlerFiles variant has been removed from the enum, maintaining consistency with the struct changes. This simplifies state comparison logic.


68-87: LGTM! State computation no longer includes handler paths.

The get_current_state method correctly omits handler file hashing, focusing only on:

  • Envio version
  • Config hash
  • Schema hash
  • ABI files hash

This reduces the scope of what triggers codegen/migrations, which is appropriate given handlers can now be auto-loaded.

codegenerator/cli/src/config_parsing/system_config.rs (3)

1182-1182: LGTM! Contract struct field correctly made optional.

The handler_path field type change from String to Option<String> is fundamental to enabling optional handlers and auto-loading behavior.


1188-1201: LGTM! Constructor signature properly updated.

The new() method signature correctly accepts Option<String> for handler_path, maintaining consistency with the struct field type.


1203-1218: LGTM! Path resolution correctly handles optional handler.

The get_path_to_handler method properly:

  • Returns Result<Option<PathBuf>> to reflect the optional nature
  • Returns Ok(None) when handler_path is None
  • Resolves the relative path and returns Some(PathBuf) when present

This allows callers to distinguish between "no handler specified" and "handler specified but path resolution failed".

codegenerator/cli/npm/envio/evm.schema.json (2)

155-160: LGTM! EVM GlobalContract schema properly updated.

The schema changes correctly reflect the optional handler:

  • Type changed to ["string", "null"]
  • Description updated to document auto-loading from src directory
  • Field no longer in required list

This matches the pattern used in fuel.schema.json and aligns with the Rust code changes.


615-620: LGTM! EVM NetworkContract schema consistently updated.

The NetworkContract schema mirrors the GlobalContract changes, ensuring uniform behavior across both contract definition contexts in the EVM ecosystem.

Comment thread codegenerator/cli/src/hbs_templating/contract_import_templates.rs Outdated
@DZakh DZakh mentioned this pull request Nov 12, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
codegenerator/cli/npm/envio/src/Utils.res (1)

364-375: Broaden fromAsyncIterator to stay truly generic

The implementation happily collects whatever an async iterator yields, but the signature pins it to string, forcing callers to upcast or add redundant conversions. Since type asyncIterator<'a> is generic and standard async-iterator bindings are parameterized the same way, keep the helper polymorphic so it works for any element type.(rescript-lang.org)

-  let fromAsyncIterator: asyncIterator<string> => promise<
-    array<string>,
-  > = %raw(`async (iterator) => {
+  let fromAsyncIterator: asyncIterator<'a> => promise<
+    array<'a>,
+  > = %raw(`async (iterator) => {
     const result = [];
     for await (const item of iterator) {
       result.push(item);
     }
     return result;
   }`)
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (1)

20-20: Document that fs.glob is experimental; no critical issues found.

The fs.glob API is present in Node.js v22.10.0 but is marked as experimental (Stability: 1). The version constraint in package.json correctly enforces "node": ">=22.0.0 <=22.10.0", and the error message at line 31 directs users to verify the Node.js version. However, add a code comment documenting that fs.glob is experimental to alert future maintainers about potential breaking changes in upcoming Node.js releases.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08a944a and 2981510.

📒 Files selected for processing (4)
  • codegenerator/cli/npm/envio/src/Utils.res (2 hunks)
  • codegenerator/cli/src/config_parsing/system_config.rs (1 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (3 hunks)
  • codegenerator/cli/templates/dynamic/subgraph_migration_templates/javascript/src/EventHandlers.js.hbs (0 hunks)
💤 Files with no reviewable changes (1)
  • codegenerator/cli/templates/dynamic/subgraph_migration_templates/javascript/src/EventHandlers.js.hbs
🧰 Additional context used
📓 Path-based instructions (5)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/npm/envio/src/Utils.res
codegenerator/cli/templates/dynamic/**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
{codegenerator/cli/templates/static/codegen/src/**,codegenerator/cli/templates/dynamic/codegen/src/**}

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Template versions of runtime live under templates/{static,dynamic}/codegen/src and are the recommended editing targets

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
**/*.res

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Prefer reading ReScript .res modules directly

Files:

  • codegenerator/cli/npm/envio/src/Utils.res
codegenerator/cli/npm/envio/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Shared library-fied runtime lives in codegenerator/cli/npm/envio

Files:

  • codegenerator/cli/npm/envio/src/Utils.res
🧠 Learnings (2)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/config_parsing/system_config.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/static/**/*.res : Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Applied to files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (7)
codegenerator/cli/src/config_parsing/system_config.rs (2)

1182-1182: Option handling for handler_path is correct throughout the codebase.

The field type change from String to Option<String> is properly coordinated. The only access to contract.handler_path (line 816 in codegenerator/cli/src/hbs_templating/codegen_templates.rs) correctly clones the Option<String> and assigns it to the ContractTemplate::handler field, which also expects Option<String>. No calls to the removed methods exist elsewhere in the codebase.


1188-1193: All Contract::new callsites verified—constructor signature change is correct and consistent.

The 4 callsites in system_config.rs (lines 582, 613, 739, 768) all correctly pass Option<String> values:

  • Lines 584, 741: g_contract.config.handler.clone() (ContractConfig::handler is Option<String>)
  • Lines 615, 770: l_contract.handler (extracted ContractConfig with handler: Option<String>)
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (5)

3-18: LGTM! Clean refactor to optional handler pattern.

The signature change to named parameters with option<string> for the handler makes the API clearer and more flexible. Error handling is thorough with helpful context.


128-147: LGTM! Async conversion and auto-loading flow are correct.

The function properly:

  1. Starts registration
  2. Auto-loads handlers from src/handlers/ first
  3. Then loads contract-specific handlers
  4. Finishes registration

The ordering is important here - auto-loaded handlers register first, followed by contract-specific handlers, which allows contract-specific handlers to potentially override or supplement auto-loaded registrations.


222-238: LGTM! Async indexer initialization is correct.

The function properly converts to async and awaits registerAllHandlers() before constructing the indexer. The memoization pattern is preserved correctly.


24-24: The pattern ./src/handlers/**/*.{js,ts} is appropriate for this codebase and requires no changes.

Verification shows that handler directories contain only .ts files (TypeScript), and there are no .jsx, .tsx, .mjs, or .cjs files in the handlers across any template. The current pattern correctly covers the actual file types used in this project. Handlers are not React components and the project uses TypeScript modules compiled by the Node.js environment, not raw CommonJS or ECMAScript modules.

Likely an incorrect or invalid review comment.


42-42: Verify path construction correctness.

The raw JavaScript require with path interpolation could be error-prone. The path construction concatenates:

  • "../" (one level up)
  • {{relative_path_to_root_from_generated}} (Handlebars variable)
  • file (from glob result, already relative to project root starting with ./src/handlers/)

Please verify that this path construction produces correct relative paths from the Generated.res module location to the handler files. Consider:

  1. What is the value of {{relative_path_to_root_from_generated}}?
  2. Does the concatenation handle path separators correctly on all platforms?
  3. Should the ./ prefix from the glob pattern be stripped before concatenation?

Comment thread codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
@DZakh DZakh mentioned this pull request Nov 12, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (1)

541-542: Sanitize contract names before using them as filenames.

The code uses contract.name.capitalized directly to generate filenames without sanitization. As previously noted, contract names from config files can contain spaces (e.g., "Fuel Greeter Indexer"), which would create files like "Fuel Greeter Indexer.ts". This causes cross-platform and shell script compatibility issues.

Add validation to reject or sanitize contract names containing spaces and other problematic filesystem characters during config parsing, or sanitize them before filename generation (e.g., replace spaces with underscores or enforce snake_case/PascalCase).

🧹 Nitpick comments (1)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (1)

517-549: Consider warning users about file overwrites.

The method silently overwrites existing handler files without warning. While this is likely intentional for the init flow, it could surprise users if they re-run initialization after making manual changes.

Consider logging a message when overwriting existing files, or documenting this behavior clearly.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2981510 and ef04bf6.

📒 Files selected for processing (4)
  • codegenerator/cli/src/executor/init.rs (3 hunks)
  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs (5 hunks)
  • codegenerator/cli/templates/dynamic/contract_import_templates/rescript/src/EventHandlers.res.hbs (0 hunks)
  • codegenerator/cli/templates/dynamic/contract_import_templates/typescript/src/EventHandlers.ts.hbs (0 hunks)
💤 Files with no reviewable changes (2)
  • codegenerator/cli/templates/dynamic/contract_import_templates/rescript/src/EventHandlers.res.hbs
  • codegenerator/cli/templates/dynamic/contract_import_templates/typescript/src/EventHandlers.ts.hbs
🧰 Additional context used
📓 Path-based instructions (1)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/src/executor/init.rs
🧠 Learnings (5)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/hbs_templating/codegen_templates.rs : hbs_templating/codegen_templates.rs feeds templates

Applied to files:

  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
  • codegenerator/cli/src/executor/init.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/static/**/*.res : Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Applied to files:

  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/dynamic/**/*.hbs : Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Applied to files:

  • codegenerator/cli/src/hbs_templating/contract_import_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/lib.rs : CLI entry point is codegenerator/cli/src/lib.rs

Applied to files:

  • codegenerator/cli/src/executor/init.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/executor/init.rs
🧬 Code graph analysis (2)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (2)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (6)
  • new (125-143)
  • new (891-895)
  • new (1162-1210)
  • new (1681-1691)
  • contract (817-821)
  • contract (979-988)
codegenerator/cli/src/config_parsing/contract_import/converters.rs (2)
  • new (17-27)
  • new (98-103)
codegenerator/cli/src/executor/init.rs (1)
codegenerator/cli/src/config_parsing/graph_migration/mod.rs (1)
  • generate_config_from_subgraph_id (234-405)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (6)
codegenerator/cli/src/executor/init.rs (3)

82-85: LGTM - Simplified function signature.

The removal of the language parameter from generate_config_from_subgraph_id aligns with the PR's objective to make handler paths optional with filesystem auto-loading. The function now correctly derives configuration without language-specific path resolution.


169-169: LGTM - Correct ecosystem flag.

Passing true for is_fuel in the Fuel contract import path correctly identifies the ecosystem for downstream handler generation.


223-223: LGTM - Correct ecosystem flag.

Passing false for is_fuel in the EVM contract import path correctly identifies the ecosystem for downstream handler generation.

codegenerator/cli/src/hbs_templating/contract_import_templates.rs (3)

243-305: LGTM - Well-structured TypeScript handler generation.

The handler content generation correctly:

  • Imports contract modules and entity types
  • Constructs entity objects with proper ID generation
  • Handles tuple param accessor indexes with array notation
  • Maintains consistent formatting

308-363: LGTM - ReScript handler generation with appropriate type conversions.

The ReScript handler generation correctly applies language-specific conventions:

  • Uses contract.name.uncapitalized for entity types (ReScript convention)
  • Chains Utils.Tuple.get(index)->Belt.Option.getUnsafe for nested tuple accessors
  • Applies Address.toString conversion for address types

Note: The chained getUnsafe operations assume the tuple structure matches the config. This is appropriate for the init/migration flow where the structure is known upfront.


551-589: LGTM - Proper integration of handler file generation.

The updated method correctly:

  • Adds the is_fuel parameter to distinguish ecosystems
  • Calls generate_handler_files before template generation
  • Maintains the existing template generation flow for test files
  • Includes helpful comment explaining the split between file generation and templates

@DZakh DZakh requested a review from JonoPrest November 13, 2025 09:20

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (1)

23-23: Fix typo in comment.

"Relatvie" should be "Relative".

-  // Relatvie to cwd (project root)
+  // Relative to cwd (project root)
🧹 Nitpick comments (3)
codegenerator/cli/src/config_parsing/system_config.rs (2)

724-724: Consider using field init shorthand.

Since the field name matches the variable name, you can simplify this to just human_config, (Rust field initialization shorthand).

-                    human_config: human_config,
+                    human_config,

864-864: Consider using field init shorthand.

Same as the EVM branch, you can simplify this to just human_config,.

-                    human_config: human_config,
+                    human_config,
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (1)

37-51: Consider normalizing the file path.

The glob pattern returns paths with a leading ./ (e.g., ./src/handlers/foo.js), which when concatenated with ../{{relative_path_to_root_from_generated}}/ results in a path like ../../.././src/handlers/foo.js with a redundant ./. While this typically works, you could normalize by stripping the leading ./ from the glob results for cleaner paths.

Example approach:

  handlerFiles->Js.Array2.forEach(file => {
    try {
-      %raw(`require("../{{relative_path_to_root_from_generated}}/" + file)`)
+      let normalizedPath = file->Js.String2.replace("./", "")
+      %raw(`require("../{{relative_path_to_root_from_generated}}/" + normalizedPath)`)
    } catch {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef04bf6 and 2861bc4.

📒 Files selected for processing (8)
  • codegenerator/cli/npm/envio/evm.schema.json (3 hunks)
  • codegenerator/cli/npm/envio/fuel.schema.json (3 hunks)
  • codegenerator/cli/src/cli_args/init_config.rs (4 hunks)
  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs (4 hunks)
  • codegenerator/cli/src/config_parsing/human_config.rs (10 hunks)
  • codegenerator/cli/src/config_parsing/system_config.rs (6 hunks)
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs (6 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/npm/envio/fuel.schema.json
  • codegenerator/cli/src/config_parsing/human_config.rs
  • codegenerator/cli/src/cli_args/init_config.rs
  • codegenerator/cli/npm/envio/evm.schema.json
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
codegenerator/cli/npm/envio/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Shared library-fied runtime lives in codegenerator/cli/npm/envio

Files:

  • codegenerator/cli/npm/envio/fuel.schema.json
  • codegenerator/cli/npm/envio/evm.schema.json
codegenerator/cli/templates/dynamic/**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
{codegenerator/cli/templates/static/codegen/src/**,codegenerator/cli/templates/dynamic/codegen/src/**}

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Template versions of runtime live under templates/{static,dynamic}/codegen/src and are the recommended editing targets

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
codegenerator/cli/src/hbs_templating/codegen_templates.rs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

hbs_templating/codegen_templates.rs feeds templates

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧠 Learnings (6)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/human_config.rs : human_config.rs reads user files and JSON schemas

Applied to files:

  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/config_parsing/human_config.rs
  • codegenerator/cli/src/cli_args/init_config.rs
  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/config_parsing/system_config.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/** : The Rust CLI lives in codegenerator/cli

Applied to files:

  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/lib.rs : CLI entry point is codegenerator/cli/src/lib.rs

Applied to files:

  • codegenerator/cli/src/config_parsing/graph_migration/mod.rs
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/static/**/*.res : Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Applied to files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/hbs_templating/codegen_templates.rs : hbs_templating/codegen_templates.rs feeds templates

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
🧬 Code graph analysis (2)
codegenerator/cli/src/cli_args/init_config.rs (1)
codegenerator/cli/src/utils/unique_hashmap.rs (1)
  • try_insert (4-17)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (2)
codegenerator/cli/src/project_paths/path_utils.rs (1)
  • add_trailing_relative_dot (93-97)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (3)
  • from_config_contract (222-241)
  • contract (227-231)
  • config (499-509)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (15)
codegenerator/cli/src/config_parsing/system_config.rs (6)

419-419: LGTM: New optional handlers field added.

The handlers: Option<String> field properly supports the auto-loading feature described in the PR objectives.


185-185: LGTM: Handler path made optional.

The change from String to Option<String> correctly supports optional handler path specification with fallback to auto-loading.


191-196: LGTM: Constructor signature updated correctly.

The Contract::new signature now accepts handler_path: Option<String>, and all call sites in the file have been updated to match the new signature.


723-723: LGTM: Handlers field properly propagated.

The handlers field is correctly propagated from evm_config to SystemConfig.


863-863: LGTM: Handlers field properly propagated for Fuel.

The handlers field is correctly propagated from fuel_config to SystemConfig, consistent with the EVM code path.


2092-2092: LGTM: Test fixtures updated correctly.

The test configurations properly include the new handlers: None field, maintaining test validity after the struct changes.

Also applies to: 2140-2140

codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (3)

3-18: LGTM: Clean refactor to optional handler.

The simplified signature using option<string> is idiomatic and type-safe, and the enhanced error message will aid debugging.


128-147: LGTM: Async conversion is correct.

The function properly awaits auto-loading before contract-specific handler registration, and the updated call sites correctly pass Some(...) or None to match the new signature.


222-238: LGTM: Async conversion is correct.

The function properly awaits handler registration and correctly stores the result in the indexer's registrations field.

codegenerator/cli/src/hbs_templating/codegen_templates.rs (6)

21-21: LGTM! Clean removal of HandlerPathsTemplate.

The import change correctly reflects the simplified handler path approach, removing the now-unused HandlerPathsTemplate while retaining ParsedProjectPaths for path operations.


1283-1286: LGTM! Well-named fields for enhanced path handling.

The addition of relative_path_to_generated_from_root and handlers_path fields provides the necessary information for template generation with filesystem auto-loading. The field names are descriptive and the Option<String> type for handlers_path correctly reflects its optional nature.


1309-1309: Function call updated correctly.

The call to ContractTemplate::from_config_contract correctly uses the updated signature with cfg_contract and cfg parameters, consistent with the simplified handler path approach.


1362-1364: Path computation logic is correct.

The computation of relative_path_to_generated_from_root uses the same diff_from_current helper as the existing relative_path_to_root_from_generated field, ensuring consistency. The symmetric path calculations (root↔generated) are properly implemented with appropriate error context.


1407-1410: Verify upstream validation of cfg.handlers path representation.

The handlers field lacks validation throughout the configuration parsing pipeline. It is defined as Option<String> in both EVM and Fuel config structs with no validation decorators, passed directly to SystemConfig, and then to ProjectTemplate without any path validation. While the field is optional (None is acceptable), when Some, it represents a path according to documentation but receives no validation. Confirm whether downstream consumers validate this path or if validation should be added at the SystemConfig or configuration parsing level.


807-816: Handler field is unused dead code—change is safe.

The handler field in ContractTemplate (line 807) is assigned from contract.handler_path at line 816 but is never accessed anywhere. The field does not appear in any .hbs templates nor is it referenced in the codebase after assignment, making it dead code. The simplification from HandlerPathsTemplate to Option<String> is appropriate for this unused field. No validation is required since the field is never actually consumed.

}
}

@module("node:fs/promises") external globIterator: string => promise<Utils.asyncIterator<string>> = "glob"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the minimum Node.js version requirement.

The glob function from node:fs/promises was introduced in Node.js v22.2.0, but line 31 mentions 22.10.0. Confirm whether 22.10.0 is truly required or if this should reference an earlier 22.x version.


🌐 Web query:

What version of Node.js introduced the glob function in node:fs/promises module?

💡 Result:

The glob function in node:fs/promises was introduced in Node.js v22.0.0. [1][2]

Sources:
[1] Node.js fs (current docs) — fsPromises.glob history (Added in: v22.0.0).
[2] Node.js v22.10.0 documentation — fsPromises.glob (Added in: v22.0.0).


Update Node.js version requirement to v22.0.0.

The glob function in node:fs/promises was introduced in Node.js v22.0.0, so the minimum version requirement at line 31 should be updated accordingly rather than requiring 22.10.0.

🤖 Prompt for AI Agents
In codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs around line
20 (and update the version check at line 31), the Node.js minimum version was
set to 22.10.0 but the `glob` export from node:fs/promises is available since
v22.0.0; change the required version string/constant from "22.10.0" to "22.0.0"
(or the variable that holds the minimum Node version) so the template and any
runtime/version check use 22.0.0 instead of 22.10.0.

@DZakh

DZakh commented Nov 17, 2025

Copy link
Copy Markdown
Member Author

I decided to turn it into a first v3 alpha, since the feature is a little bit tricky and requires to use node.js 22+ and ideally below 22.10, since higher versions work weirdly with commonjs + mocha

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scenarios/test_codegen/test/lib_tests/PgStorage_test.res (1)

182-183: Critical: Duplicate index generation confirmed in PgStorage.makeInitializeTransaction.

The duplicate indices are generated by the implementation logic, not just in the test expectation. The bug occurs because:

  1. First index creation (lines 164-170): The allTables loop calls makeCreateTableIndicesQuery on entity A's table, generating CREATE INDEX "A_b_id"...
  2. Second index creation (lines 172-185): The derived indices loop processes A's derived-from fields and generates a duplicate CREATE INDEX "A_b_id"... for the same field

Entity A's b_id field is being indexed twice because it's both a regular indexed field and a derived-from field. The derived indices loop should skip fields that are already indexed via the first loop.

Location: codegenerator/cli/npm/envio/src/PgStorage.res, lines 172-185 in makeInitializeTransaction

Fix required: Before creating a derived index, verify that it hasn't already been created as a regular index. Consider adding a check to prevent duplicate index generation for fields that appear in both categories.

♻️ Duplicate comments (2)
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (2)

20-33: Align Node.js version message with actual supported minimum

The error text currently hardcodes “Node.js 22.10.0” as the version to check for, while the PR notes this feature as “Node 22+” (and even “preferably below 22.10”). To avoid confusing users, it’d be better to:

  • Decide the real minimum supported version (e.g. “>= 22.0.0” or whatever engines/CI enforce), and
  • Update this message (and any other references) to match that single source of truth.

23-23: Fix spelling in comment

Minor typo: “Relatvie” → “Relative”.

-  // Relatvie to cwd (project root)
+  // Relative to cwd (project root)
🧹 Nitpick comments (2)
codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (2)

24-52: Confirm .ts handler loading story or narrow the glob

srcPattern includes both *.js and *.ts, and autoLoadFromSrcHandlers immediately requires each matched file. That assumes the runtime can load .ts files (e.g. via ts-node, SWC register, or a similar hook). In a plain Node.js setup this will throw for every .ts handler and abort registration.

You might want to either:

  • Explicitly document that a TS loader is required at runtime for src/handlers/**/*.ts, or
  • Narrow the default glob to compiled JS only (and let users point handlers_path at built artifacts if they want).

For example, if you choose the latter:

-  let srcPattern = `./{{#if handlers_path}}{{handlers_path}}{{else}}src/handlers{{/if}}/**/*.{js,ts}`
+  let srcPattern = `./{{#if handlers_path}}{{handlers_path}}{{else}}src/handlers{{/if}}/**/*.js`

128-147: Keep handler auto-load comment in sync with glob behavior

The implementation auto-loads *.js and *.ts (per srcPattern), but the comment says “all .js files”. Consider updating the wording to “handler files” or “.js/.ts files” so it matches the actual glob.

For example:

-  // Auto-load all .js files from src/handlers directory
+  // Auto-load all handler files (e.g. .js/.ts) from src/handlers directory
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2861bc4 and bdfef00.

⛔ Files ignored due to path filters (1)
  • scenarios/test_codegen/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • codegenerator/cli/npm/envio/package.json (1 hunks)
  • codegenerator/cli/npm/envio/package.json.tmpl (1 hunks)
  • codegenerator/cli/npm/envio/src/Utils.res (2 hunks)
  • codegenerator/cli/npm/envio/src/db/InternalTable.res (0 hunks)
  • codegenerator/cli/src/hbs_templating/codegen_templates.rs (6 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (3 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (1 hunks)
  • scenarios/test_codegen/test/helpers/Mock.res (1 hunks)
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res (3 hunks)
💤 Files with no reviewable changes (1)
  • codegenerator/cli/npm/envio/src/db/InternalTable.res
🚧 Files skipped from review as they are similar to previous changes (5)
  • codegenerator/cli/npm/envio/package.json
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs
  • codegenerator/cli/npm/envio/src/Utils.res
  • codegenerator/cli/npm/envio/package.json.tmpl
  • scenarios/test_codegen/test/helpers/Mock.res
🧰 Additional context used
📓 Path-based instructions (5)
codegenerator/cli/**

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

The Rust CLI lives in codegenerator/cli

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
codegenerator/cli/src/hbs_templating/codegen_templates.rs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

hbs_templating/codegen_templates.rs feeds templates

Files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
codegenerator/cli/templates/dynamic/**/*.hbs

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Dynamic templates are Handlebars files under codegenerator/cli/templates/dynamic

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
{codegenerator/cli/templates/static/codegen/src/**,codegenerator/cli/templates/dynamic/codegen/src/**}

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Template versions of runtime live under templates/{static,dynamic}/codegen/src and are the recommended editing targets

Files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
**/*.res

📄 CodeRabbit inference engine (.cursor/rules/navigation.mdc)

Prefer reading ReScript .res modules directly

Files:

  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
🧠 Learnings (7)
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/hbs_templating/codegen_templates.rs : hbs_templating/codegen_templates.rs feeds templates

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/system_config.rs : system_config.rs converts to internal structs

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/lib.rs : CLI entry point is codegenerator/cli/src/lib.rs

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/** : The Rust CLI lives in codegenerator/cli

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/src/human_config.rs : human_config.rs reads user files and JSON schemas

Applied to files:

  • codegenerator/cli/src/hbs_templating/codegen_templates.rs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to codegenerator/cli/templates/static/**/*.res : Static templates are raw ReScript files copied verbatim under codegenerator/cli/templates/static

Applied to files:

  • codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs
📚 Learning: 2025-10-21T16:31:22.127Z
Learnt from: CR
Repo: enviodev/hyperindex PR: 0
File: .cursor/rules/navigation.mdc:0-0
Timestamp: 2025-10-21T16:31:22.127Z
Learning: Applies to generated/src/PgStorage.res : In generated runtime, PgStorage.res is part of the persistence stack

Applied to files:

  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res
🧬 Code graph analysis (1)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (2)
codegenerator/cli/src/project_paths/path_utils.rs (1)
  • add_trailing_relative_dot (93-97)
codegenerator/cli/src/hbs_templating/contract_import_templates.rs (3)
  • from_config_contract (222-241)
  • contract (227-231)
  • config (499-509)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
🔇 Additional comments (8)
codegenerator/cli/src/hbs_templating/codegen_templates.rs (5)

807-807: LGTM! Handler field simplified to support optional autoloading.

The change from HandlerPathsTemplate to Option<String> aligns with the PR's autoload feature and simplifies the contract template structure.


811-816: LGTM! Handler path extraction simplified.

The direct clone of contract.handler_path is straightforward and correctly aligns with the new optional handler path structure.


1283-1283: LGTM! New fields support autoload feature.

The addition of relative_path_to_generated_from_root and handlers_path enables bidirectional path resolution and optional handler directory specification, supporting the filesystem auto-loading feature.

Also applies to: 1286-1286


1309-1309: LGTM! Call site correctly updated.

The call to from_config_contract correctly passes both cfg_contract and cfg parameters, matching the updated function signature.


1407-1407: LGTM! New fields correctly assigned.

The new relative_path_to_generated_from_root and handlers_path fields are correctly assigned from computed values and config, respectively.

Also applies to: 1410-1410

scenarios/test_codegen/test/lib_tests/PgStorage_test.res (1)

169-169: LGTM! Schema change aligns with PR objectives.

The removal of handler_files_hash from the persisted_state table is consistent with the PR's introduction of filesystem auto-loading for handlers. The remaining abi_files_hash field is appropriate as ABI files remain part of the configuration hash validation.

Also applies to: 248-248, 330-330

codegenerator/cli/templates/dynamic/codegen/src/Generated.res.hbs (2)

3-18: Optional handler path handling looks good

The new option<string>-based registerContractHandlers cleanly separates “no handler” from “use this path” and preserves behavior while improving error context. No changes needed here.


228-244: Let me verify if there are any additional getIndexer references in the dynamic templates that might need checking:

Based on the verification results, the grep search found all getIndexer() call sites in the repository:

  1. Test file (scenarios/test_codegen/test/E2EEthNode_test.res:72): Uses await Generated.getIndexer()
  2. Static template (codegenerator/cli/templates/static/codegen/src/Index.res:232): Uses await Generated.getIndexer()

Both call sites properly await the now-async function. ReScript's compiler enforces that "using await outside of an async function is an error," so any missed awaits would have been caught at compile time.

The original review comment's concern about guarding against concurrent initialization (potential double-initialization) remains a valid but optional hardening suggestion rather than a blocking issue, since the current implementation with the ref pattern will simply return the cached result on subsequent calls.


Call site awaits are correctly updated; no blocking issues remain

Both known call sites properly await the async getIndexer(). The static template at codegenerator/cli/templates/static/codegen/src/Index.res:232 and test file at scenarios/test_codegen/test/E2EEthNode_test.res:72 both use await correctly.

The suggestion to guard against concurrent initialization (e.g., by caching an "initialization in progress" promise) remains optional—the current ref-based caching pattern will handle subsequent calls correctly by returning the cached indexer.

Comment thread codegenerator/cli/src/hbs_templating/codegen_templates.rs Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Comment on lines +22 to +24
"engines": {
"node": ">=22.0.0 <=22.10.0"
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about this, why do we need <=22.10 again? I use v24 on my machine for eg

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mocha starts attempting to run tests in esm, which breaks in some cases

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reasoning that this PR will go to v3.0.0-alpha.0, so it's fine to have the limitation, since one of the next alphas will bring ESM only mode, and lift the restriction of node.js <=22.10

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no problmes with running the indexer, only when running mocha

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah cool 👍🏼 so this will not be the latest version for some time

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, until ESM support

registrations
} else {
Generated.registerAllHandlers()
await Generated.registerAllHandlers()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I seem to remember if we made this async it causes problems for the testing framework. Does that still work fine?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I changed the testing framework some time ago to support this case

import assert from "assert";
import { TestHelpers, User } from "generated";
import { TestHelpers } from "generated";
import type { User } from "generated";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this because we're using interfaces now or something?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this was an issue when I ran mocha with node >=22.10 and it used esm module resolution and didn't know what a type is.

@JonoPrest JonoPrest left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool Dmitry,

Looking good :) exciting to be thinking about v3

@DZakh DZakh merged commit 0b2a34d into main Nov 20, 2025
2 checks passed
@DZakh DZakh deleted the dz/src-handlers branch November 20, 2025 10:59
@coderabbitai coderabbitai Bot mentioned this pull request Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants