{"id":26915072,"url":"https://github.com/andjsrk/commandapi-safeext","last_synced_at":"2025-04-01T17:51:18.676Z","repository":{"id":253818613,"uuid":"844594740","full_name":"andjsrk/commandapi-safeext","owner":"andjsrk","description":"A better way to write commands using CommandAPI","archived":false,"fork":false,"pushed_at":"2024-08-27T19:39:14.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-08-27T21:37:11.508Z","etag":null,"topics":["commandapi","library","minecraft","minecraft-plugin"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/andjsrk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-08-19T15:19:46.000Z","updated_at":"2024-08-27T19:39:18.000Z","dependencies_parsed_at":"2024-08-19T19:45:18.968Z","dependency_job_id":"9c455388-d003-4721-83e9-14809b9edc7b","html_url":"https://github.com/andjsrk/commandapi-safeext","commit_stats":null,"previous_names":["andjsrk/commandapi-safeext"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andjsrk%2Fcommandapi-safeext","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andjsrk%2Fcommandapi-safeext/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andjsrk%2Fcommandapi-safeext/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andjsrk%2Fcommandapi-safeext/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andjsrk","download_url":"https://codeload.github.com/andjsrk/commandapi-safeext/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246686252,"owners_count":20817758,"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","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":["commandapi","library","minecraft","minecraft-plugin"],"created_at":"2025-04-01T17:51:18.045Z","updated_at":"2025-04-01T17:51:18.665Z","avatar_url":"https://github.com/andjsrk.png","language":"Kotlin","readme":"# commandapi-safeext\nA better way to write commands using [CommandAPI](https://commandapi.jorel.dev/).\n\n## Motivation\nWith vanilla CommandAPI, writing commands is error-prone and inconvenient:\n\n```kt\ncommandAPICommand(\"some_cmd\") {\n    integerArgument(\"first\")\n    stringArgument(\"second\")\n    blockStateArgument(\"third\")\n    booleanArgument(\"fourth\")\n    integerArgument(\"fifth\", optional = true)\n    playerExecutor { player, args -\u003e\n        val first = args[\"first\"] as String // oops, I forgot to update here after changing the type of the argument!\n        val second = args[\"seocnd\"] as String // oops, there is a typo in the argument name!\n        val third = args[\"third\"] as BlockState // oops, I cast the argument to wrong type! - https://commandapi.jorel.dev/9.5.0/argument_blockstate.html\n        \n        val fourth = args[\"fourth\"] as Boolean\n        // finally got the right way, but it is still inconvenient :(\n        // it still requires me to manually cast the value even I wrote *boolean*Argument(\"fourth\"), what?\n        \n        val fifth = args.getOptional(\"fifth\").getOrNull() as Int?\n        // I wrote `optional = true` above... why are you not so smart?\n    }\n}\n```\n... here commandapi-safeext is.\n\n## Example\n```kt\ncommandAPICommand(\"some_cmd\") {\n    val first = safeIntegerArgument(\"first\")\n    val second = safeStringArgument(\"seocnd\") // although a typo still can exist, this does not affect getting the value of the argument!\n    val third = safeBlockStateArgument(\"third\")\n    // skips the boolean argument 'fourth' that was present in the example above\n    val fourth = safeIntegerArgument(\"fourth\").optional()\n    playerExecutor { player, args -\u003e\n        val first = args[first]\n        //               ^ first: RequiredSafeArgument\u003cIntegerArgument, Int\u003e\n        //               the argument itself contains type data, so there is no need to manually cast now!\n        val second = args[second] // if there is a typo, *compiler* will catch that!\n        val third = args[third] // since manual casting is no longer needed, mis-casting can never happen!\n        val fourth = args[fourth]\n        //  ^             ^ fourth: OptionalSafeArgument\u003cIntegerArgument, Int\u003e\n        //  ^ fourth: Int?\n        // now you are allowed to write concise, DRY code!\n    }\n}\n```\n\n## Major changes\n\n### No `useNamespacedKey` parameters\nOriginally, functions like `biomeArgument` have `useNamespacedKey` parameter.\nBut they obstruct keeping consistency of return type; so they have split into separate functions.\n\n### No `optional` parameters\nTo get proper argument type, `optional` parameters have split into separate methods.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandjsrk%2Fcommandapi-safeext","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandjsrk%2Fcommandapi-safeext","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandjsrk%2Fcommandapi-safeext/lists"}