Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: String Storage ADO #512

Merged

Conversation

mdjakovic0920
Copy link
Contributor

@mdjakovic0920 mdjakovic0920 commented Jul 9, 2024

Motivation

Make an ADO that is similar to key/value primitive ADO but it also stores only single string value.

Implementation

String Storage can be set to be one of the following:

Private: Only the owner is allowed to set/remove values.

Public: String Storage is open to anyone similar to a public database.

Restricted: Only the user that set the value is able to modify/remove it.

Testing

Added unit-testing of smart contract

Version Changes

Contract version is set at 1.0.0

Summary by CodeRabbit

  • New Features

    • Introduced a string storage contract with functionalities for instantiation, execution, querying, and migration.
    • Implemented access controls for stored strings, allowing varying levels of privacy (Private, Public, Restricted).
    • Added mock implementations for testing string storage operations, including instantiation and querying data.
  • Bug Fixes

    • Enhanced validation logic for string values to ensure compliance with defined restrictions.
  • Tests

    • Added a comprehensive suite of test cases to validate the string storage contract's functionality and restrictions.

Copy link
Contributor

coderabbitai bot commented Jul 9, 2024

Walkthrough

The updates enhance the andromeda-string-storage contract by introducing a structured framework for managing string storage. Key changes include new modules for contract functionality, execution logic, testing, and state management. Significant components include the implementation of execution and query handlers, mock implementations, state definitions, and comprehensive unit tests to ensure robust functionality.

Changes

File Change Summary
contracts/.../config Introduces aliases for build and test commands related to Wasm and schema operations.
contracts/.../Cargo.toml Updates dependencies and configurations for testing and backtraces.
contracts/.../examples/schema.rs Adds logic for defining messages for instantiation, querying, and execution.
contracts/.../src/contract.rs Implements functionality for string storage, including entry points for instantiation, execution, querying, and migration.
contracts/.../src/execute.rs Introduces logic for handling execution messages, such as updating restrictions and setting values.
contracts/.../src/lib.rs Defines the module structure for the string storage contract project.
contracts/.../src/mock.rs Provides mock implementations for instantiation, setting values, adding rates, and querying data.
contracts/.../src/query.rs Implements functions for checking permissions, retrieving values, and getting data owners.
contracts/.../src/state.rs Defines constants for items related to string storage.
contracts/.../src/testing/... Adds mock functions and test cases for string storage functionality.
packages/.../src/lib.rs Adds a new module string_storage to the andromeda-data-storage package.
packages/.../src/string_storage.rs Introduces message structures and validation logic for string storage.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Contract
    participant Storage

    User->>Contract: Instantiate(InstantiateMsg)
    Contract->>Storage: Save initial state
    Storage-->>Contract: Acknowledgement
    Contract-->>User: Response

    User->>Contract: Execute(ExecuteMsg)
    Contract->>Storage: Perform action based on ExecuteMsg
    Storage-->>Contract: Acknowledgement
    Contract-->>User: Response

    User->>Contract: Query(QueryMsg)
    Contract->>Storage: Retrieve data
    Storage-->>Contract: Data
    Contract-->>User: QueryResponse
Loading

Poem

In the realm of code so bright,
Strings now stored with all their might.
Mocking values, testing true,
Execution flows anew.
Andromeda's shining star,
Data safe, both near and far.
CodeRabbit hops with glee,
In this contract, perfection we see.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d545085 and 9ab6409.

Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
Files selected for processing (14)
  • contracts/data-storage/andromeda-string-storage/.cargo/config (1 hunks)
  • contracts/data-storage/andromeda-string-storage/Cargo.toml (1 hunks)
  • contracts/data-storage/andromeda-string-storage/examples/schema.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/contract.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/execute.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/lib.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/mock.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/query.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/state.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/mock.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/mod.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/tests.rs (1 hunks)
  • packages/andromeda-data-storage/src/lib.rs (1 hunks)
  • packages/andromeda-data-storage/src/string_storage.rs (1 hunks)
