v3.0.0
Major Changes
-
f219aa3: confluence.js 3.0 — both Confluence Cloud APIs from one package.
The library now covers Cloud REST v2 (30 namespaces, 218 methods) alongside
v1 (28 namespaces, 130 methods). Both are first-class: Atlassian has not
deprecated v1, and the two cover different ground. Onehostand one client
serve both — the API path belongs to the request, not to your config.Runtime dependencies are down to
zodalone. axios, form-data, oauth and
atlassian-jwt are gone with the old transport, which is now the built-infetch.
Every response is validated against a Zod 4 schema, so API drift raises a
SchemaMismatchErrorinstead of surfacing asundefinedlater on.import { createV2Client } from 'confluence.js'; const confluence = createV2Client({ host: 'https://your-domain.atlassian.net', auth: { type: 'basic', email, apiToken }, }); await confluence.page.getPages({ spaceId: ['123'] });
Or import just what you call — the package is ESM-only and tree-shakable, with
entry points atconfluence.js/v1,confluence.js/v2andconfluence.js/core.OAuth 2.0 (3LO) is a first-class strategy. Hand over your app credentials and
a refresh token, and the client refreshes before expiry, retries once on a401,
resolves the cloud id, and routes through the Atlassian gateway — where 3LO tokens
are actually accepted:const confluence = createV2Client({ auth: { type: 'oauth2', clientId, clientSecret, refreshToken, onTokenRefresh: ({ refreshToken }) => tokenStore.save(refreshToken), }, });
The flow itself is covered too, so no separate OAuth library is needed:
generateAuthorizationUrl,parseCallbackUrl,exchangeAuthorizationCode,
refreshOAuth2TokenandgetAccessibleResources.Both version factories accept an existing client, so v1 and v2 can share one
OAuth token — building one each would make the first refresh invalidate the
other's rotating refresh token:const client = createClient({ auth: { type: 'oauth2', … } }); const v1 = createV1Client(client); const v2 = createV2Client(client);
Node and the browser, from one build. There is no separate web build: the code
branches on what the runtime supports rather than on which runtime it is. It loads
from a dependency-resolving CDN as published, and a self-containeddist/browser.js
with zod inlined covers plain file hosts and<script type="module">:<script type="module"> import { createV2Client } from 'https://esm.sh/confluence.js'; </script>
Attachments accept the same values everywhere — a
File,Blob,Uint8Array,
string, stream, and still Node'sBufferandReadable, which are aUint8Array
and anAsyncIterablerespectively. They are no longer named inAttachmentContent,
so the shipped declarations compile in a project without@types/node. Where a
browser cannot send a request body as a stream, the stream is read into aBlob
rather than failing. See the browser guide.Every failure has a type. Non-2xx responses throw an
ApiErrorsubclass —
AuthError,ForbiddenError,NotFoundError,RateLimitError(with
retryAfterMsparsed fromRetry-After),ServerError. Transport faults throw
NetworkErrorinstead of leaking a rawfetchTypeError, and OAuth failures
throwOAuthError. A 2xx whose body does not match the schema throws
SchemaMismatchError, carrying the rawbodyand, when the shape drifted, the
underlyingZodErroroncause. Each ships anisXxxpredicate that checks a branded marker
rather than the prototype chain, so narrowing survives two copies of the package
in onenode_modules:import { isNotFoundError, isRateLimitError } from 'confluence.js'; if (isNotFoundError(error)) return null; if (isRateLimitError(error)) await sleep(error.retryAfterMs ?? 60_000);
Breaking changes
new ConfluenceClient({…})→createV1Client({…})/createV2Client({…})authentication: { basic: {…} }→auth: { type: 'basic', … };oauth2→auth: { type: 'oauth2', … }- JWT (Atlassian Connect) authentication is not supported — Connect apps should stay on
confluence.js@2 - Callbacks,
middlewares,apiPrefixandbaseRequestConfigare removed noCheckAtlassianTokenis removed with nothing to replace it: v1 enforces XSRF
on every write, so every v1 write now sendsX-Atlassian-Token: no-checkitselfBaseClientand the per-namespace classes are gone, as are deep imports likeconfluence.js/api/content- Errors are
ApiErrorand its subclasses (status,statusText,body) rather
thanAxiosError; transport faults areNetworkError, OAuth failures areOAuthError AttachmentContentno longer namesBufferorReadable. Both still work — the
type describes them structurally — but a declaration that required@types/node
broke every browser consumercreateMultipartRequestBodyreturns aPromise: collecting a stream for a runtime
that cannot send one is asynchronous- The v1 surface follows Atlassian's current spec, which has dropped 37 operations
(getContent,createContent,getSpace, …) since 2.x shipped — each is mapped
to its v2 equivalent in the migration guide
See MIGRATION.md;
a codemod handles the mechanical parts.