HackerRankKit

0.6.0

An unofficial Swift client for the HackerRank for Work REST API, with typed models and a no-network mock backend.
adamtheturtle/HackerRankKit

What's New

0.6.0

2026-07-18T18:03:23Z

URL-correctness and credential-scope fixes, plus the PaginatedRESTClient 0.2.0 bump. Each fix carries a regression test verified to fail without it.

Fixed

  • Path segments are no longer double percent-encoded (#10). pathSegment escaped an id and URL.appending(path:) escaped it again, so ada+test@example.com was requested as ada%252Btest%2540example.com — the server saw a literal ada%2Btest%40example.com and 404'd, or addressed a different record. SCIM /Users/{id} was the most likely trigger, since many deployments use the email as the resource id. Every URL now goes through one funnel that never re-encodes. The old suite used only bare ids like t1, which is why this was invisible.
  • A single malformed SCIM row no longer empties the directory (#11). The try? wrapped the array rather than the element, so one numeric id where a String? was expected made scimUsers()/scimGroups() return an empty list — with no error and no log line — for a fully populated directory. Now decodes leniently per element, like the other list endpoints.
  • + is now escaped in search queries (#12). URLComponents leaves + literal, and the Rack/Rails backend decodes it as a space, so C++ and plus-addressed emails were searched for as something else entirely.
  • allUsers no longer duplicates a user when a row is dropped (#13). Fan-out offsets were derived from the decoded count, but the server pages by requested limit — so one malformed record shifted every subsequent offset and returned a user twice, feeding duplicate keys to a SwiftUI ForEach. Offsets now come from the page size.
  • The Bearer token is no longer sent to a foreign host (#14). cursorURL returned any absolute URL from a server next field unvalidated, and authorizedGET attaches the credential unconditionally — so a response naming another host received the user's personal access token. Cursors are now constrained to baseURL's origin (scheme, host, port), and anything else is rejected.

Upgrading

PaginatedRESTClient is now 0.2.0. HackerRankPage's Item is constrained to Identifiable so each page can supply a stable identity and keep the parallel fetch path — source-breaking in principle, though all ten item types already conformed. pageSize is declared as the API's documented maximum of 100, sourced from the same constant every request already sends as its limit, so the two cannot drift.

Full changelog: 0.5.0...0.6.0

HackerRankKit

An unofficial Swift client for the HackerRank for Work REST API, with typed models and a no-network mock backend.

Documentation | Swift Package Index

Installation

.package(url: "https://github.com/adamtheturtle/HackerRankKit.git", from: "0.1.0")

Add HackerRankKit to your app target and HackerRankKitMock to tests or demos that should run without the network.

Products

  • HackerRankKit: Typed API client for tests, candidates, questions, interviews, users, teams, and the audit log.
  • HackerRankKitMock: In-process fake API seeded with canned data.

Usage

import HackerRankKit

let client = HackerRankClient(token: "your-personal-access-token")

let tests = try await client.testsPage()
let created = try await client.createTest(name: "Phone screen")

Requirements

  • Swift 6.2+
  • macOS 15+, iOS 18+, tvOS 18+, watchOS 11+, or visionOS 2+

License

MIT. See LICENSE.

Description

  • Swift Tools 6.2.0
View More Packages from this Author

Dependencies

Last updated: Sat Aug 01 2026 07:24:47 GMT-0900 (Hawaii-Aleutian Daylight Time)