Skip to content

feat: generate typed SDK from OpenAPI and prepare v6 - #121

Open
javorosas wants to merge 42 commits into
mainfrom
chore/sdk-6-release-and-tooling
Open

javorosas wants to merge 42 commits into
mainfrom
chore/sdk-6-release-and-tooling

Conversation

@javorosas

@javorosas javorosas commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Generate request/response types, public model aliases, resource methods, and response date plans from a public OpenAPI contract pinned to a documentation commit using openapi-typescript and the TypeScript compiler.
  • Cover all 118 documented HTTP operations and 238 component schemas while preserving existing resource names, method aliases, HTTP transport, binary downloads/uploads, and local signature verification.
  • Decode declared date-time fields as Date values without a handwritten date-path inventory. Preserve calendar dates, SAT stamp text, custom XML, and opaque metadata. Test new date fields, dictionaries, recursive models, and complement discriminants.
  • Refine CFDI edit discriminants and structured complement inputs, preserve required composed fields, require overtime details for payroll perception 019 and own-resource amounts for mixed funding, and type road transport vehicle/insurance requirements. Input perception codes follow the published catalog; response codes remain open strings. No client-side validation is added.
  • Accept omitted/default invoice use, supported nullable draft fields, and payment complement data as a single payment object or an array. Align documented invoice defaults and keep release notes concise.
  • Add typed receipt invoice/dry-run overloads, receipt customer assignment, FIEL upload, and API health checks. Expose input models and complete complement enum members.
  • Prepare SDK 6.0, modernize dependencies/ESLint, use Rolldown for JavaScript and declarations, and publish ESM/CommonJS entry points with matching declarations. CommonJS supports require('facturapi') while retaining .default.
  • Keep only the public documentation repository, path and full commit SHA in openapi/source.json. Synchronization resolves docs main or an explicit public ref once, downloads from that exact commit, and records the SHA only after parsing succeeds. Generation always reads the pinned commit into memory; no downloaded specification or custom checksum manifest is committed.
  • Generate method descriptions, argument/return documentation and absolute documentation links from the spec; preserve SDK-specific upload/download and local signature guidance, including docs on every receipt invoice overload.
  • Keep public imports at the package root. Update migration guidance, preserve published changelog entries, and document contributor generation/check commands.

Release coordination

Consolidates #120 and #121 into one SDK 6.0 release PR against main. Includes consistent response date hydration and the related type corrections; #120 is superseded by this PR.

The pinned public documentation commit includes the contract corrections in FacturAPI/facturapi-docs#303. Until that PR is merged, sync its public branch to a full SHA; resync to main after merge. Moving docs branches no longer invalidates generation checks. Builds and runtime tests use committed generated sources without network access or sibling checkouts; generation downloads the spec from the recorded commit. Merge #303 after SDK 6 is published so its CommonJS installation example matches the available release.

Validation

  • Build and generated-file reproducibility checks. Simplified operation bindings from 2421 to 566 lines by deriving paths, bodies, and query arguments from OpenAPI; the binding refactor preserved generated signatures and behavior. Method documentation has since been enriched; transpiled runtime code remains identical in all 11 resource/tool files. Explicit overrides preserve established signatures and special behavior.
  • 51 Node tests and 10 web runtime tests, including real local cryptography and compiler-based date discovery.
  • Public TypeScript contracts with NodeNext and legacy CommonJS resolution, ISO/Date input values, read-only response fields excluded from requests, payment-summary reuse, catalog codes with leading zeros, and invoice/dry-run result overloads.
  • Four native package compatibility/export checks and three Chromium tests; dedicated CI runs the native checks on Node 18.
  • Dependency audit: no known vulnerabilities; YAML parser updated to 5.4.2.
  • Lint and git diff checks. Published changelog entries remain byte-identical.

@javorosas javorosas changed the title Prepare SDK 6.0 release and modernize tooling and package exports feat: generate typed SDK from OpenAPI and prepare v6 Sep 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Invoice creation currently returns untyped fields and leaves response timestamps as strings.

Review effort: Balanced
Findings: None

What changed in this PR

This PR prepares the SDK for v6 by generating its public types and resource methods from a pinned OpenAPI contract. It builds on the response-date work in #120 and coordinates with the public contract corrections in facturapi-docs#303.

Changes:

  • Generate typed methods, models, and response-date plans while retaining the existing transport and webhook validation.
  • Add ESM and CommonJS packaging, compatibility checks, and SDK generation checks.
  • Update consumer migration guidance and release notes.
