Пространства
Пространства — единственное место, где разделение версий по-настоящему неудобно: v2 их читает, v1 их пишет. Atlassian убрал getSpace/getSpaces из спеки v1 и не добавил create/update/delete в v2, поэтому жизненный цикл проходит через обе версии.
import { createV1Client, createV2Client } from 'confluence.js';
const host = 'https://your-domain.atlassian.net';
const v2 = createV2Client({ host, auth });
const v1 = createV1Client({ host, auth });Чтение — v2
const spaces = await v2.space.getSpaces({ limit: 25 });
for (const space of spaces.results ?? []) {
console.log(`${space.key} — ${space.name}`);
}
const space = await v2.space.getSpaceById({ id: 123456 });Создание — v1
Обратите внимание на форму: v1 принимает поля плоско, без обёртки body.
const created = await v1.space.createSpace({
key: 'DOCS',
name: 'Документация',
description: { plain: { value: 'Документация по продукту', representation: 'plain' } },
});
console.log(created.id, created.key);Личное, приватное пространство:
await v1.space.createPrivateSpace({ key: 'MYNOTES', name: 'Мои заметки' });Обновление — v1
await v1.space.updateSpace({ spaceKey: 'DOCS', name: 'Документация по продукту' });Удаление — v1, и это задача
const task = await v1.space.deleteSpace({ spaceKey: 'DOCS' });WARNING
Удаление пространства не происходит на месте. Вызов возвращает долгую задачу, как только работа поставлена в очередь: когда промис зарезолвился, пространство ещё на месте. Если нужно знать, когда оно действительно исчезло, опрашивайте longRunningTask.getTask({ id: task.id }).
Свойства пространства
Произвольный JSON, прикреплённый к пространству. Здесь v2 закрывает всё:
await v2.spaceProperties.createSpaceProperty({
spaceId: 123456,
body: { key: 'team.owner', value: { squad: 'platform', slack: '#platform' } },
});
const props = await v2.spaceProperties.getSpaceProperties({ spaceId: 123456 });
const one = await v2.spaceProperties.getSpacePropertyById({ spaceId: 123456, propertyId: 789 });Значения возвращаются как есть — объекты, массивы, строки и числа приходят в той же форме, в какой вы их положили.
Права
Чтение — v2:
const permissions = await v2.spacePermissions.getSpacePermissionsAssignments({ id: 123456, limit: 100 });Запись — v1, но только на сайте с классическими правами пространств:
await v1.spacePermissions.addPermissionToSpace({
spaceKey: 'DOCS',
subject: { type: 'group', identifier: groupId },
operation: { key: 'read', target: 'space' },
});Сайты в roles-only режиме отвергают это целиком
Сайт в режиме roles-only (RBAC) отвечает на любую классическую запись прав ошибкой 400 InvalidRbacOperationException: Space permission updates that are not from RBAC are not supported in roles-only mode. Это не проблема доступа, и никакого флага передать нельзя: такой сайт управляет доступом через роли пространств в v2:
const roles = await v2.spaceRoles.getSpaceRoles({ spaceId: 123456 });
const assignments = await v2.spaceRoles.getRoleAssignments({ id: 123456 });Ещё две вещи, на которых настаивает живой API, если вы всё же на сайте с классическими правами:
read space— предусловие. Выдача любого другого права субъекту без него падает с 400 и прямо об этом сообщает.- Создатель пространства уже имеет на нём все права. Повторная выдача — это
400 Permission already exists, а не тихий no-op.
Метки и настройки пространства
И то и другое — только v1:
await v1.experimental.addLabelsToSpace({ spaceKey: 'DOCS', body: [{ prefix: 'global', name: 'product' }] });
const labels = await v1.experimental.getLabelsForSpace({ spaceKey: 'DOCS' });
const settings = await v1.spaceSettings.getSpaceSettings({ spaceKey: 'DOCS' });
const theme = await v1.themes.getSpaceTheme({ spaceKey: 'DOCS' }); // 404, если у пространства тема сайтаexperimental — это собственное название неймспейса у Atlassian: такие эндпоинты могут меняться без предупреждения.