diff --git a/.bestpractices.json b/.bestpractices.json index 0f8203d0c..d2a52957c 100644 --- a/.bestpractices.json +++ b/.bestpractices.json @@ -18,7 +18,7 @@ "osps_br_07_01_status": "Met", "osps_br_07_01_justification": "GitHub secret scanning with push protection is enabled, TruffleHog scans every pull request (https://github.com/brazilian-utils/javascript/blob/main/.github/workflows/security.yml) and .env files are git-ignored.", "osps_do_01_01_status": "Met", - "osps_do_01_01_justification": "https://brazilian-utils.com.br/getting-started and https://brazilian-utils.com.br/utilities document every utility, in English and Portuguese.", + "osps_do_01_01_justification": "https://brazilian-utils.com.br/libs/javascript/ and the utility pages it links to (https://brazilian-utils.com.br/utils/cpf/, ...) document every utility, in English and Portuguese; the sources are docs/utilities.md and docs/pt-br/utilities.md.", "osps_do_02_01_status": "Met", "osps_do_02_01_justification": "https://github.com/brazilian-utils/javascript/blob/main/SUPPORT.md and the bug report issue template: https://github.com/brazilian-utils/javascript/issues/new/choose", "osps_gv_02_01_status": "Met", @@ -44,7 +44,7 @@ "osps_qa_05_01_status": "Met", "osps_qa_05_01_justification": "Build output (dist) is git-ignored; nothing generated and executable is committed.", "osps_qa_05_02_status": "Met", - "osps_qa_05_02_justification": "The only binary files are two small PNG images of the docs site (docs/images), reviewable as images.", + "osps_qa_05_02_justification": "The repository has no binary files: everything committed is text, reviewable in a diff.", "osps_vm_02_01_status": "Met", "osps_vm_02_01_justification": "https://github.com/brazilian-utils/javascript/blob/main/SECURITY.md#reporting-a-vulnerability", "osps_ac_04_01_status": "Met", @@ -76,7 +76,7 @@ "osps_sa_01_01_status": "Met", "osps_sa_01_01_justification": "https://github.com/brazilian-utils/javascript/blob/main/CONTRIBUTING.md#architecture", "osps_sa_02_01_status": "Met", - "osps_sa_02_01_justification": "The public API is documented at https://brazilian-utils.com.br/utilities and checked on every pull request against the last npm release, which fails on a breaking change and lists every added, removed and changed declaration: https://github.com/brazilian-utils/javascript/blob/main/CONTRIBUTING.md#public-api-validation", + "osps_sa_02_01_justification": "The public API is documented at https://brazilian-utils.com.br/libs/javascript/ and checked on every pull request against the last npm release, which fails on a breaking change and lists every added, removed and changed declaration: https://github.com/brazilian-utils/javascript/blob/main/CONTRIBUTING.md#public-api-validation", "osps_sa_03_01_status": "Met", "osps_sa_03_01_justification": "https://github.com/brazilian-utils/javascript/blob/main/SECURITY.md#threat-model", "osps_vm_01_01_status": "Met", @@ -142,9 +142,9 @@ "license_location_status": "Met", "license_location_justification": "https://github.com/brazilian-utils/javascript/blob/main/LICENSE", "documentation_basics_status": "Met", - "documentation_basics_justification": "https://brazilian-utils.com.br/getting-started", + "documentation_basics_justification": "https://brazilian-utils.com.br/libs/javascript/", "documentation_interface_status": "Met", - "documentation_interface_justification": "https://brazilian-utils.com.br/utilities documents every exported function; API Extractor fails CI on an undocumented export: https://github.com/brazilian-utils/javascript/blob/main/CONTRIBUTING.md#public-api-validation", + "documentation_interface_justification": "https://brazilian-utils.com.br/libs/javascript/ documents every exported function; API Extractor fails CI on an undocumented export: https://github.com/brazilian-utils/javascript/blob/main/CONTRIBUTING.md#public-api-validation", "sites_https_status": "Met", "sites_https_justification": "The site, the repository and the npm package are HTTPS only.", "discussion_status": "Met", @@ -280,9 +280,9 @@ "documentation_security_status": "Met", "documentation_security_justification": "https://github.com/brazilian-utils/javascript/blob/main/SECURITY.md#whats-in-scope and https://github.com/brazilian-utils/javascript/blob/main/SECURITY.md#threat-model", "documentation_quick_start_status": "Met", - "documentation_quick_start_justification": "https://brazilian-utils.com.br/getting-started", + "documentation_quick_start_justification": "https://brazilian-utils.com.br/libs/javascript/", "documentation_current_status": "Met", - "documentation_current_justification": "The docs are checked in CI: the Check workflow runs the llms.txt generator over them on every run, so a missing docs file fails it, jsr.json fails it when stale, an undocumented export fails the public API check, and a pull request that changes a utility must update both language versions.", + "documentation_current_justification": "The docs are checked in CI: the Check workflow generates the examples of the guides from their templates on every run, so a broken template fails it, jsr.json fails it when stale, an undocumented export fails the public API check, and a pull request that changes a utility must update both language versions.", "documentation_achievements_status": "Met", "documentation_achievements_justification": "The README links the OpenSSF Best Practices and Scorecard badges: https://github.com/brazilian-utils/javascript#readme", "accessibility_best_practices_status": "Unmet", @@ -292,7 +292,7 @@ "sites_password_security_status": "N/A", "sites_password_security_justification": "The project sites store no passwords; authentication is GitHub's and npm's.", "maintenance_or_update_status": "Met", - "maintenance_or_update_justification": "1.x names are kept as deprecated aliases in 2.x and the upgrade is documented: https://brazilian-utils.com.br/migration-v1-to-v2", + "maintenance_or_update_justification": "1.x names are kept as deprecated aliases in 2.x and the upgrade is documented: https://brazilian-utils.com.br/guides/javascript/migration-v1-to-v2/", "vulnerability_report_credit_status": "N/A", "vulnerability_report_credit_justification": "No vulnerability was resolved in the last 12 months; SECURITY.md commits to crediting reporters.", "vulnerability_response_process_status": "Met", @@ -374,7 +374,7 @@ "test_branch_coverage80_status": "Met", "test_branch_coverage80_justification": "100% branch coverage, enforced in CI.", "hardened_site_status": "Unmet", - "hardened_site_justification": "The documentation site is served by GitHub Pages, which does not let a project set Content-Security-Policy, HSTS or X-Content-Type-Options headers.", + "hardened_site_justification": "The documentation site, https://brazilian-utils.com.br, is built from https://github.com/brazilian-utils/docs and served by Cloudflare Pages; it sends X-Content-Type-Options: nosniff, but no Content-Security-Policy or HSTS header yet.", "security_review_status": "Met", "security_review_justification": "The maintainers reviewed the security requirements and boundaries in September 2026 and recorded the result as the threat model and policies in https://github.com/brazilian-utils/javascript/blob/main/SECURITY.md", "code_review_standards_status": "Met", diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ca59c2741..d273d919e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -10,7 +10,6 @@ - [ ] `docs/utilities.md` (English) - [ ] `docs/pt-br/utilities.md` (Portuguese) - [ ] `npm run check` passes locally (format, lint, types). -- [ ] I ran `npm run build:llms` if I touched `docs/utilities.md` (the Check workflow fails when `docs/llms.txt` is stale). - [ ] This change does not introduce a breaking change, **or** I flagged it clearly below and it was discussed with maintainers beforehand. - [ ] This change does not add any runtime dependency (this library is zero-runtime-dependency by design). diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index f0cea14de..a2455cc7a 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -53,16 +53,13 @@ jobs: - name: Validate the public API run: npm run check:api - - name: Check llms.txt/llms-full.txt build from the docs - run: npm run build:llms - - name: Check the JSR exports are up to date run: npm run build:jsr && git diff --exit-code -- jsr.json - - name: Build the documentation site - # The site is generated at deploy time (the Docs workflow), so nothing here can be stale; - # this only has to fail when a generator does. - run: npm run build:docs + - name: Generate the examples of the guides + # The docs site (brazilian-utils/docs) runs this before it reads `docs/`; the generated files + # are not committed, so this only has to fail when the generator does. + run: npm run build:examples - name: Check the VEX statements against the suppressed advisories run: npm run check:vex diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 6c05f68cb..000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,63 +0,0 @@ -# Builds the documentation site and publishes it to GitHub Pages. Everything the site needs that a -# script can write - the per-page shells, the sitemap, llms.txt, llms-full.txt and the examples of -# the document field page - is written here rather than kept in the repository, so a page and what -# it is generated from can never disagree. -# -# This needs Pages set to "GitHub Actions" (Settings -> Pages -> Build and deployment -> Source); -# serving the branch directly would publish `docs/` without these files. -name: Docs - -on: - push: - branches: [main] - paths: - - docs/** - - scripts/** - - package.json - - .github/workflows/docs.yml - workflow_dispatch: - -concurrency: - group: pages - cancel-in-progress: false - -permissions: - contents: read - -jobs: - deploy: - name: Build and deploy - runs-on: ubuntu-latest - timeout-minutes: 15 - - permissions: - pages: write - id-token: write - - environment: - name: github-pages - url: ${{ steps.deploy.outputs.page_url }} - - steps: - - name: Checkout code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - name: Setup - uses: ./.github/actions/setup - - - name: Build the site - run: npm run build:docs - - - name: Configure Pages - uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0 - - - name: Upload the site - uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0 - with: - path: docs - - - name: Deploy to Pages - id: deploy - uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1 diff --git a/.github/zizmor.yml b/.github/zizmor.yml index 27697cb21..890da5459 100644 --- a/.github/zizmor.yml +++ b/.github/zizmor.yml @@ -7,7 +7,6 @@ rules: ignore: - build.yml - check.yml - - docs.yml - datasets.yml - live-tests.yml - mutation.yml diff --git a/.gitignore b/.gitignore index 760402ec3..f78a0b1b1 100644 --- a/.gitignore +++ b/.gitignore @@ -18,16 +18,8 @@ reports # the one that pins this project's dependencies. deno.lock -# The documentation site is generated by `npm run build:docs` and published by the Docs workflow: -# only what a person writes is kept here. -docs/*.html -!docs/index.html -docs/pt-br/*.html -docs/guides/*.html -docs/pt-br/guides/*.html -docs/sitemap.xml -docs/llms.txt -docs/llms-full.txt +# The examples the guides show are generated from templates by `npm run build:examples` (the docs +# site, brazilian-utils/docs, runs it before reading `docs/`): only what a person writes is kept here. docs/snippets/document-field/generated/ docs/snippets/address-form/*/cep-field.* docs/snippets/address-form/*/field.* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 39fcad1c3..2592bf496 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,11 +42,8 @@ and is invoked through the `npm` scripts below, so you don't need to install any | `npm run test:chrome-browser`, `npm run test:firefox-browser`, `npm run test:edge-browser`, `npm run test:safari-browser` | Runs the test suite in real browsers via `vp test --browser.enabled`. | | `npm run build` | Builds the library for publishing with `vp pack` (also runs attw and publint over the built output). | | `npm run build:data` | Regenerates the datasets under `src/_internals/constants` from the IBGE/CONCLA sources (`scripts/data.ts`); run by the scheduled `Update datasets` workflow. | -| `npm run build:llms` | Regenerates `docs/llms.txt` and `docs/llms-full.txt` from the docs (`scripts/llms.ts`). Generated at deploy time, not kept in the repository. | -| `npm run build:site` | Regenerates the per-page copies of `docs/index.html`, `docs/404.html` and `docs/sitemap.xml` from the sidebars (`scripts/site.ts`). Generated at deploy time, not kept in the repository. | | `npm run build:jsr` | Regenerates the `exports` of `jsr.json`, one per utility folder (`scripts/jsr.ts`); CI fails if they're out of date. | -| `npm run build:docs` | Runs the three generators of the site above, which is what the Docs workflow deploys and what a Vercel preview builds. | -| `npm run build:examples` | Regenerates the examples of the document field page from their templates (`scripts/examples.ts`). Generated at deploy time, not kept in the repository. | +| `npm run build:examples` | Regenerates the examples of the guides from their templates (`scripts/examples.ts`); the docs site runs it before reading `docs/`. Generated, not kept in the repository. | | `npm run check:dependencies` | Fails if `package.json` declares any runtime `dependencies` (this package ships zero by design). | | `npm run check:tree-shaking` | Builds nothing; measures the single-import size of every export against `dist` (`scripts/tree-shaking.ts`). Run it after `npm run build` when you change a dataset, and update the bundle-size table in `docs/getting-started.md` / `docs/pt-br/getting-started.md`. | | `npm run check:duplication` | Runs [jscpd](https://jscpd.dev) over `src` and `scripts`; any copy-pasted block of 5+ lines / 50+ tokens fails. | @@ -179,7 +176,8 @@ example `formatSomething`): - `docs/pt-br/utilities.md` (Portuguese translation) 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 + belongs to (the docs site maps that heading to the utility's page, see + [Documentation](#documentation)), one sentence saying what it does, 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 @@ -187,11 +185,6 @@ example `formatSomething`): 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 - check the result. The two files are built at deploy time and never committed; CI runs the - generator, which fails only when a docs file it reads is missing. - 6. If the utility is based on an official Brazilian specification/document (e.g. a government validation algorithm), link to the authoritative source in the code comment (`@see`) or PR description so reviewers can verify the implementation. @@ -417,54 +410,48 @@ Every utility must keep working across all the runtimes this library targets: Avoid Node-specific APIs unless they are polyfilled/guarded, and prefer standard, widely available JavaScript/TypeScript features. -## Documentation site - -`docs/` is the source of [brazilian-utils.com.br](https://brazilian-utils.com.br), served by GitHub -Pages with [docsify](https://docsify.js.org): `docs/index.html` renders the Markdown in the -browser, with `_sidebar.md`, `_navbar.md` and `_coverpage.md` as its navigation. - -- Only what a person writes lives in `docs/`: the `Docs` workflow runs `npm run build:docs` and - publishes the result to GitHub Pages, so the page shells, `sitemap.xml`, `llms.txt`, - `llms-full.txt` and the generated examples are never committed (and never stale). Run - `npm run build:docs` to see the site as it is published; a pull request that touches `docs/` or - `scripts/` gets the same build as a Vercel preview. -- docsify runs in history mode, so every page is a real URL (`/getting-started`, - `/pt-br/utilities`) that search engines index on its own. GitHub Pages serves each one from a - copy of `index.html` next to the page (`getting-started.html`) that carries the page's own - title, description, canonical URL and hreflang pair, and `npm run build:site` - (`scripts/site.ts`) writes those copies, `404.html` and `sitemap.xml` from the sidebars and the - pages' front matter. Links from the hash-router era (`/#/getting-started?id=usage`) are - rewritten on load, so nothing out there breaks. -- Every page starts with a front matter block with a quoted `title` and `description` (and - `keywords`), and has no `#` heading of its own: the plugin in `docs/index.html` turns the title - into the page's heading and the block feeds the page's metadata (a small wrapper there hands - the search plugin the same view, so the block never shows up in search results). Scripts read - the block through `scripts/front-matter.ts`. -- The site's own CSS is `docs/styles.css`, linked by every shell: styles go there, not in a - `