File Description
vitest.web.config.mts Configures web unit tests.
vitest.node.config.mts Configures Node unit tests.
vite.config.ts Removes the old build configuration.
vite.config.mts Configures ESM and CommonJS bundles.
test/​node/​sdk-generation.node.test.ts Tests date-plan discovery.
test/​node/​runtime-compat.node.test.ts Extends runtime response tests.
test/​compat/​node18-compat.test.cjs Checks CommonJS compatibility.
test/​compat/​esm-compat.test.mjs Checks native ESM imports.
test/​browser/​runtime-smoke.browser.spec.ts Updates the browser bundle path.
test-d/​runtime-types.test-d.ts Tests public type contracts.
test-d/​package-exports.mts Checks ESM declarations.
test-d/​package-exports.cts Checks CommonJS declarations.
src/​wrapper.ts Applies generated response-date plans.
src/​types/​webhook.ts Uses generated webhook types.
src/​types/​runtime.ts Defines portable binary types.
src/​types/​retention.ts Exposes generated retention aliases.
src/​types/​receipt.ts Exposes generated receipt aliases.
src/​types/​product.ts Exposes the generated product alias.
src/​types/​organization.ts Exposes generated organization aliases.
src/​types/​invoice.ts Exposes generated invoice aliases.
src/​types/​index.ts Exports generated models.
src/​types/​customer.ts Exposes generated customer aliases.
src/​types/​complements.ts Exposes generated complement aliases.
src/​types/​common.ts Exposes generated common aliases.
src/​tools/​webhooks.ts Generates webhook methods.
src/​tools/​tools.ts Adds the API health method.
src/​tools/​comercioExteriorCatalogs.ts Generates catalog search typing.
src/​tools/​catalogs.ts Generates catalog search typing.
src/​tools/​cartaPorteCatalogs.ts Generates Carta Porte catalog methods.
src/​runtime/​webhooks.ts Preserves signature validation and hydrates events.
src/​runtime/​uploads.ts Prepares binary uploads.
src/​runtime/​dates.ts Applies date plans to responses.
src/​resources/​retentions.ts Generates typed retention methods.
src/​resources/​receipts.ts Generates typed receipt methods and overloads.
src/​resources/​products.ts Generates typed product methods.
src/​resources/​customers.ts Generates typed customer methods.
src/​generated/​models.ts Exports generated model aliases.
src/​generated/​dates.ts Stores generated date plans.
src/​generated/​contracts.ts Defines operation request and response types.
src/​enums.ts Adds complement enum members.
scripts/​sync-openapi.mjs Syncs the pinned public contract.
scripts/​sdk/​models.json Maps public model names.
scripts/​sdk/​enums.json Maps semantic enum bindings.
scripts/​sdk/​date-plans.mjs Compiles date plans from types.
scripts/​generate-sdk.mjs Generates SDK files from OpenAPI.
scripts/​commonjs-types.mjs Produces CommonJS declarations.
rolldown.config.mjs Configures declaration bundling.
README.md Updates usage and migration guidance.
package.json Prepares v6 exports, scripts, and dependencies.
openapi/​source.json Pins the public contract revision.
eslint.config.mjs Adds the updated lint configuration.
eslint.config.js Removes the old lint configuration.
CHANGELOG.md Documents consumer-facing v6 changes.
AGENTS.md Documents contributor generation practices.
.prettierignore Excludes generated artifacts from formatting.
.gitignore Ignores test and browser reports.
.github/​workflows/​ci.yml Adds generation and compatibility checks.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@javorosas
javorosas removed this pull request from stack #122 September 30, 2026 22:41
@javorosas
javorosas changed the base branch from FAC-2305-fix-response-date-types to main September 30, 2026 22:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved critical and moderate findings affect declarations, date serialization, webhook responses, and the pinned contract.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity · 4 Low severity

Open (7)

Comment thread scripts/commonjs-types.mjs
Comment thread scripts/generate-sdk.mjs Outdated
Comment thread src/runtime/webhooks.ts Outdated
Comment thread scripts/sdk/documentation.mjs Outdated
Comment thread src/resources/products.ts Outdated
Comment thread src/resources/retentions.ts Outdated
Comment thread src/tools/webhooks.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +53 to +63
if (type.isUnion()) {
nodes[id] = {
kind: 'union',
variants: type.types.map((variant) => ({
plan: compile(variant),
match: Object.fromEntries(
checker.getPropertiesOfType(variant).flatMap((property) => {
const values = literals(
checker.getTypeOfSymbolAtLocation(property, source),
)
return values.length === 1 ? [[property.name, values]] : []
Comment thread src/runtime/dates.ts
Comment on lines +40 to +41
) || plan.variants.find((variant) => !Object.keys(variant.match).length)
return variant ? deserializeResponseDates(value, variant.plan) : value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants