This guide will help you contribute to the Infisical SDK.
.env file content
cargo test
to ensure that all tests pass.cargo test
from the root directory. You must always run tests before opening a pull request.
Execution flow diagram for the SDK from the target language to the base SDK. The execution flow is the same for all target languages.
cargo test
from the root directory.
infisical-json
crate, which executes “commands” from the base SDK. If you need to create a new target-language specific crate, please try to create native bindings for the target language. Some languages don’t have direct support for native bindings (Java as an example). In those cases we can use the C bindings (crates/infisical-c
) in the target language.
crates/infisical
), we define all the inputs/outputs.
If you are interested in reading about QuickType works under the hood, you can read more here.
This is an example of a type defined in Rust (both input and output). For this to become a generated type, you’ll need to add it to our schema generator. More on that further down.
crates/sdk-schemas/src/main.rs
.
Simply add the output (also called response), to the write_schema_for_response!
macro. This will let QuickType know that it should generate types for the given structs. The main function will look something like this:
schemas.ts
file found in the support/scripts
folder. If you are adding a new language, it’s important that you add the language to the code.
This is an example of how how we generate types for Node.js:
infisical_py.so
. After renaming it you also need to move it into the root of the crates/infisical-py
folder./target
directory at the root of the project.
You have to manually move the generated file into the languages/java/src/main/resources
directory.Result
with an error message. We have a custom Result type defined in the error.rs
file in the base SDK.
All our errors are defined in an enum called Error
. The Error
enum is defined in the error.rs
file in the base SDK. The Error
enum is used in the Result
type, which is used as the return type for all functions in the base SDK.
crates/infisical/src/api/secrets/create_secret.rs
. When the error happened due to a request error to our API, we have an API error handler. This prevents duplicate code and keeps error handling consistent across the SDK. You can find the api error handler in the error.rs
file.
success (boolean)
, data (could be anything or nothing)
, and errorMessage (string or null)
.
The success
field is used to determine if the request was successful or not. The data
field is used to return data from the SDK. The errorMessage
field is used to return an error message if the request was not successful.
This means that if the success if false or if the error message is not null, something went wrong and we should throw an error on the target-language level, with the error message.
infisical-json
crate), takes care of executing commands sent from the target language. It also takes care of parsing the input and output to and from JSON. The command handler is the only part of the base SDK that should be aware of JSON. The rest of the base SDK should be completely unaware of JSON, and only work with the Rust structs defined in the base SDK.
The command handler exposes a function called run_command
, which is what we use in the target language to execute commands. The function takes a json string as input, and returns a json string as output. We use helper functions generated by QuickType to convert the input and output to and from JSON.
CreateSecret
command. We will use that as an example here as well.
crates/infisical/src/manager/secrets.rs
file.
crates/infisical-json/src/command.rs
file. The Command
enum is what we use to define new commands.
In the codesnippet below we define a new command called CreateSecret
. The CreateSecret
command takes a CreateSecretOptions
struct as input. We don’t have to define the output, because QuickType’s converter helps us with figuring out the return type for each command.
crates/infisical-json/src/client.rs
file. The run_command
function is what we use to execute commands.
In the Client implementation we try to parse the JSON string into a Command
enum. If the parsing is successful, we match the command and execute the corresponding function.
languages/node
directory:
infisical-napi
crate, and move the generated bindings to the appropriate folder.
After building the new bindings, you can access the new functionality in the Node.js SDK source.