{"id":21947949,"url":"https://github.com/j4c0b3y/configapi","last_synced_at":"2025-12-29T11:23:46.588Z","repository":{"id":263260838,"uuid":"889831047","full_name":"J4C0B3Y/ConfigAPI","owner":"J4C0B3Y","description":"Flexible and robust static access configuration api.","archived":false,"fork":false,"pushed_at":"2025-08-23T11:23:37.000Z","size":157,"stargazers_count":17,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-02T20:19:33.011Z","etag":null,"topics":["config-api"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/J4C0B3Y.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":"https://donate.j4c0b3y.net"}},"created_at":"2024-11-17T11:01:45.000Z","updated_at":"2025-09-01T09:50:29.000Z","dependencies_parsed_at":"2025-01-17T13:20:29.117Z","dependency_job_id":"e00441a0-d89f-44fa-a952-ae7f7b814ea5","html_url":"https://github.com/J4C0B3Y/ConfigAPI","commit_stats":null,"previous_names":["j4c0b3y/configapi"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/J4C0B3Y/ConfigAPI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J4C0B3Y%2FConfigAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J4C0B3Y%2FConfigAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J4C0B3Y%2FConfigAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J4C0B3Y%2FConfigAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/J4C0B3Y","download_url":"https://codeload.github.com/J4C0B3Y/ConfigAPI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/J4C0B3Y%2FConfigAPI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002681,"owners_count":26083442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config-api"],"created_at":"2024-11-29T05:10:49.569Z","updated_at":"2025-10-10T04:30:56.581Z","avatar_url":"https://github.com/J4C0B3Y.png","language":"Java","funding_links":["https://donate.j4c0b3y.net"],"categories":[],"sub_categories":[],"readme":"# ConfigAPI\n\nFlexible and robust static access configuration api.\n\n\u003e Special thanks to [dejvokep](https://github.com/dejvokep) for [BoostedYAML](https://github.com/dejvokep/boosted-yaml), \n\u003e which is used internally for yaml parsing and file management.\n\n###### Trusted and used by [Refine Development](https://refinedev.xyz/).\n\n## Features\n\n- Seamless static config value access\n- Use inbuilt or register custom type loading\n- Move config values with path relocations\n- Configurable config file backup system\n- Remove unused / unknown keys + logging\n- File structure and value formatting\n- Annotation based field modifiers\n- Automatic header and footer comments\n- User friendly message utility class\n- Supports kotlin's static classes\n- Small and lightweight (~500kb)\n\n## Support\n\nIf you need any assistance using or installing my ConfigAPI,\nfeel free to contact me by either adding me on discord (@J4C0B3Y)\nor by creating an issue and explaining your problem or question.\n\n## Installation\n\nPrebuilt jars can be found in [releases](https://github.com/J4C0B3Y/CommandAPI/releases).\n\n\u003e **NOTE:** \u003cbr\u003e\n\u003e It is recommended to relocate the library to prevent\n\u003e version mismatches with other projects that use the api.\n\n### Maven \u0026 Gradle\n\n- Replace `PLATFORM` with your desired platform. (eg, core).\n- Replace `VERSION` with the latest release version on GitHub.\n\n```kts\nrepositories {\n    maven(\"https://repo.j4c0b3y.net/public/\")\n}\n\ndependencies {\n    implementation(\"net.j4c0b3y:ConfigAPI-PLATFORM:VERSION\")\n}\n```\n\n```xml\n\u003crepositories\u003e\n    \u003crepository\u003e\n        \u003cid\u003ej4c0b3y-public\u003c/id\u003e\n        \u003curl\u003ehttps://repo.j4c0b3y.net/public/\u003c/url\u003e\n    \u003c/repository\u003e\n\u003c/repositories\u003e\n\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003enet.j4c0b3y\u003c/groupId\u003e\n        \u003cartifactId\u003eConfigAPI-PLATFORM\u003c/artifactId\u003e\n        \u003cversion\u003eVERSION\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n### Building\n\n1. Clone this repository and enter its directory.\n2. Run the intellij build configuration by clicking the top right icon.\n3. Alternatively you can run `gradle build`.\n4. The output jar files will be located in the `jars` directory.\n\n## Usage\n\nA config handler instance is required before creating any config classes.\n\nIf you are using this in a bukkit plugin, use `BukkitConfigHandler` instead,\nit registers extra providers for bukkit classes like `Location` and `World`.\n\n```java\n// A logger must be passed into the config handler.\nConfigHandler configHandler = new ConfigHandler(logger);\n```\n\nOptionally, you can change the default config behaviour.\n\n```java\n// Disable structure formatting (spacing, comment positioning, etc.)\nconfigHandler.setFormatStructure(false);\n\n// Disable value formatting (saved from providers)\nconfigHandler.setFormatValues(false);\n\n// Disable removing unrecognised keys from the file.\nconfigHandler.setRemoveUnrecognised(false);\n```\n\n### General Usage\n\nTo make a static access config, you must extend the `StaticConfig` class,\nall fields in your class will be loaded and saved to the yaml document.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e!! Note for Bukkit Plugins (Expand) !!\u003c/b\u003e\u003c/summary\u003e\n\n---\n\n- The file specified in the constructor should be in the plugin's data folder, else it will appear in the main server directory.\n\n```java \npublic Settings(ExamplePlugin plugin) {\n    super(\n        new File(plugin.getDataFolder(), \"settings.yml\"),\n        plugin.getConfigHandler()\n    );\n}\n```\n---\n\u003c/details\u003e\n\n```java\npublic class Settings extends StaticConfig {\n    \n    public Settings(ConfigHandler handler) {\n        // You must specify the file and config handler.\n        super(new File(\"settings.yml\"), handler);\n    }\n    \n    // You can specify config options with public static fields.\n    public static String EXAMPLE = \"example\";\n    public static boolean ENABLED = false;\n    public static double TEST = 234.324;\n    \n    // You can also nest them using subclasses.\n    public static class WHATEVER {\n        public static String NAME = \"J4C0B3Y\";\n        public static int AMOUNT = 17;\n    }\n}\n```\n\nTo see which datatypes can be used, please scroll to the `Providers` section below. \n\nNext, the config must be loaded, this creates the file, and loads all values from it.\n\n```java\nSettings settings = new Settings();\nsettings.load();\n```\n\nHere is what is saved to the file:\n\n```yaml\nexample: \"example\"\nenabled: true\ntest: 234.324\n\nwhatever:\n  name: \"J4C0B3Y\"\n  amount: 17\n```\n\nWhen the user changes the values in the yaml, \nthe value of the associated static field will be set.\n\nYou can access the value of a config option in any part of\nyour code, here I print the value of the `NAME` field.\n\n```java\nSystem.out.println(Settings.WHATEVER.NAME);\n// Output: J4C0B3Y\n```\n\nBy default, the yaml key is the field name, lower case, \nwith all \"_\" replaced with \"-\" characters.\n\nThe key formatter can be changed using the following method:\n\n```java\n// Maintains the capitalization, but still replaces _ with -.\nconfigHandler.setKeyFormatter(key -\u003e key.replace(\"_\", \"-\"));\n```\n\n### Providers\n\nProviders are how field values are translated between java objects and yaml values.\n\nThere are inbuilt providers for strings, number primitives and wrappers, any enum,\nUUIDs, URIs, regex patterns, booleans, any many more.\n\nYou can even have lists, sets and other collections of the registered provider types.\n\nAdditionally maps of string to any registered type can be loaded and saved.\n\nIf you would like to put your custom class in the static config, \na type provider will have to be created and registered for it.\n\nPlease refer to existing inbuilt providers on how to do this, a good complex example is the \n[LocationProvider](https://github.com/J4C0B3Y/ConfigAPI/blob/main/bukkit/src/main/java/net/j4c0b3y/api/config/platform/bukkit/provider/LocationProvider.java) \nfrom the bukkit module.\n\nIf you still don't know what you're doing, feel free to message me on discord.\n\n### Annotations\n\nAnnotations can be used within the class that extends `StaticConfig`,\nthese are used to change the behaviour of the fields and sections.\n\n#### @Key\n\nUsed to change the key saved in the yaml document.\n\n```java\n@Key(\"test\")\npublic static String MESSAGE = \"whatever\";\n```\n\n```yaml\n# Before\nmessage: \"whatever\"\n\n# After\ntest: \"whatever\"\n```\n\n#### @Comment\n\nUsed to add a single or multiline comment to a field or class,\nthis always goes directly above the yaml key.\n\n```java\n@Comment(\"This is a single line comment.\")\npublic static boolean ENABLED = false;\n\n@Comment({\n    \"This is a multi line comment,\", \n    \"go in depth with your explanation.\"\n})\npublic static int VERSION = 1;\n```\n\n```yaml\n# This is a single line comment.\nenabled: false\n\n# This is a multi line comment,\n# go in depth with your explanation.\nversion: 1\n```\n\n#### @Ignore\n\nUsed to completely ignore a field or section from the api,\nno processing will be done to it.\n\n```java\npublic static String HELLO = \"world\";\n\n@Ignore\npublic static String TEST = \"whatever\";\n```\n\n```yaml\nhello: \"world\"\n```\n\n#### @Hidden\n\nUsed when the key should not be saved to file be default, \nit must be manually specified by the user to be loaded.\n\nIf used on a section, whose name is typed by the user in the file,\nall the section's fields will be revealed as well on load.\n\n```java\n@Hidden\npublic static boolean OVERRIDE = false;\n```\n\n```yaml\n# Nothing is saved to file,\n# OVERRIDE is set to false.\n\n# Value is manually specified by user:\noverride: true\n# OVERRIDE is set to true.\n```\n\n#### @Priority\n\nUsed to set the position / order of a node instead of \nusing the position of the static member in the class.\n\nNodes have a priority of `Integer.MAX_VALUE` by default.\n\n```java\n@Priority(2)\npublic static int EXAMPLE = 3;\n\n@Priority(1)\npublic static class TEST { }\n```\n\n```yaml\ntest: {}\nexample: 3\n```\n\n#### @Header \u0026 @Footer\n\n- @Header is used to add a header comment to the top of a config document.\n- @Footer is used to add a footer comment to the bottom of a config document.\n\n```java\n@StaticConfig.Header(\"This is a header!\")\n@StaticConfig.Footer({\"This is a footer!\", \"Second line!\"})\npublic class Settings extends StaticConfig {}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eHow to I remove \u003ccode\u003eStaticConfig.\u003c/code\u003e from the annotation?\u003c/summary\u003e\n\n---\n\nYou must statically import the Header annotation from the StaticConfig class.\n\n```java\nimport static net.j4c0b3y.api.config.StaticConfig.Header;\n```\n\nThen you can use the annotation like this instead:\n\n```java\n@Header(\"This is a shorter way of using the header annotation!\")\npublic class Settings extends StaticConfig {}\n```\n\n---\n\u003c/details\u003e\n\n```yaml\n# This is a header!\n\nexample: true\n\n# This is a footer!\n# Second line!\n```\n\n#### Dynamic Headers\n\nIf you would like to dynamically change the content of the header when saving,\nyou can override the `public List\u003cString\u003e getHeader()/getFooter()` methods.\n\n```java\nimport java.util.Arrays;\n\npublic class Settings extends StaticConfig {\n\n    @Override\n    public List\u003cString\u003e getHeader() {\n        return Arrays.asList(\"Create a nice\", \"dynamic header!\");\n    }\n}\n```\n\n### Final Members\n\nIf a field or class is marked final, its value is always reset in the config.\n\n```java\npublic static final String TEST = \"hello\";\n```\n\n```yaml\n# This value is always reverted to \"hello\" on load.\ntest: \"hello\"\n```\n\n### Relocations\n\nUsed if you change the location of a key in your static config, and want it to\nautomatically copy the value to the new location for existing user files.\n\n```java\npublic Settings(ConfigHandler handler) {\n    // ...\n    \n    // Specify the full paths of target and replacement.\n    relocate(\"target\", \"replacement\");\n} \n```\n\nThis will relocate the value of the `target` key if present,\nto the `replacement` key, then delete the `target` key.\n\n### Backups\n\nBackups duplicate the current file on disk, \nthey don't save the in-memory document values. \n\nThey are created when keys are automatically removed from a config,\nthe default behaviour can be changed with the following options.\n\n```java\n// Disable backups being created if keys are automatically removed.\nconfigHandler.setCreateBackupOnRemove(false);\n\n// Changes the date format used for the backup file name.\nconfigHandler.setBackupDateFormat(\"yyyy-MM-dd-hh-mm-a\");\n```\n\nBackups can also be created manually through the config document.\n\n```java\n// Returns the filename of the backed up file.\nString fileName = config.getDocument().backup();\n```\n\n### Resolvers \n\nResolvers assign the provider used to load and save the static fields,\nresolvers should not be used by 99% of people unless you know what you are doing.\n\nFor more information about resolvers, please refer to the internal javadocs.\n\n### Limitations\n\nDue to the way that class members are retrieved in java, fields are always above\nsubclasses meaning the following is not possible without using @Priority.\n\n\u003cdetails\u003e\n\u003csummary\u003eExpand\u003c/summary\u003e\n\nHere is an example where the `TEST` subclass is above the `EXAMPLE` field. \n\n```java\npublic class Settings extends StaticConfig {\n    // ...\n    \n    public static class TEST {\n        public static boolean ENABLED = true;\n    }\n    \n    public static String EXAMPLE = \"example\";\n}\n```\n\nBut the `example` key is above the `test` key for the reason described above. \n\n```yaml\nexample: \"example\"\n\ntest:\n  enabled: true\n```\n\u003c/details\u003e\n\n### Message Utility\n\nThe config api comes with an in-built `Message` class that you can use\nto send single or multi-line messages with replaced placeholders and\ntranslations easily to a player or other form of user.\n\n#### Usage\n\nHere is an example of how it can be used, first create the default config.\n\n```java\npublic class Messages extends StaticConfig {\n    // ...\n    public static Message RELOAD_SUCCESS = Message.of(\n        \"\u0026aSuccessfully reloaded in \u003cduration\u003ems!\"\n    );\n\n    public static Message RELOAD_FAILED = Message.of(\n        \"\u0026cAn issue occurred whilst reloading the plugin,\",\n        \"\u0026cplease check console for any errors!\"\n    );\n}\n```\n\nSecond, use the message from the config to send the message to the user.\n\n```java\nMessages.RELOAD_SUCCESS\n    .replace(\"\u003cduration\u003e\", duration) // Replace custom placeholders in each line.\n    .map(Color::translate) // Translate the message (parse papi placeholders as well).\n    .send(player::sendMessage); // Send each of the lines to the player or user.\n```\n\n#### Advantages\n\nThe message utility is very useful for the following reasons:\n\n- Very clean usage and experience for the developer implementing logic.\n- Allows users to set the message as `[]` in the config to not send any message.\n- Allows users to choose whether they want single or multi line messages.\n\n### Want more?\n\nEach and every class in my config api has detailed javadocs explaining what\nmethods and variables are used for, and functionality of internal methods.\n\n\u003e Made with ❤ // J4C0B3Y 2024\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj4c0b3y%2Fconfigapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj4c0b3y%2Fconfigapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj4c0b3y%2Fconfigapi/lists"}