Skip to content
Closed
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
28 changes: 22 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Thank you for your interest in contributing to Brazilian Utils! This project exists thanks to
[everyone who contributes](README.md#contributors), and we'd love your help solving the little
day-to-day problems of building software for Brazilian businesses.
day-to-day problems of building software for Brazil.

By participating in this project, you agree to abide by our
[Code of Conduct](CODE_OF_CONDUCT.md).
Expand Down Expand Up @@ -139,9 +139,14 @@ example `formatSomething`):
- `docs/utilities.md` (English)
- `docs/pt-br/utilities.md` (Portuguese translation)

Follow the existing format: a `##` heading with the function name, a short description, and a
`javascript` code block showing example input/output. Place the new section next to the other
utilities in the same domain, keeping both files in the same order.
Follow the existing format: a `###` heading with the function name under the `##` family it
belongs to, one sentence saying what it does (`llms.txt` indexes that sentence), a few short
bullets for the options and the return rules, a `javascript` code block showing example
input/output, and a one-line `Source:` (`Fonte:` in Portuguese) with the official reference when
there is one. Do not repeat what the Conventions section at the top of the file already says
(nothing throws, masked input is accepted, generators use `Math.random()`); the JSDoc is the place
for every edge case, the reference is the place for what a caller needs. Keep both files in the
same order.

