Change the contract

Add or change a function in the shared contract. Every page of this site and every library follows the contract.

The contract in docs defines each utility: one folder per utility (the contract calls it a domain), with a contract.json. Each file lists the functions, their signatures and the test cases that every library runs. This site makes its pages from the contract. When a change to the contract is merged, each library that does not have the new function gets an issue.

Files of a domain

contract/
├── _categories.json   the groups of the sidebar
├── cpf/
│   ├── contract.json  title, summary, category, functions and their test cases
│   ├── spec.en.md     the long rule and the algorithm, in English
│   ├── spec.pt-br.md  the same text, in Portuguese
│   └── references.md  links to the official documents
└── license-plate/
    └── contract.json  the folder is the domain in kebab-case
{
  "$schema": "../../schema/contract.schema.json",
  "domain": "cpf",
  "title": { "en": "CPF", "pt-BR": "CPF" },
  "summary": { "en": "One sentence under the page title.", "pt-BR": "Uma frase abaixo do título." },
  "category": "documents",
  "order": 1,
  "related": ["cnpj"],
  "functions": {
    "isValid": {
      "level": "core",
      "summary": { "en": "Checks whether a CPF is valid.", "pt-BR": "Verifica se um CPF é válido." },
      "params": [{ "name": "value", "type": "string" }],
      "returns": "boolean",
      "tests": [
        { "args": ["82178537464"], "returns": true },
        { "args": ["00000000000"], "returns": false, "note": "reserved number" }
      ]
    }
  }
}

The keys of functions are the function names in the contract, such as isValid. The same name has three uses:

  • the ## heading of the function in each library's usage files,
  • the second part of the function id, such as cpf.isValid,
  • the name that the validator, the issues and the status pages use.

Do not rename a function. A new name breaks every library. To change only the title on the page, add label with { "en", "pt-BR" }. docs/contract.md describes every field.

Add a function or a domain

  1. Add the function to contract/<domain>/contract.json, or create the folder for a new domain. Give the function a signature and test cases. The test cases are the spec that every library must pass. Include the examples of the official rule and the edge cases: empty input, formatted input, a wrong check digit.

  2. A new domain also gets its spec: what the identifier is, its format and its algorithm, in spec.en.md and spec.pt-br.md, and the official sources in references.md. npm run lint names the domains that still lack them.

  3. Run npm run lint. It checks the contract, the schemas and the format. npm run docs fmt fixes the format.

  4. Run npm run docs sync, then npm run check -- --tests to see which libraries already pass the new cases.

  5. Open the pull request. The pipeline adds the contract changelog to the pull request, and the list of issues it will open. After the merge, each library without the function gets an issue titled Implement <function>, and the function appears on this site.

The test cases decide

The text explains the rule. The test cases decide the behavior, and the libraries run the test cases. If the text says that formatted input is not valid, a test case must expect false for formatted input.

Change a behavior

A change to an expected value changes every library. In the pull request, give the official source of the change and the libraries that it affects. After the merge, each library that fails the changed cases gets an issue titled Fix <function>.

Edit on GitHub

Last updated on

On this page