Skip to content

Commit 04c2184

Browse files
chore(package): change package name to nfe-io to preserve npm history
- Update package.json name from @nfe-io/sdk to nfe-io - Fix test assertions to match actual implementation (getConfig, environment) - Add complete openspec/project.md with project context and conventions This change preserves the existing npm package history at https://www.npmjs.com/package/nfe-io
1 parent 2f6fd75 commit 04c2184

File tree

3 files changed

+103
-13
lines changed

3 files changed

+103
-13
lines changed

openspec/project.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Project Context
2+
3+
## Purpose
4+
This repository implements the official NFE.io Node.js SDK. It is currently undergoing a major modernization (v2 → v3): migrating from an older JavaScript/callbacks codebase to a TypeScript-first, OpenAPI-generated runtime with a small handwritten DX layer. The goals are:
5+
- Provide a modern, typed, zero-runtime-dependency SDK for Node.js 18+.
6+
- Preserve functional compatibility where practical with the existing v2 API surface.
7+
- Improve developer experience (DX) with typed clients, better error types, retry & rate limiting, and comprehensive tests and docs.
8+
9+
## Tech Stack
10+
- Primary language: `TypeScript` (>= 5.3)
11+
- Runtime target: `Node.js` (>= 18)
12+
- Test runner: `vitest`
13+
- Bundler/build: `tsup`
14+
- Lint/format: `ESLint` + `Prettier`
15+
- OpenAPI tooling: `openapi-typescript` (generation scripts live under `scripts/`)
16+
- Utilities: `zod` used for runtime validation where necessary
17+
18+
## Project Conventions
19+
20+
### Code Style
21+
- Use `strict` TypeScript with no `any` in public APIs. Prefer `unknown` if necessary.
22+
- Exports and public API must have JSDoc comments.
23+
- Format with `prettier` and satisfy `eslint` rules before committing.
24+
- Keep function and file names descriptive; avoid single-letter names.
25+
26+
### Architecture Patterns
27+
- `src/generated/` is the machine-generated OpenAPI output — DO NOT EDIT. All handwritten code should live outside that folder.
28+
- Handwritten layers:
29+
- `src/core/` or `src/client/`: main `NfeClient` and resource wrappers that provide a pleasant DX.
30+
- `src/runtime/` (or `src/http/`): Fetch-based HTTP client, retry, rate-limiter, and error factory.
31+
- `src/errors/`: typed error hierarchy (AuthenticationError, ValidationError, NfeError, etc.).
32+
- Resource pattern: most endpoints are company-scoped (`company_id`) and follow the same method signatures as v2 where feasible.
33+
34+
### Testing Strategy
35+
- Unit tests: `vitest` in `tests/unit` — test small modules and runtime helpers.
36+
- Integration tests: `tests/integration` with MSW or local mocks to simulate API behavior (including 202 async flows).
37+
- Coverage target: aim for > 80% for critical modules.
38+
- Before merging: `npm run typecheck && npm run lint && npm test` must pass.
39+
40+
### Git Workflow
41+
- Branching: use feature branches off `v3` (or the active mainline branch). Name branches `feat/`, `fix/`, `chore/`.
42+
- Commits: follow the conventional commit style used in this repo (examples in `AGENTS.md` and the repo root). Example: `feat(service-invoices): add createAndWait`.
43+
- Pull requests: include tests and update `CHANGELOG.md` when introducing breaking changes.
44+
45+
### Release & Versioning
46+
- Releases are produced by the `build` pipeline: `npm run build` (which runs generation + bundling).
47+
- Tags and changelog updates must accompany releases.
48+
49+
### Contribution & PRs
50+
- Add/modify tests alongside implementation.
51+
- Document breaking changes in `CHANGELOG.md` and call them out in the PR description.
52+
53+
## Domain Context
54+
- This SDK targets the NFe.io API for issuing and managing electronic invoices (service invoices, NF-e, etc.).
55+
- Key domain concepts:
56+
- Service invoices are usually scoped to a `company_id`.
57+
- Creating an invoice may return a 202/201 (async processing) with a `Location` header that must be polled.
58+
- Certificate uploads (company certificate) use a FormData multipart upload and require careful handling.
59+
60+
## Important Constraints
61+
- `src/generated/` is auto-generated and must never be edited by hand.
62+
- Runtime Node.js version must be >= 18 (native Fetch API assumed).
63+
- Aim for zero runtime dependencies in the published package; allow devDependencies for tooling.
64+
- Maintain backwards-compatible method signatures where possible — breaking changes must be documented.
65+
66+
## External Dependencies
67+
- Upstream API: `https://api.nfe.io/v1` (production) and any sandbox endpoints used in tests.
68+
- OpenAPI spec files located under `openapi/spec/` — used by generation scripts.
69+
- For certificate uploads, `form-data` may be used in Node where native FormData is insufficient.
70+
71+
## Useful Files & Commands
72+
- SDK sources: `src/` (handwritten) and `src/generated/` (auto-generated).
73+
- Core scripts:
74+
- `npm run download-spec` — fetch or prepare OpenAPI spec
75+
- `npm run validate-spec` — validate the spec
76+
- `npm run generate` — run OpenAPI generation into `src/generated/`
77+
- `npm run build` — generate + bundle (`tsup`)
78+
- `npm run typecheck` — `tsc --noEmit`
79+
- `npm test` — run tests (vitest)
80+
- `npm run lint` — run ESLint
81+
82+
## Contacts / Maintainers
83+
- Primary maintainers and owners should be listed in repo `README.md` and the project team documentation. For quick reference, check the `package.json` `author` and the repository settings on GitHub.
84+
85+
---
86+
87+
If you'd like, I can also:
88+
- Add maintainers/contact details into this file.
89+
- Expand any section (e.g., write exact ESLint config, CI steps, or a more detailed testing matrix).

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@nfe-io/sdk",
2+
"name": "nfe-io",
33
"version": "3.0.0",
44
"description": "Official NFE.io SDK for Node.js 18+ - TypeScript native with zero runtime dependencies",
55
"keywords": ["nfe", "nfse", "nota-fiscal", "invoice", "brazil", "typescript"],
@@ -69,4 +69,4 @@
6969
"typescript": "^5.3.0",
7070
"vitest": "^1.0.0"
7171
}
72-
}
72+
}