After editing `docs/getting-started.md` or `docs/utilities.md`, run `npm run build:llms` to
regenerate `docs/llms.txt` and `docs/llms-full.txt` (see [llms.txt](https://llmstxt.org/)) and
Expand Down Expand Up @@ -345,6 +350,17 @@ browser, with `_sidebar.md`, `_navbar.md` and `_coverpage.md` as its navigation.
`docs/llms-full.txt` keep their headings; run `npm run build:llms` after editing a page.
- Context7 indexes `docs/` as `/brazilian-utils/javascript`; `context7.json` says what it reads,
and `.github/workflows/context7.yml` asks for a refresh when the docs change on `main`.
- The guide pages (`docs/guides/`, `docs/pt-br/guides/`) show how to use the package with React,
Vue, Angular and plain JavaScript. Their examples are complete: a `jsx` or `vue` block with a
default export, a `typescript` block whose default export is an `@Component` with the selector
`app-root`, or a full `html` document. `docs/run.js` (a docsify plugin loaded by `index.html`) puts a
Run button on those blocks and runs them in a sandboxed iframe, compiling JSX with sucrase, a
single-file component with `@vue/compiler-sfc` and an Angular component with Babel, each fetched
from jsdelivr when a button is first clicked, with an import map that resolves `react`, `vue`,
`@angular/*`, `zod`, `valibot` and the package itself to jsdelivr, at the versions pinned at the
top of `run.js`.
A new example only needs to follow one of those shapes; a fragment (no default export, no
`<html>`) gets no button. `window.$docsify.run` overrides the CDN URLs when testing offline.

To preview the site, point a static file server that resolves `/page` to `page.html`, the way
GitHub Pages does, at `docs/`.
Expand Down Expand Up @@ -467,8 +483,8 @@ the commit messages.
responses as untrusted. A workflow change keeps actions pinned by SHA, permissions minimal and
secrets away from pull request code. A new development dependency needs a reason, a maintained
upstream and a license compatible with MIT.
7. **Can the next person use it?** The JSDoc and both `docs/utilities.md` files describe what the
code does, edge cases included, with an example that is true; the commit message has the right
7. **Can the next person use it?** The JSDoc describes what the code does, edge cases included,
both `docs/utilities.md` files describe what a caller needs, with an example that is true; the commit message has the right
Conventional Commit type, because the changelog and the version are computed from it.

**Automated pull requests** get the same review with a narrower focus: a Dependabot bump is read
Expand Down
46 changes: 12 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<img src="https://raw.githubusercontent.com/brazilian-utils/brand/main/github-hero/github-hero-js.png" width="100%" alt="Brazilian Utils" />

<p>Utils library for Brazilian-specific businesses.</p>
<p>Utilities for Brazilian data: CPF, CNPJ, CEP, boleto, Pix, holidays and more.</p>

[📖 Documentation](https://brazilian-utils.com.br/getting-started)

Expand Down Expand Up @@ -29,56 +29,34 @@

# Getting Started

Brazilian Utils is a library focused on solving problems that we face daily in the development of applications for the Brazilian business.
Brazilian Utils is a zero-dependency library of small utilities for the day-to-day problems of building software for Brazil: validating, formatting, parsing and generating CPF, CNPJ, CEP, boleto, Pix, phone numbers, holidays and more.

## Why Brazilian Utils

- **Zero runtime dependencies.** Nothing else lands in your `node_modules` or in your bundle.
- **Tree-shakeable, down to the function.** `import { isValidCpf }` costs about 1.4 KB minified (0.8 KB gzipped); every util is also its own subpath entry (`@brazilian-utils/brazilian-utils/get-cities`) for the heavy ones.
- **Runs everywhere.** Node.js `^20.19.0 || >=22.12.0`, Bun, Deno and evergreen browsers, tested in CI on every one of them.
- **Written in TypeScript.** Types ship with the package; the public API is tracked by an API report so nothing changes silently.
- **Validated against the official rules.** Every validator cites the specification, law or dataset it implements (`@see` in the docs), and the test suite is mutation-tested, not just covered.
- **Tree-shakeable, down to the function.** `import { isValidCpf }` costs about 1.4 KB minified (0.8 KB gzipped). Every util is also its own subpath entry, so the heavy ones can be lazy-loaded.
- **Runs everywhere.** Node.js `^20.19.0 || >=22.12.0`, Bun, Deno and evergreen browsers, all tested in CI.
- **Written in TypeScript.** Types ship with the package, and an API report tracks the public API so nothing changes silently.
- **Validated against the official rules.** Every validator cites the specification, law or dataset it implements, and the test suite is mutation-tested, not just covered.
- **Documented in English and Portuguese**, with an `llms.txt` for AI assistants.

## Installation

You can install **Brazilian Utils** in a few ways:

as npm package:

```bash
npm install --save @brazilian-utils/brazilian-utils
```

with yarn package manager:

```bash
yarn add @brazilian-utils/brazilian-utils
```

with pnpm:

```bash
pnpm add @brazilian-utils/brazilian-utils
```

with bun:

```bash
bun add @brazilian-utils/brazilian-utils
npm install @brazilian-utils/brazilian-utils
```

or `<script>` tag (global `BrazilianUtils`):
The same package works with `yarn add`, `pnpm add` and `bun add`. In a plain `<script>` tag it exposes the global `BrazilianUtils`:

```html
<script src="https://unpkg.com/@brazilian-utils/brazilian-utils/dist/brazilian-utils.umd.cjs"></script>
```

### Runtime support

The supported range is the `engines` field in `package.json`; every row below is exercised by the [Tests workflow](https://github.com/brazilian-utils/javascript/actions/workflows/tests.yml?query=branch%3Amain) on every pull request.
The supported range is the `engines` field in `package.json`; every row below runs in the [Tests workflow](https://github.com/brazilian-utils/javascript/actions/workflows/tests.yml?query=branch%3Amain) on every pull request.

| Runtime | Supported | Covered in CI |
| Runtime | Supported | Tested in CI |
| -------- | ------------------------- | ----------------------------- |
| Node.js | `^20.19.0 \|\| >=22.12.0` | 20, 22, 24, 26 |
| Bun | latest | latest |
Expand All @@ -87,15 +65,15 @@ The supported range is the `engines` field in `package.json`; every row below is

## Usage

To use a utility, import the required function, as shown below:
Import the function you need:

```javascript
import { isValidCpf } from "@brazilian-utils/brazilian-utils";

isValidCpf("1232454233345"); // false
```

You can check a list of utilities [by clicking here](https://brazilian-utils.com.br/utilities).
The [utilities reference](https://brazilian-utils.com.br/utilities) lists every function, grouped by family, with its options and examples.

- Using an AI coding assistant? The docs are indexed on Context7 as [`/brazilian-utils/javascript`](https://context7.com/brazilian-utils/javascript), and [llms.txt](https://brazilian-utils.com.br/llms.txt) lists every util for other tools. See [AI assistants](https://brazilian-utils.com.br/getting-started?id=ai-assistants).
- The package is tree-shakeable. Every util is also available as its own subpath (e.g. `@brazilian-utils/brazilian-utils/get-cities`) so you can lazy-load the few heavy ones. See [Bundle size](https://brazilian-utils.com.br/getting-started?id=bundle-size).
Expand Down
2 changes: 1 addition & 1 deletion context7.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"url": "https://context7.com/brazilian-utils/javascript",
"public_key": "pk_oM2bnqm6FW1O0U0ygGlHr",
"projectTitle": "Brazilian Utils",
"description": "Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more.",
"description": "Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more.",
"folders": ["docs"],
"excludeFolders": ["docs/pt-br"],
"excludeFiles": [
Expand Down
19 changes: 15 additions & 4 deletions docs/404.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<title>Not found · Brazilian Utils</title>
<meta name="description" content="Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more." />
<meta name="description" content="Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more." />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="dark" />
<meta name="theme-color" content="#009739" />
Expand All @@ -28,7 +28,7 @@
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Brazilian Utils" />
<meta property="og:title" content="Brazilian Utils" />
<meta property="og:description" content="Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more." />
<meta property="og:description" content="Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more." />
<meta property="og:locale" content="en_US" />
<meta property="og:locale:alternate" content="pt_BR" />
<meta property="og:image" content="https://brazilian-utils.com.br/images/logo.png" />
Expand All @@ -45,14 +45,14 @@
"@id": "https://brazilian-utils.com.br/#website",
"url": "https://brazilian-utils.com.br/",
"name": "Brazilian Utils",
"description": "Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more.",
"description": "Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more.",
"inLanguage": ["en", "pt-BR"]
},
{
"@type": "SoftwareSourceCode",
"@id": "https://brazilian-utils.com.br/#library",
"name": "Brazilian Utils",
"description": "Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more.",
"description": "Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more.",
"url": "https://brazilian-utils.com.br/",
"codeRepository": "https://github.com/brazilian-utils/javascript",
"programmingLanguage": "TypeScript",
Expand Down Expand Up @@ -253,8 +253,19 @@
};
</script>

<!-- Run buttons for the examples of the guide pages (see the comment at the top of run.js);
registers a plugin, so it loads before docsify reads the configuration. -->
<script src="/run.js"></script>
<!-- Docsify 5: the major version pin picks up non-breaking releases automatically -->
<script src="//cdn.jsdelivr.net/npm/docsify@5/dist/docsify.min.js"></script>
<!-- Syntax highlighting for the guide pages: docsify bundles Prism with HTML, CSS and
JavaScript only; JSX, TypeScript and TSX come from the same Prism release, and a `vue`
fence highlights as HTML (Prism has no Vue grammar; the markup one covers a single-file
component well enough). -->
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-jsx.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-tsx.min.js"></script>
<script>Prism.languages.vue = Prism.languages.markup;</script>
<!-- The search plugin indexes the raw Markdown through Docsify.get, without the front-matter
plugin, so it would index the front matter as a heading and lose the page's title; this
hands it every page the way it renders: the block gone, the title as the H1. -->
Expand Down
2 changes: 1 addition & 1 deletion docs/_coverpage.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<img src="https://raw.githubusercontent.com/brazilian-utils/brand/main/logos/logo-js.svg" alt="Brazilian Utils" width="360"/>

> Utils library for Brazilian-specific businesses.
> Utilities for Brazilian data: CPF, CNPJ, CEP, boleto, Pix, holidays and more.

- Zero runtime dependencies
- Tree-shakeable, one import per util
Expand Down
5 changes: 5 additions & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
* [Getting Started](getting-started.md)
* [Utilities](utilities.md)
* Guides
* [React](guides/react.md)
* [Vue](guides/vue.md)
* [Angular](guides/angular.md)
* [Plain JavaScript](guides/vanilla.md)
* [Migration v1 to v2](migration-v1-to-v2.md)
19 changes: 15 additions & 4 deletions docs/getting-started.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<title>Getting Started · Brazilian Utils</title>
<meta name="description" content="Install Brazilian Utils, the zero-dependency utils library for Brazilian businesses, and learn how to import a util, which runtimes are supported and how the bundle size behaves." />
<meta name="description" content="Install Brazilian Utils, the zero-dependency library of utilities for Brazilian data, import a util, check the supported runtimes and keep your bundle small." />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="color-scheme" content="dark" />
<meta name="theme-color" content="#009739" />
Expand Down Expand Up @@ -32,7 +32,7 @@
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Brazilian Utils" />
<meta property="og:title" content="Getting Started · Brazilian Utils" />
<meta property="og:description" content="Install Brazilian Utils, the zero-dependency utils library for Brazilian businesses, and learn how to import a util, which runtimes are supported and how the bundle size behaves." />
<meta property="og:description" content="Install Brazilian Utils, the zero-dependency library of utilities for Brazilian data, import a util, check the supported runtimes and keep your bundle small." />
<meta property="og:url" content="https://brazilian-utils.com.br/getting-started" />
<meta property="og:locale" content="en_US" />
<meta property="og:locale:alternate" content="pt_BR" />
Expand All @@ -50,14 +50,14 @@
"@id": "https://brazilian-utils.com.br/#website",
"url": "https://brazilian-utils.com.br/",
"name": "Brazilian Utils",
"description": "Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more.",
"description": "Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more.",
"inLanguage": ["en", "pt-BR"]
},
{
"@type": "SoftwareSourceCode",
"@id": "https://brazilian-utils.com.br/#library",
"name": "Brazilian Utils",
"description": "Zero-dependency, tree-shakeable utils for Brazilian-specific businesses: CPF, CNPJ, boleto, Pix, CEP, holidays and more.",
"description": "Zero-dependency, tree-shakeable utilities for Brazilian data: validate, format, parse and generate CPF, CNPJ, CEP, boleto, Pix, holidays and more.",
"url": "https://brazilian-utils.com.br/",
"codeRepository": "https://github.com/brazilian-utils/javascript",
"programmingLanguage": "TypeScript",
Expand Down Expand Up @@ -258,8 +258,19 @@
};
</script>

<!-- Run buttons for the examples of the guide pages (see the comment at the top of run.js);
registers a plugin, so it loads before docsify reads the configuration. -->
<script src="/run.js"></script>
<!-- Docsify 5: the major version pin picks up non-breaking releases automatically -->
<script src="//cdn.jsdelivr.net/npm/docsify@5/dist/docsify.min.js"></script>
<!-- Syntax highlighting for the guide pages: docsify bundles Prism with HTML, CSS and
JavaScript only; JSX, TypeScript and TSX come from the same Prism release, and a `vue`
fence highlights as HTML (Prism has no Vue grammar; the markup one covers a single-file
component well enough). -->
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-jsx.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-typescript.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-tsx.min.js"></script>
<script>Prism.languages.vue = Prism.languages.markup;</script>
<!-- The search plugin indexes the raw Markdown through Docsify.get, without the front-matter
plugin, so it would index the front matter as a heading and lose the page's title; this
hands it every page the way it renders: the block gone, the title as the H1. -->
Expand Down
Loading
Loading