@assinafy/sdk 2.0.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,469 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@assinafy/sdk` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.1.1] - 2026-08-06
11
+
12
+ Maintenance only. The published `dist/` is byte-identical to 2.1.0; no runtime,
13
+ type, or API surface changed.
14
+
15
+ ### Changed
16
+
17
+ - Dependabot no longer proposes `typescript` 7.x. TypeScript 7 is the native
18
+ rewrite: the `typescript` entrypoint exports only `{version,
19
+ versionMajorMinor}` and the compiler API moved to `typescript/unstable/*`
20
+ with a different shape. That breaks `tsup --dts` (bundled `rollup-plugin-dts`
21
+ reads `ts.sys.useCaseSensitiveFileNames` at module load) and falls outside
22
+ `typescript-eslint`'s `>=4.8.4 <6.1.0` peer range. The ignore is documented
23
+ in `.github/dependabot.yml` and should be removed once both support TS 7.
24
+
25
+ ## [2.1.0] - 2026-08-06
26
+
27
+ ### Added
28
+
29
+ - Full typed coverage of the current official OpenAPI contract: **89/89
30
+ operations across 68 paths**, including account theme/logo/statistics, OAuth
31
+ URL helpers/linking, authenticated-user profile/statistics, and all signer
32
+ response/acknowledgement shapes.
33
+ - An exhaustive machine-auditable endpoint ledger (`docs/API_COVERAGE.md`),
34
+ compatibility record, and a scheduled OpenAPI operation-drift gate.
35
+ - Strict test-source typechecking and enforced Bun coverage floors. The suite
36
+ now executes every public HTTP wrapper and covers the production source at
37
+ more than 95% of functions and 98% of lines.
38
+ - Canonical GitLab CI plus SHA-pinned GitHub mirror workflows. Tag mirrors now
39
+ build one immutable tarball, verify its checksum, and publish that same file
40
+ to npm (OIDC trusted publishing) and GitHub Packages.
41
+
42
+ ### Fixed
43
+
44
+ - Public/login/signer-code requests now use a credential-free transport, so
45
+ account API keys and Bearer tokens cannot leak onto public routes.
46
+ - The high-level upload workflow validates every signer before uploading and
47
+ always waits for document metadata before creating an assignment; opting out
48
+ only skips the final presentation re-fetch.
49
+ - `sendToken(documentId, email)` now sends the official `{ email }` request and
50
+ uses the legacy `{ recipient, channel }` form only explicitly or after a
51
+ narrowly matched compatibility error.
52
+ - Empty success acknowledgements resolve to `void`, malformed list envelopes
53
+ throw instead of silently becoming `[]`, and API response types were aligned
54
+ with nullable/variant wire shapes.
55
+ - Automatic `429` replay is now limited to idempotent HTTP methods. `POST` and
56
+ `PATCH` require an explicit non-empty `Idempotency-Key`.
57
+ - Configuration, upload files/PDF content, dynamic paths, polling values,
58
+ signer updates, webhook inputs/events, and pagination metadata receive strict
59
+ validation; diagnostic logging and network-error causes no longer expose
60
+ request credentials or user payloads.
61
+ - Restored the official name-only signer request and account
62
+ `notification_sender_type` field. Both are now represented exactly as the
63
+ OpenAPI defines them; the live audit records the sandbox's lagging rejection
64
+ of `notification_sender_type` without blocking unrelated endpoint tests.
65
+ - Restored the official public, code-free signer artifact download while
66
+ retaining an optional access-code argument for legacy deployments, and made
67
+ owner-only assignment-signer fields optional in signer-context responses.
68
+
69
+ ### Security
70
+
71
+ - Updated the dependency graph and overrides to **zero known advisories**.
72
+ - Removed arbitrary-ref/manual publishing, pinned current actions to immutable
73
+ commit SHAs, set least-privilege permissions/timeouts, and removed the
74
+ long-lived npm publish token in favor of OIDC.
75
+ - Clarified that webhook HMAC verification is an opt-in utility: the current
76
+ Assinafy OpenAPI document does not specify a signing header or algorithm.
77
+
78
+ ### Earlier 2.1.0 audit work (completed 2026-07-19)
79
+
80
+ Full audit against the live sandbox API (`https://sandbox.assinafy.com.br/v1`)
81
+ and the OpenAPI reference: every safely runnable operation was probed, fixture-
82
+ or legal-consent-dependent operations were recorded as explicit skips, and the
83
+ SDK was reconciled against the observed request/response shapes.
84
+
85
+ #### Fixed
86
+
87
+ - **`signerDocuments.acceptTerms()` and `signerDocuments.verifyEmail()` were
88
+ unauthenticated.** Both sent the `signer-access-code` in the JSON request body,
89
+ but the API's `signerAccessCode` security scheme is a **query** parameter — so
90
+ every call was rejected with `401`. They now pass the code as
91
+ `?signer-access-code=…` (matching every other signer-side method), and
92
+ `verifyEmail` sends only `verification-code` in the body.
93
+ - **`uploadAndRequestSignatures()` returned a stale document.** With
94
+ `waitForReady` enabled (the default) it still returned the pre-processing
95
+ upload snapshot (`status: 'uploaded'`, empty `pages`, no `assignment`). It now
96
+ returns the document re-fetched after the assignment is created, so `status`,
97
+ `pages`, and the embedded `assignment` are current.
98
+ - **README workspace example used an invalid colour.** `primary_color:
99
+ '#ff0066'` is rejected by the account endpoints, which require exactly 6 hex
100
+ characters with **no** leading `#` (verified live). Fixed the example and
101
+ documented the format on the payload types.
102
+
103
+ #### Added
104
+
105
+ - **`workspaces.delete(accountId, { force: true })`** — send the documented
106
+ `force` flag (in the request body) to override deletion restrictions.
107
+ - **`signerDocuments.uploadSignature(..., { reuse: true })`** — expose the API's
108
+ `reuse` query flag to persist a signature for reuse on future documents.
109
+ - **`confirmData()` now accepts the documented `full_name` and `government_id`**
110
+ fields (additive; `undefined` values are stripped).
111
+ - **`IDocumentUploadResponse.signing_url`** — the upload endpoint always returns
112
+ it (previously missing from the type).
113
+ - **`IAssignmentEntry`** — a typed shape for `collect`-method assignment
114
+ `entries` (was `unknown[]`).
115
+ - Request/response payload examples on **every** public method, and expanded
116
+ unit-test coverage across all resources.
117
+
118
+ #### Changed
119
+
120
+ - **`IDocumentUploadResponse.declined_by`** is now typed `ISigner | null` (was
121
+ `string | null`), matching the sibling document response types and the API.
122
+ - Workspace `events` on webhook registration and `socialLogin.provider` now use
123
+ the open-enum (`… | AnyString`) convention, keeping literal autocomplete while
124
+ accepting server-controlled strings.
125
+ - **Tooling / CI:** GitHub Actions are pinned to commit SHAs (with a
126
+ `dependabot.yml` to keep them and npm deps current); the release workflow pins
127
+ an exact Bun version for reproducible, provenance-signed publishes; `scripts/`
128
+ is now linted and typechecked; the redundant `.npmignore` and the stale,
129
+ CI-unused `package-lock.json` were removed (the repo is Bun-first).
130
+
131
+ #### Compatibility notes
132
+
133
+ - The sandbox still rejects `notification_sender_type` during account creation
134
+ but accepts it during update. The SDK exposes the official field and records
135
+ that sandbox lag explicitly instead of deleting documented functionality.
136
+ - The live list API clamps `per-page` to **50**. `sendToken` uses the current
137
+ official `{ email }` body first and retains the older `{ recipient, channel }`
138
+ form as an explicit, narrowly scoped compatibility path.
139
+
140
+ ## [2.0.0] - 2026-07-15
141
+
142
+ ### Removed (breaking)
143
+
144
+ - **`webhooks.delete()`** — `DELETE /accounts/{id}/webhooks/subscriptions`
145
+ returns `404`; the endpoint does not exist. Use **`webhooks.inactivate()`**
146
+ (`PUT /accounts/{id}/webhooks/inactivate`) to stop deliveries; the
147
+ subscription is retained and re-enabled by calling `webhooks.register()` again
148
+ with `is_active: true`. The method never functioned, so no working runtime
149
+ behaviour changes.
150
+
151
+ ### Fixed
152
+
153
+ - **`per_page` was silently ignored on every list call.** The API reads only
154
+ `per-page`; `per_page` is accepted and discarded, so the response fell back to
155
+ 20 items (verified: `?per-page=2` → 2 items, `?per_page=2` → 20). Every list
156
+ method's documentation advertised `per_page`, so paging appeared to work while
157
+ quietly returning the wrong page size. Both spellings are now honoured —
158
+ `per_page` is normalised to `per-page`, and an explicit `per-page` wins.
159
+ - `signers.findByEmail` asked for `per_page: 100` and therefore received 20.
160
+ It now requests the API's **maximum page size of 50** (larger values are
161
+ silently clamped to 50 by the server).
162
+ - **Failed artifact downloads reported "API request failed".** Downloads are
163
+ issued with `responseType: 'arraybuffer'`, which axios also applies to error
164
+ responses, so JSON error bodies arrived as a Buffer and the real message was
165
+ discarded. `download`, `thumbnail`, `downloadPage`, `templates.downloadPage`
166
+ and the signer-side downloads now surface what the server actually said (e.g.
167
+ "Artefato não está disponível." when requesting `certificated` before signing).
168
+ - **`signers.create` could not recover from a duplicate-email race.** It caught
169
+ `409`, but this API answers a duplicate email with **400**, so the recovery
170
+ path never ran. It now handles both and still rethrows unrelated 4xx.
171
+ - **`waitUntilReady` reported auth and not-found failures as a timeout.** The
172
+ poll loop swallowed every `ApiError`, so an invalid API key, a wrong account,
173
+ or a deleted document burned the full `maxWaitMs` and then threw
174
+ `ValidationError('Timeout waiting for document to be ready')`. Because
175
+ `uploadAndRequestSignatures` awaits it by default, a bad key hung the SDK's
176
+ flagship helper for 30 s and then misreported the cause. A 4xx now surfaces
177
+ immediately; 5xx and 429 still retry as before.
178
+ - **`toSdkError` dropped `cause` when a non-`Error` value was thrown.** The
179
+ cause was passed into the `context` parameter instead of `options`, so
180
+ `error.cause` was `undefined` exactly where the original throw was least
181
+ identifiable. It now populates `cause` and leaves `context` empty.
182
+ - **`templates.create(source, { name })` silently ignored `name`.** The API
183
+ derives a template's display name from the filename of the uploaded `file`
184
+ part, not from a `name` field, so every template was named after the uploaded
185
+ file regardless of the option. `name` is now applied.
186
+ - `.pdf` is appended when absent: `'NDA template'` → `'NDA template.pdf'`.
187
+ - Accents are transliterated by the API: `'Contrato de Serviço'` is stored as
188
+ `'Contrato de Servico.pdf'`.
189
+ - Callers who passed `name` and relied on the previous filename-derived result
190
+ will now get the name they asked for.
191
+
192
+ ### Added
193
+
194
+ - **`documents.upload(source, { name })`** — uploaded documents could not
195
+ previously be named. Same semantics as `templates.create`.
196
+ - **`documents.search(params, accountId?)`** — `GET /accounts/{id}/documents/search`.
197
+ A lighter-weight `list`: same item shape, without the expanded
198
+ `assignment`/`pages`. Supports `search`, `status`, `page`, `per-page`.
199
+ - **`documents.rename(documentId, name)`** — `PATCH /documents/{id}`. Returns
200
+ `400` while the document is still in `metadata_processing`, so await
201
+ `waitUntilReady()` first on a fresh upload; passing `name` to `upload()`
202
+ avoids both the round-trip and the wait.
203
+ - **`assignments.list(params, accountId?)`** — `GET /assignments`, paginated via
204
+ `page` / `per-page`.
205
+ - **`signerDocuments.search(signerId, accessCode, search?)`** —
206
+ `GET /signers/{id}/documents/search`, the signer-side counterpart of
207
+ `documents.search`.
208
+ - **`IPage`** — a real type for document/template `pages[]`:
209
+ `{ id, number, height, width, download_url?, fields? }`.
210
+ - **`MAX_UPLOAD_BYTES`** is now exported, so callers can check a file against the
211
+ API's 25 MB limit before uploading.
212
+ - **`AnyString`** — used to keep editor autocomplete on fields like
213
+ `AssignmentVerificationMethod` and `SendTokenChannel`. `'Email' | 'Whatsapp' |
214
+ string` collapses to plain `string` and loses the suggestions; these now read
215
+ `'Email' | 'Whatsapp' | AnyString`. Any string is still accepted, so values the
216
+ API adds later keep type-checking.
217
+
218
+ ### Changed (breaking)
219
+
220
+ - **Node.js 22+ is now required** (`engines: >=22`, was `>=20`). Node 20 reached
221
+ end-of-life in April 2026. The SDK is tested on Node 22 and 24 against the
222
+ built CJS and ESM artifacts.
223
+ - **`exports` now declares per-condition `types`**, so ESM consumers resolve
224
+ `dist/index.d.mts` instead of the CJS-flavoured `dist/index.d.ts`.
225
+
226
+ ### Internal
227
+
228
+ - Compiled against ES2022 with `noUncheckedIndexedAccess`, `isolatedModules` and
229
+ `verbatimModuleSyntax` enabled (each produced zero errors). ES2022 also lets
230
+ the error classes pass `cause` through the native `Error` constructor instead
231
+ of assigning it behind a cast.
232
+ - `src` is now typechecked against `@types/node` rather than `bun-types`. The
233
+ package ships to Node but was type-checked against Bun's globals, so a
234
+ Bun-only API would have compiled cleanly and failed at runtime for consumers.
235
+ - `documents.upload` and `templates.create` were byte-for-byte the same
236
+ load → validate → build-form → POST → assert-id sequence over different paths;
237
+ both now share `BaseResource.uploadPdf`.
238
+
239
+ ### Heads-up for upgraders (type-level — no runtime break)
240
+
241
+ - **`ITemplateDetailsResponse.pages` and `IDocumentDetailsResponse.pages` are
242
+ now `IPage[]`** (were `unknown[]`). This fixes the documented
243
+ `template.pages![0].id` pattern, which previously failed to compile with
244
+ `TS2571: Object is of type 'unknown'`. Code that cast `pages` to a local shape
245
+ can drop the cast.
246
+ - **`IWebhookDispatch.created_at` / `updated_at` are now `string`** (were
247
+ `number`). The API sends ISO-8601 (`'2026-07-15T20:04:36Z'`), so arithmetic on
248
+ these was always operating on a string.
249
+ - **`ITemplateListItem` gained `pages` and lost `resource` / `account_id`.** The
250
+ list endpoint does return `pages` — so `template.pages` no longer fails to
251
+ compile — and never returned the other two. `ITemplateDetailsResponse.account_id`
252
+ was likewise a phantom and is gone.
253
+ - **`documents.rename` now returns `IRenameDocumentResponse`**
254
+ (`Omit<IDocumentDetailsResponse, 'pages' | 'assignment'>`). The endpoint does
255
+ not return either field, so the old type promised a required `pages` array
256
+ that was `undefined` at runtime.
257
+ - **`ICreateAssignmentPayload.copy_receivers` is documented as unreliable.** On
258
+ the sandbox plan the API accepts it and persists nothing — verified `[]` from
259
+ `create`, `list` and `details().assignment`, for both emails and signer IDs.
260
+ Kept (it may be plan-gated) but do not assume a CC was delivered.
261
+
262
+ ## [1.5.0] - 2026-06-05
263
+
264
+ Full production-readiness audit against [the live API docs](https://api.assinafy.com.br/v1/docs),
265
+ re-verified end-to-end against the live **sandbox** (`https://sandbox.assinafy.com.br/v1`).
266
+ Closes the last coverage gap (Template create/update/delete), removes a dead
267
+ endpoint, tightens types to the real wire shapes, and modernises the toolchain.
268
+
269
+ ### Removed
270
+
271
+ - **`assignments.cancel`** — it called
272
+ `POST /accounts/{id}/signature-requests/{id}/cancel`, which is undocumented and
273
+ returns `404` on the live API (verified). There is no workspace-side cancel
274
+ endpoint — cancel by deleting the document (`documents.delete`, when its status
275
+ is deletable) or via the signer-side decline
276
+ (`signerDocuments.decline(documentId, assignmentId, accessCode, reason)`).
277
+ The method never functioned, so no working runtime behaviour changes.
278
+
279
+ ### Heads-up for upgraders (type-level / advisory — no runtime break)
280
+
281
+ - **`IAssignment.signing_urls` is now `Array<{ signer_id, url }>`** (was
282
+ `Record<string, string>`) — matching the live/doc payload. TypeScript code that
283
+ indexed it as a map (`signing_urls[signerId]`) should switch to finding the
284
+ entry by `signer_id`.
285
+ - **`IWebhookSubscription` no longer declares `id` / `created_at`** — the API
286
+ returns `{ events, is_active, url, email, updated_at }` (one subscription per
287
+ workspace, keyed by URL).
288
+ - **Recommended Node is now 20+** (`engines` updated; Node 18 is end-of-life).
289
+ Advisory only — `engines` does not block installs on older runtimes.
290
+
291
+ ### Added
292
+
293
+ - **`TemplateResource.create`** — `POST /accounts/{id}/templates` (multipart PDF
294
+ upload). Returns the template object (status `Uploaded` → `Ready`).
295
+ - **`TemplateResource.update`** — `PUT /accounts/{id}/templates/{id}` (`name`,
296
+ `message`).
297
+ - **`TemplateResource.delete`** — `DELETE /accounts/{id}/templates/{id}`.
298
+ - **Automatic 429 retry.** The client retries rate-limited requests up to
299
+ `maxRetries` times (default `2`), honoring `Retry-After` /
300
+ `X-Rate-Limit-Reset`. Configure via the new `maxRetries` client option; set
301
+ `0` to disable.
302
+ - Exported `DEFAULT_WEBHOOK_EVENTS` (the default `webhooks.register` event set).
303
+ - New types: `ICostEstimate`, `IResendCostEstimate`, `IAssignmentSigner`,
304
+ `IAssignmentItem`, `IUpdateTemplatePayload`.
305
+
306
+ ### Changed
307
+
308
+ - `assignments.estimateCost` / `documents.estimateCostFromTemplate` now return
309
+ the typed `ICostEstimate`; `assignments.estimateResendCost` returns
310
+ `IResendCostEstimate` (was `Record<string, unknown>`).
311
+ - `IAssignment.items` / `.signers` are now fully typed (`IAssignmentItem[]` /
312
+ `IAssignmentSigner[]`); `IDocumentListItem` exposes the `artifacts`,
313
+ `signing_url`, `pages`, `assignment`, `decline_reason`, `declined_by` fields
314
+ the API actually returns; `IDocumentUploadResponse.assignment` is optional;
315
+ `IWorkspaceResponse` colors are nullable; `IDocumentDetailsResponse` gains
316
+ `template_id`.
317
+ - Multipart upload helpers (`loadSource` / `validateUpload` / `buildUploadForm`)
318
+ were extracted into `src/resources/upload.ts` and shared by document and
319
+ template uploads (DRY).
320
+ - `scripts/live-smoke.ts` honors `ASSINAFY_BASE_URL` (so it can target the
321
+ sandbox) and now exercises the template lifecycle in `--upload` mode.
322
+
323
+ ### Tooling
324
+
325
+ - ESLint upgraded to v9 (flat config, `eslint.config.mjs`) with
326
+ `typescript-eslint` v8.
327
+ - CI/release workflows hardened: least-privilege `permissions`, `concurrency`
328
+ cancellation, `oven-sh/setup-bun@v2`, `--frozen-lockfile` installs, Node 22
329
+ for publishing, and npm provenance (`--provenance` + `id-token: write`).
330
+ - esbuild pinned via `overrides` to keep the bun + npm lockfiles reproducible.
331
+
332
+ ### Tests
333
+
334
+ 113 unit tests pass (`bun test`). New suites cover `TemplateResource` (incl. the
335
+ new CRUD), the `BaseResource` helpers (`callOptional` 404→null, `callVoid`,
336
+ `callBinary`, `callList`), the rate-limit retry helpers, and assignment/document
337
+ response shapes. All read and write paths re-verified against the live sandbox,
338
+ including template create/get/update/downloadPage/delete.
339
+
340
+ ## [1.4.0] - 2026-05-27
341
+
342
+ Full file-by-file audit against [the live API docs](https://api.assinafy.com.br/v1/docs),
343
+ re-validated end-to-end against the live API. Closes the last coverage gap (Tags)
344
+ and fixes signer-creation and type accuracy.
345
+
346
+ ### Added
347
+
348
+ - **`TagResource`** (new — `client.tags`): `list` (with `search`), `create`,
349
+ `update` (rename / recolor, `color: null` clears), and `delete`
350
+ (`{ force: true }` detaches everywhere first). Covers
351
+ `GET/POST/PUT/DELETE /accounts/{id}/tags`.
352
+ - **`DocumentResource` tag methods**: `listTags`, `replaceTags`, `addTags`,
353
+ `detachTag` — the `GET/PUT/POST /accounts/{id}/documents/{id}/tags` and
354
+ `DELETE /accounts/{id}/documents/{id}/tags/{tag_id}` endpoints.
355
+ - **Sequential signing**: `step` is now accepted on assignment signer objects
356
+ (`assignments.create` / `estimateCost`) and on template signers
357
+ (`documents.createFromTemplate`).
358
+ - `documents.createFromTemplate` options now accept `tags` (tag names attached
359
+ to the created document).
360
+ - New types: `ITag`, `IInlineTag`, `ICreateTagPayload`, `IUpdateTagPayload`, and
361
+ `IDocumentListParams` (typed `status` / `method` / `tags` filters).
362
+
363
+ ### Changed
364
+
365
+ - **Signer `email` is now optional.** The API accepts WhatsApp-only signers, so
366
+ `signers.create` requires *at least one* of `email` / `whatsapp_phone_number`
367
+ (or the `phone` alias). The idempotent-by-email reuse only runs when an email
368
+ is supplied; WhatsApp-only signers are always created fresh. `ISigner.email`
369
+ is now `string | null`.
370
+ - `assignments.resetExpiration` accepts `string | null` — passing `null` clears
371
+ the expiration (previously the value was silently dropped).
372
+ - Document/template types now expose the `tags` (and template
373
+ `default_document_tags`) arrays returned by the API; `IDocumentActivity.origin`
374
+ is typed as the `{ ip, user-agent }` object the API actually returns, with the
375
+ event `payload` snapshot added.
376
+
377
+ ### Tests
378
+
379
+ 86 unit tests pass (`bun test`). New `tags` and `documents` suites cover Tag CRUD
380
+ and document-tag attach/detach; new signer tests cover WhatsApp-only creation and
381
+ CPF normalisation. All read and write paths re-verified against the live API
382
+ (`scripts/live-smoke.ts --write`).
383
+
384
+ ## [1.3.0] - 2026-05-12
385
+
386
+ 100% endpoint coverage of [the live API docs](https://api.assinafy.com.br/v1/docs).
387
+ Audited file-by-file and validated end-to-end against the live API.
388
+
389
+ ### Added
390
+
391
+ - **`AuthenticationResource`** (new — `client.auth`): `login`, `socialLogin`,
392
+ `createApiKey`, `getApiKey`, `deleteApiKey`, `changePassword`,
393
+ `requestPasswordReset`, `resetPassword`.
394
+ - **`FieldsResource`** (new — `client.fields`): full CRUD for field definitions,
395
+ plus `validate`, `validateMultiple`, and `listTypes`.
396
+ - **`SignerDocumentsResource`** (new — `client.signerDocuments`) for signer-side
397
+ flows authenticated by `signer-access-code`: `self`, `acceptTerms`,
398
+ `verifyEmail`, `confirmData`, `getCurrent`, `list`, `download`, `signMultiple`,
399
+ `declineMultiple`, `uploadSignature`, `downloadSignature`, `getAssignment`,
400
+ `sign`, `decline`.
401
+ - **`DocumentResource`**: `statuses`, `getPublic`, `sendToken` (the
402
+ `/documents/statuses`, `/public/documents/{id}`, and `/public/documents/{id}/send-token`
403
+ endpoints).
404
+ - **`AssignmentResource`**: `listWhatsAppNotifications`
405
+ (`GET /documents/{id}/assignments/{id}/whatsapp-notifications`).
406
+ - **`TemplateResource`**: `downloadPage`
407
+ (`GET /accounts/{id}/templates/{id}/pages/{page_id}/download`).
408
+ - New types: `IDocumentStatusInfo`, `IPublicDocumentInfo`, `SendTokenChannel`,
409
+ `ILoginResponse`, `IApiKeyResponse`, `IMaskedApiKeyResponse`,
410
+ `IFieldDefinition`, `ICreateFieldPayload`, `IUpdateFieldPayload`,
411
+ `IFieldType`, `IFieldValidationResult`, `IFieldValidateMultipleEntry`,
412
+ `IWhatsAppNotification`, `ISignFieldEntry`. Added `has_signature`,
413
+ `has_initial`, and `resource` fields to `ISigner`.
414
+ - `ClientConfigInput` and `buildAssignmentPayload` are now re-exported from
415
+ the package entry point for advanced use cases.
416
+ - Live smoke-test script (`scripts/live-smoke.ts`) covering every read-only
417
+ endpoint plus optional `--write` and `--upload` modes.
418
+
419
+ ### Tests
420
+
421
+ 70 unit tests pass (`bun test`). New suites cover the authentication, fields,
422
+ and signer-documents resources. Build + ESM/CJS bundles validated against the
423
+ live API.
424
+
425
+ ## [1.2.0] - 2026-05-06
426
+
427
+ Full API parity audit. Adds the Template resource and missing Document operations, and aligns signer
428
+ fields (`cpf`, `whatsapp_phone_number`) with the PHP SDK and n8n node.
429
+
430
+ ### Added
431
+
432
+ - **`TemplateResource`** (new class exposed as `client.templates`):
433
+ - `list(params?, accountId?)` — `GET /accounts/{accountId}/templates`
434
+ - `get(templateId, accountId?)` — `GET /accounts/{accountId}/templates/{templateId}`
435
+ - **`DocumentResource`**:
436
+ - `createFromTemplate(templateId, signers, options?, accountId?)` — `POST /accounts/{accountId}/templates/{templateId}/documents`
437
+ - `estimateCostFromTemplate(templateId, signers, accountId?)` — `POST /accounts/{accountId}/templates/{templateId}/documents/estimate-cost`
438
+ - `verify(hash)` — `GET /documents/{hash}/verify`
439
+ - **`cpf` field** in `ICreateSignerPayload`, `IUpdateSignerPayload`, `ISigner`, and `IUploadAndRequestSignaturesSigner`. The `normaliseSignerPayload` helper strips non-digit characters before sending (mirrors PHP SDK `sanitizeDocument` behaviour).
440
+ - New types: `ITemplateListItem`, `ITemplateListResponse`, `ITemplateDetailsResponse`, `ITemplateRole`, `ITemplateSigner`, `ICreateDocumentFromTemplateOptions`.
441
+ - `TemplateResource` exported from `index.ts`.
442
+
443
+ ## [1.1.1] - 2026-04-28
444
+
445
+ ### Changed
446
+
447
+ - Renamed package to `@assinafy/sdk` and configured dual-publish to npmjs.com and GitHub Packages.
448
+
449
+ ## [1.1.0] - 2026-04-25
450
+
451
+ ### Added
452
+
453
+ - `AssignmentResource.estimateCost`, `resendNotification`, `estimateResendCost`, `resetExpiration`, `cancel`.
454
+ - `DocumentResource.thumbnail`, `downloadPage`, `activities`, `isFullySigned`, `getSigningProgress`, `waitUntilReady`.
455
+ - `WorkspaceResource.update`, `delete`.
456
+ - `WebhookResource.inactivate`, `listEventTypes`, `listDispatches`, `retryDispatch`.
457
+ - High-level `uploadAndRequestSignatures` helper on `AssinafyClient`.
458
+ - `PaginatedResult<T>` with parsed `X-Pagination-*` header meta.
459
+
460
+ [Unreleased]: https://github.com/assinafy/typescript-sdk/compare/v2.1.1...HEAD
461
+ [2.1.1]: https://github.com/assinafy/typescript-sdk/compare/v2.1.0...v2.1.1
462
+ [2.1.0]: https://github.com/assinafy/typescript-sdk/compare/v2.0.0...v2.1.0
463
+ [2.0.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v2.0.0
464
+ [1.5.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.5.0
465
+ [1.4.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.4.0
466
+ [1.3.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.3.0
467
+ [1.2.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.2.0
468
+ [1.1.1]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.1.1
469
+ [1.1.0]: https://github.com/assinafy/typescript-sdk/releases/tag/v1.1.0