Files skipped from review due to trivial changes (4)
  • contracts/data-storage/andromeda-string-storage/.cargo/config
  • contracts/data-storage/andromeda-string-storage/src/state.rs
  • contracts/data-storage/andromeda-string-storage/src/testing/mod.rs
  • packages/andromeda-data-storage/src/lib.rs
Additional comments not posted (58)
contracts/data-storage/andromeda-string-storage/src/lib.rs (6)

1-1: Module import contract is appropriate.

The contract module is necessary for the main contract logic.


2-2: Module import execute is appropriate.

The execute module is necessary for handling execution messages.


3-4: Module import mock is appropriate.

The mock module is necessary for testing and is conditionally compiled.


5-5: Module import query is appropriate.

The query module is necessary for handling query messages.


6-6: Module import state is appropriate.

The state module is necessary for managing the contract's state.


8-9: Module import testing is appropriate.

The testing module is necessary for testing and is conditionally compiled.

contracts/data-storage/andromeda-string-storage/examples/schema.rs (4)

1-1: Schema definition for InstantiateMsg is appropriate.

The InstantiateMsg schema is necessary for instantiating the contract.


1-1: Schema definition for QueryMsg is appropriate.

The QueryMsg schema is necessary for querying the contract.


1-1: Schema definition for ExecuteMsg is appropriate.

The ExecuteMsg schema is necessary for executing the contract.


3-10: Schema generation using write_api is appropriate.

The write_api macro is necessary for generating the schema for instantiation, query, and execution messages.

contracts/data-storage/andromeda-string-storage/Cargo.toml (6)

1-6: Package metadata is appropriate.

The package metadata includes necessary information such as name, version, authors, edition, and rust-version.


8-12: Exclude section is appropriate.

The exclude section lists files that should not be part of the source code publication.


16-17: Lib section is appropriate.

The lib section defines the crate types as cdylib and rlib.


19-24: Features section is appropriate.

The features section defines optional features such as backtraces, library, and testing.


26-36: Dependencies section is appropriate.

The dependencies section lists the necessary dependencies for the package.


38-40: Target dependencies section is appropriate.

The target dependencies section lists dependencies for non-Wasm targets.

contracts/data-storage/andromeda-string-storage/src/query.rs (3)

6-20: Function has_permission is appropriate.

The function checks if an address has permission to access the stored data based on the restriction type and ownership.


22-27: Function get_value is appropriate.

The function retrieves the stored value and returns it in a response structure.


29-34: Function get_data_owner is appropriate.

The function retrieves the owner of the stored data and returns it in a response structure.

contracts/data-storage/andromeda-string-storage/src/testing/mock.rs (5)

18-29: LGTM!

The proper_initialization function correctly initializes the mock dependencies and calls the instantiate function with the appropriate parameters.


31-37: LGTM!

The query_value function correctly handles the query and returns the expected result.


39-49: LGTM!

The set_value function correctly sets the value in the contract by calling the execute function with the appropriate parameters.


51-62: LGTM!

The set_value_with_funds function correctly sets the value in the contract with the provided funds by calling the execute function with the appropriate parameters.


64-71: LGTM!

The delete_value function correctly deletes the value from the contract by calling the execute function with the appropriate parameters.

contracts/data-storage/andromeda-string-storage/src/contract.rs (4)

23-44: LGTM!

The instantiate function correctly initializes the contract and saves the restriction to the state.


47-60: LGTM!

The execute function correctly handles execution messages by creating an ExecuteContext and dispatching the message to the appropriate handler.


63-69: LGTM!

The query function correctly handles query messages by dispatching the message to the appropriate handler.


72-74: LGTM!

The migrate function correctly handles migration by calling the ADOContract's migrate method.

packages/andromeda-data-storage/src/string_storage.rs (8)

5-9: LGTM!

The InstantiateMsg type definition is correct and follows best practices.


11-21: LGTM!

The ExecuteMsg type definition is correct and follows best practices.


23-31: LGTM!

The QueryMsg type definition is correct and follows best practices.


33-49: LGTM!

The StringStorage type definition and validation logic are correct and follow best practices.


74-79: LGTM!

The StringStorageRestriction type definition is correct and follows best practices.


81-84: LGTM!

The GetValueResponse type definition is correct and follows best practices.


86-89: LGTM!

The GetDataOwnerResponse type definition is correct and follows best practices.


91-141: LGTM!

The tests module includes comprehensive test cases that cover various scenarios for the string storage contract. The test functions follow best practices and ensure the correctness of the contract.

contracts/data-storage/andromeda-string-storage/src/mock.rs (8)

16-40: LGTM!

The MockStringStorage struct and its implementation provide mock functions for instantiating and interacting with the string storage contract. The functions follow best practices and ensure the correctness of the contract interactions.


42-56: LGTM!

The execute_set_value function correctly sets the value in the contract by calling the execute_contract function with the appropriate parameters.


58-66: LGTM!

The execute_add_rate function correctly adds the rate to the contract by calling the execute function with the appropriate parameters.


68-72: LGTM!

The query_value function correctly handles the query and returns the expected result.


74-78: LGTM!

The query_data_owner function correctly handles the query and returns the expected result.


81-84: LGTM!

The mock_andromeda_string_storage function correctly returns a boxed contract for the string storage.


86-95: LGTM!

The mock_string_storage_instantiate_msg function correctly creates the instantiation message for the string storage contract.


98-113: LGTM!

The utility functions correctly create various messages for interacting with the string storage contract.

contracts/data-storage/andromeda-string-storage/src/execute.rs (5)

22-48: LGTM! Verify the message handling logic.

The function is well-structured and handles various execution messages. Ensure that the logic for handling different message types is correct and that all necessary checks and balances are in place.


51-65: LGTM!

The function includes necessary checks for authorization and ensures the transaction is non-payable. The logic appears correct.


67-101: LGTM!

The function is comprehensive and includes necessary checks and balances. The logic for handling tax deductions is well-implemented.


104-117: LGTM!

The function includes necessary checks for authorization and ensures the transaction is non-payable. The logic appears correct.


119-158: LGTM!

The function is well-implemented and includes necessary logic for handling tax calculations and refunds. The use of ADOContract::default().query_deducted_funds is appropriate.

contracts/data-storage/andromeda-string-storage/src/testing/tests.rs (9)

20-23: LGTM!

The test function is well-structured and covers the initialization scenario adequately.


25-56: LGTM!

The test function covers both setting and updating scenarios and includes assertions to verify the correctness of the operations.


58-157: LGTM!

The test function is comprehensive and covers various scenarios for handling tax deductions. The assertions verify the correctness of the operations.


159-185: LGTM!

The test function covers invalid scenarios and includes assertions to verify the correctness of error handling.


188-195: LGTM!

The test function covers the deletion scenario and includes assertions to verify the correctness of the operation.


197-220: LGTM!

The test function covers various scenarios for the private restriction mode and includes assertions to verify the correctness of the operations.


222-247: LGTM!

The test function covers various scenarios for the public restriction mode and includes assertions to verify the correctness of the operations.


249-292: LGTM!

The test function covers various scenarios for the restricted restriction mode and includes assertions to verify the correctness of the operations.


294-311: LGTM!

The test function covers the scenario for querying the data owner and includes assertions to verify the correctness of the operation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9ab6409 and 2087220.

