Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ await didit.sessions.create(

Resources and methods follow the API: `didit.<resource>.<method>(...)`, with nested resources such as `didit.sessions.imports` or `didit.cases.notes`.
Path parameters are positional; everything else goes in one params object whose fields keep the API's names (snake_case).
[api.md](api.md) lists all 257 methods with their HTTP routes and types.
[api.md](api.md) lists every method with its HTTP route and types, generated from `openapi/`.

```ts
import { fileFromPath } from "@didit-protocol/sdk-node";
Expand Down
2 changes: 1 addition & 1 deletion docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Convert names to the language's idiom and nothing else:
| Ruby | `didit.sessions.imports.create(...)` |
| C# | `await client.Sessions.Imports.CreateAsync(...)` |

The full resource tree (version 1, 248 server operations in 47 resources) is in `overlay.json`.
The full version-1 resource tree is generated from `openapi/*.json` and listed in `api.md`, one section per resource; `overlay.json` holds only the naming overrides upstream does not carry yet.
Highlights: `sessions`, `sessions.imports`, `sessions.reviews`, the standalone APIs (`id_verification.verify`, `face_match.compare`, `face_search.search`, `passive_liveness.check`, `age_estimation.estimate`, `proof_of_address.verify`, `document_ai.analyze`, `aml.screen`, `database_validation.validate`, `phone.send_code`, `email.check_code`, `ip.assess_risk`, `kyb.search`), `id_wallets`, `fraud_checks`, `users`, `businesses`, `transactions`, `transactions.rules`, `transactions.travel_rule`, `wallet_screening`, `travel_rule`, `travel_rule.wallet_addresses`, `workflows`, `questionnaires`, `webhooks.destinations`, `billing`, `biometric_templates`, `customization`, `cases` (with `notes`, `links`, `checklist`, `requests`, `teams`, `routing_rules`, `blueprints`, `regulatory_reports`), `regulatory_reports`, `report_templates`, `networks`, and `account` (`account.organizations`, `account.applications`).

## 5. Architecture
Expand Down
52 changes: 52 additions & 0 deletions tests/docs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// The generated API reference and the README that points at it. The number of
// methods in api.md's header must match the method rows below it, and a method
// count stated in the README must match it too, so the docs cannot drift from
// the generated reference as the API grows.

import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";

const readme = readFileSync(new URL("../README.md", import.meta.url), "utf8");
const api = readFileSync(new URL("../api.md", import.meta.url), "utf8");
const design = readFileSync(new URL("../docs/DESIGN.md", import.meta.url), "utf8");

/** The count in "Every method of ...: N methods, generated from openapi/". */
const declared = /Every method of `@didit-protocol\/sdk-node`: (\d+) methods/.exec(api)?.[1];

/** One row per method in the api.md tables. */
const rows = api.split("\n").filter((line) => line.startsWith("| `didit."));

/** One section per resource in api.md. */
const sections = api.split("\n").filter((line) => line.startsWith("## `didit."));

describe("API reference", () => {
it("declares the number of methods it lists", () => {
expect(declared).toBeDefined();
expect(Number(declared)).toBe(rows.length);
});

it("is linked from the README", () => {
expect(readme).toContain("[api.md](api.md)");
});

it("does not state a method count the reference disagrees with", () => {
// The README deliberately names no count: the spec sync regenerates api.md
// and the tables above, so a number copied into the README goes stale.
// If one is added, it has to be right.
const claimed = /(\d+) methods/.exec(readme)?.[1];
if (claimed !== undefined) expect(Number(claimed)).toBe(rows.length);
});
});

describe("Design document", () => {
it("does not state server operation or resource counts the reference disagrees with", () => {
// DESIGN.md's resource-tree paragraph is where a reader is told how large
// the contract is. It deliberately names no size, because a spec sync
// regenerates api.md; if a size is added back, it has to be right.
const claimed = /(\d+) server operations in (\d+) resources/.exec(design);
if (claimed !== null) {
expect(Number(claimed[1])).toBe(rows.length);
expect(Number(claimed[2])).toBe(sections.length);
}
});
});
Loading