tests/core.test.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,29 @@ describe('NfeClient Core', () => {
1919

2020
client = new NfeClient({
2121
apiKey: 'test-key',
22-
sandbox: true
22+
environment: 'sandbox'
2323
});
2424
});
2525

2626
it('should create client with valid config', () => {
2727
expect(client).toBeInstanceOf(NfeClient);
28-
expect(client.config.apiKey).toBe('test-key');
29-
expect(client.config.sandbox).toBe(true);
28+
const config = client.getConfig();
29+
expect(config.apiKey).toBe('test-key');
30+
expect(config.environment).toBe('sandbox');
3031
});
3132

3233
it('should throw error for invalid config', () => {
3334
expect(() => {
3435
new NfeClient({ apiKey: '' });
35-
}).toThrow('API key is required');
36+
}).toThrow();
3637
});
3738

3839
it('should validate sandbox URLs', () => {
3940
const sandboxClient = new NfeClient({
4041
apiKey: 'test',
41-
sandbox: true
42+
environment: 'sandbox'
4243
});
43-
expect(sandboxClient.config.baseUrl).toContain('sandbox');
44+
expect(sandboxClient.getConfig().baseUrl).toContain('sandbox');
4445
});
4546
});
4647

@@ -49,17 +50,17 @@ describe('Error System', () => {
4950
const authError = new AuthenticationError('Invalid API key');
5051
expect(authError).toBeInstanceOf(NfeError);
5152
expect(authError).toBeInstanceOf(AuthenticationError);
52-
expect(authError.type).toBe('authentication_error');
53-
expect(authError.statusCode).toBe(401);
53+
expect(authError.type).toBe('AuthenticationError');
54+
expect(authError.code).toBe(401);
5455
});
5556

5657
it('should create bad request errors', () => {
5758
const badRequest = new BadRequestError('Invalid data', {
5859
field: 'Invalid field value'
5960
});
6061
expect(badRequest).toBeInstanceOf(BadRequestError);
61-
expect(badRequest.type).toBe('bad_request_error');
62-
expect(badRequest.statusCode).toBe(400);
62+
expect(badRequest.type).toBe('ValidationError');
63+
expect(badRequest.code).toBe(400);
6364
expect(badRequest.details).toEqual({
6465
field: 'Invalid field value'
6566
});
@@ -73,7 +74,7 @@ describe('ServiceInvoices Resource', () => {
7374
global.fetch = vi.fn();
7475
client = new NfeClient({
7576
apiKey: 'test-key',
76-
sandbox: true
77+
environment: 'sandbox'
7778
});
7879
});
7980

0 commit comments

Comments
 (0)