Files selected for processing (1)
  • contracts/data-storage/andromeda-string-storage/src/mock.rs (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • contracts/data-storage/andromeda-string-storage/src/mock.rs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Outside diff range, codebase verification and nitpick comments (11)
contracts/data-storage/andromeda-string-storage/src/testing/mock.rs (3)

39-49: Clarify the purpose of set_value.

The function set_value sets a value using the ExecuteMsg::SetValue message. Ensure that the function's purpose is clear and documented, especially regarding its use in tests.


51-62: Clarify the purpose of set_value_with_funds.

The function set_value_with_funds is similar to set_value but includes a coin. Ensure that the function's purpose and differences from set_value are clear and documented.


64-68: Clarify the purpose of delete_value.

The function delete_value deletes a value using the ExecuteMsg::DeleteValue message. Ensure that the function's purpose is clear and documented, especially regarding its use in tests.

packages/andromeda-data-storage/src/string_storage.rs (8)

5-9: Consider documenting the InstantiateMsg structure.

The InstantiateMsg structure defines the initialization parameters. Consider adding documentation to clarify its fields and usage.


11-21: Consider documenting the ExecuteMsg variants.

The ExecuteMsg enum defines the execution messages. Consider adding documentation to clarify each variant's purpose and usage.


23-31: Consider documenting the QueryMsg variants.

The QueryMsg enum defines the query messages. Consider adding documentation to clarify each variant's purpose and usage.


33-36: Consider documenting the StringStorage enum.

The StringStorage enum defines the storage type. Consider adding documentation to clarify its purpose and usage.


63-69: Consider documenting the try_get_value function.

The try_get_value function retrieves the string value. Consider adding documentation to clarify its purpose and usage.


71-76: Consider documenting the StringStorageRestriction enum.

The StringStorageRestriction enum defines access restrictions. Consider adding documentation to clarify each variant's purpose and usage.


78-81: Consider documenting the GetValueResponse structure.

The GetValueResponse structure defines the response for a value query. Consider adding documentation to clarify its fields and usage.


83-86: Consider documenting the GetDataOwnerResponse structure.

The GetDataOwnerResponse structure defines the response for a data owner query. Consider adding documentation to clarify its fields and usage.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 2087220 and cb3e854.

Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
Files selected for processing (10)
  • contracts/data-storage/andromeda-string-storage/examples/schema.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/contract.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/execute.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/mock.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/query.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/state.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/mock.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/mod.rs (1 hunks)
  • contracts/data-storage/andromeda-string-storage/src/testing/tests.rs (1 hunks)
  • packages/andromeda-data-storage/src/string_storage.rs (1 hunks)
Files skipped from review due to trivial changes (1)
  • contracts/data-storage/andromeda-string-storage/src/testing/mod.rs
Additional comments not posted (36)
contracts/data-storage/andromeda-string-storage/examples/schema.rs (1)

1-10: LGTM!

The code correctly uses the write_api macro to generate schema for the contract messages.

contracts/data-storage/andromeda-string-storage/src/state.rs (1)

1-7: LGTM!

The constants for storing data, data owner, and restriction type are well-defined using cw_storage_plus::Item.

contracts/data-storage/andromeda-string-storage/src/query.rs (3)

1-19: LGTM!

The has_permission function effectively checks permissions based on the restriction type and uses ADOContract for permission checks.


21-24: LGTM!

The get_value function correctly retrieves the stored value from DATA.


26-30: LGTM!

The get_data_owner function correctly retrieves the data owner and converts it to AndrAddr.

contracts/data-storage/andromeda-string-storage/src/testing/mock.rs (1)

1-3: Ensure imports are necessary and used.

The imports from andromeda_data_storage::string_storage are comprehensive. Verify that all imported entities are utilized within the file.

contracts/data-storage/andromeda-string-storage/src/contract.rs (4)

22-44: Ensure instantiation handles all edge cases.

The instantiate function sets up the contract with initial parameters. Ensure that all edge cases, such as invalid input or storage errors, are handled.


46-60: Ensure execution logic covers all message types.

The execute function delegates message handling to handle_execute. Ensure that all possible ExecuteMsg variants are covered and handled appropriately.


62-69: Ensure query logic covers all message types.

The query function handles different QueryMsg variants. Ensure that all possible query types are covered and handled appropriately.


71-74: Ensure migration logic is complete.

The migrate function updates the contract version. Ensure that all necessary migration steps are included and that the function handles potential errors.

packages/andromeda-data-storage/src/string_storage.rs (4)

1-3: Ensure all imports are necessary.

Verify that all imported entities from andromeda_std and cosmwasm_schema are utilized within the file.


38-46: Ensure validate function covers all cases.

The validate function checks for an empty string. Ensure that all potential invalid cases are covered and handled.


49-61: Ensure conversion implementations are correct.

The From implementations convert between StringStorage and String. Verify that these conversions are correct and cover all cases.


88-137: Ensure test coverage is comprehensive.

The test module includes tests for conversion, validation, and retrieval functions. Ensure that all edge cases and potential errors are covered in the tests.

contracts/data-storage/andromeda-string-storage/src/mock.rs (8)

16-17: LGTM! Struct definition is correct.

The MockStringStorage struct is appropriately defined for mocking purposes.


19-40: LGTM! Function implementation is correct.

The instantiate function correctly handles contract instantiation and returns the expected result.


42-55: LGTM! Function implementation is correct.

The execute_set_value function correctly handles the execution logic, including the optional funds parameter.


57-65: LGTM! Function implementation is correct.

The execute_add_rate function correctly handles rate addition logic.


67-71: LGTM! Function implementation is correct.

The query_value function correctly handles the query logic.


73-77: LGTM! Function implementation is correct.

The query_data_owner function correctly handles the query logic.


80-83: LGTM! Function implementation is correct.

The mock_andromeda_string_storage function correctly wraps the execute, instantiate, and query functions for testing.


85-112: LGTM! Function implementations are correct.

The functions for generating mock messages are correctly implemented for testing purposes.

contracts/data-storage/andromeda-string-storage/src/execute.rs (5)

18-44: LGTM! Function implementation is correct.

The handle_execute function correctly processes execution messages and delegates to specific handlers.


47-61: LGTM! Function implementation is correct.

The update_restriction function correctly updates the restriction setting with proper authorization checks.


63-98: LGTM! Function implementation is correct.

The set_value function correctly handles permissions, validation, and tax logic for setting a value.


100-112: LGTM! Function implementation is correct.

The delete_value function correctly removes a value with proper authorization checks.


114-152: LGTM! Function implementation is correct.

The tax_set_value function correctly calculates and handles tax for setting a value, including refund logic.

contracts/data-storage/andromeda-string-storage/src/testing/tests.rs (9)

21-24: LGTM! Test implementation is correct.

The test_instantiation function correctly tests the proper initialization of the String Storage ADO.


26-52: LGTM! Test implementation is correct.

The test_set_and_update_value function correctly tests setting and updating a value in the String Storage ADO.


54-146: LGTM! Test implementation is correct.

The test_set_value_with_tax function correctly tests setting a value with tax considerations, covering various scenarios.


156-172: LGTM! Test implementation is correct.

The test_set_value_invalid function correctly tests setting an invalid value, covering invalid input scenarios.


175-182: LGTM! Test implementation is correct.

The test_delete_value function correctly tests the deletion of a value in the String Storage ADO.


184-207: LGTM! Test implementation is correct.

The test_restriction_private function correctly tests the private restriction mode, covering various scenarios.


209-234: LGTM! Test implementation is correct.

The test_restriction_public function correctly tests the public restriction mode, covering various scenarios.


236-279: LGTM! Test implementation is correct.

The test_restriction_restricted function correctly tests the restricted restriction mode, covering various scenarios.


281-304: LGTM! Test implementation is correct.

The test_query_data_owner function correctly tests querying the data owner in the String Storage ADO.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between cb3e854 and 01ad147.

Files selected for processing (2)
  • CHANGELOG.md (1 hunks)
  • packages/andromeda-data-storage/src/string_storage.rs (1 hunks)
Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
Files skipped from review as they are similar to previous changes (1)
  • packages/andromeda-data-storage/src/string_storage.rs

@crnbarr93 crnbarr93 merged commit 62b6a54 into andromedaprotocol:development Aug 27, 2024
5 checks passed
@mdjakovic0920 mdjakovic0920 deleted the mdjakovic/string-ado branch September 2, 2024 15:19
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.

3 participants