@headless-lms/core 0.5.0 → 0.6.0

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.
Files changed (72) hide show
  1. package/dist/assets/events.d.ts +18 -18
  2. package/dist/assets/file-urls.d.ts +3 -0
  3. package/dist/assets/file-urls.js +1 -0
  4. package/dist/assets/file-urls.js.map +1 -1
  5. package/dist/assets/index.js +1 -1
  6. package/dist/assets/ports.d.ts +1 -1
  7. package/dist/assets/service.d.ts +1 -1
  8. package/dist/assets/service.js +28 -23
  9. package/dist/assets/service.js.map +1 -1
  10. package/dist/automations/catalog.js +1 -1
  11. package/dist/automations/notifications/processor.js +2 -2
  12. package/dist/automations/notifications/service.js +1 -1
  13. package/dist/automations/service.js +1 -1
  14. package/dist/content/events.d.ts +84 -48
  15. package/dist/content/index.d.ts +2 -2
  16. package/dist/content/model.d.ts +2 -2
  17. package/dist/content/notification-categories.js +1 -1
  18. package/dist/content/ports.d.ts +11 -11
  19. package/dist/content/service.d.ts +16 -12
  20. package/dist/content/service.js +62 -16
  21. package/dist/content/service.js.map +1 -1
  22. package/dist/discussion/chats.js +2 -2
  23. package/dist/discussion/events.d.ts +8 -8
  24. package/dist/discussion/posts.d.ts +1 -1
  25. package/dist/discussion/posts.js +3 -3
  26. package/dist/discussion/posts.js.map +1 -1
  27. package/dist/discussion/service.js +2 -2
  28. package/dist/discussion/subscriptions.js +1 -1
  29. package/dist/entitlements/events.d.ts +48 -48
  30. package/dist/entitlements/service.js +1 -1
  31. package/dist/identity/devices.js +1 -1
  32. package/dist/identity/events.d.ts +2 -2
  33. package/dist/identity/notification-settings.js +1 -1
  34. package/dist/identity/service.d.ts +1 -1
  35. package/dist/identity/service.js +3 -3
  36. package/dist/identity/service.js.map +1 -1
  37. package/dist/integrations/service.js +2 -2
  38. package/dist/organizations/effective-permissions.d.ts +3 -1
  39. package/dist/organizations/effective-permissions.js +8 -3
  40. package/dist/organizations/effective-permissions.js.map +1 -1
  41. package/dist/organizations/events.d.ts +29 -23
  42. package/dist/organizations/index.d.ts +2 -2
  43. package/dist/organizations/model.d.ts +2 -2
  44. package/dist/organizations/notification-categories.js +1 -1
  45. package/dist/organizations/ports.d.ts +6 -3
  46. package/dist/organizations/service.d.ts +1 -1
  47. package/dist/organizations/service.js +17 -7
  48. package/dist/organizations/service.js.map +1 -1
  49. package/dist/organizations/testing.js +1 -1
  50. package/dist/organizations/testing.js.map +1 -1
  51. package/dist/progress/service.js +2 -2
  52. package/dist/reporting/member/model.d.ts +3 -0
  53. package/dist/reporting/member/ports.d.ts +2 -1
  54. package/dist/reporting/member/service.d.ts +2 -1
  55. package/dist/reporting/member/service.js +17 -1
  56. package/dist/reporting/member/service.js.map +1 -1
  57. package/dist/shared/actor.d.ts +1 -0
  58. package/dist/types/content.d.ts +2 -2
  59. package/dist/types/index.d.ts +3 -3
  60. package/dist/types/organizations.d.ts +2 -2
  61. package/dist/types/schemas/content.d.ts +68 -6
  62. package/dist/types/schemas/content.js +19 -2
  63. package/dist/types/schemas/content.js.map +1 -1
  64. package/dist/types/schemas/discussion.d.ts +14 -14
  65. package/dist/types/schemas/entitlements.d.ts +8 -8
  66. package/dist/types/schemas/index.d.ts +3 -3
  67. package/dist/types/schemas/index.js +3 -3
  68. package/dist/types/schemas/notifications.d.ts +4 -4
  69. package/dist/types/schemas/organizations.d.ts +4 -1
  70. package/dist/types/schemas/organizations.js +3 -1
  71. package/dist/types/schemas/organizations.js.map +1 -1
  72. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { spaceSettingsDefaults } from "../types/schemas/content.js";
2
- import { noopLogger } from "../shared/logger.js";
3
2
  import { ConflictError, ForbiddenError, InvalidInputError, NotFoundError } from "../shared/errors.js";
3
+ import { noopLogger } from "../shared/logger.js";
4
4
  import { contentEvents } from "./events.js";
5
5
  import { EVENT_LEADS, EVENT_STARTING_SOON_JOB } from "./jobs.js";
6
6
  import { isDeepStrictEqual } from "node:util";
@@ -36,6 +36,13 @@ const EVENT_LEAD_KEYS = Object.keys(EVENT_LEADS);
36
36
  function shownPublicly(item) {
37
37
  return item.status === "published" || item.type === "event" && item.status === "canceled";
38
38
  }
39
+ function spaceImageIds(space) {
40
+ return [
41
+ space.coverAssetId,
42
+ space.backgroundAssetId,
43
+ space.iconAssetId
44
+ ].filter((id) => id !== null);
45
+ }
39
46
  function sameIdSet(current, requested) {
40
47
  if (current.length !== requested.length) return false;
41
48
  const have = new Set(current);
@@ -93,10 +100,28 @@ var ContentService = class {
93
100
  };
94
101
  }
95
102
  syncThumbnail(item) {
96
- return this.files.syncPublicImage(item.orgId, item.id, shownPublicly(item) ? item.thumbnailAssetId : null);
103
+ return this.files.syncPublicImages(item.orgId, item.id, shownPublicly(item) && item.thumbnailAssetId ? [item.thumbnailAssetId] : []);
97
104
  }
98
105
  withdrawThumbnail(orgId, id) {
99
- return this.files.syncPublicImage(orgId, id, null);
106
+ return this.files.syncPublicImages(orgId, id, []);
107
+ }
108
+ spaceView(space, published) {
109
+ const url = (image, assetId) => !assetId ? null : published ? this.fileUrls.publicImage(space.orgId, space.id, assetId) : this.fileUrls.spaceImage(space.id, image);
110
+ return {
111
+ ...space,
112
+ coverUrl: url("cover", space.coverAssetId),
113
+ backgroundUrl: url("background", space.backgroundAssetId),
114
+ iconUrl: url("icon", space.iconAssetId)
115
+ };
116
+ }
117
+ async communityPublished(orgId, communityId) {
118
+ return (await this.repo.findCommunityById(orgId, communityId))?.status === "published";
119
+ }
120
+ async oneSpaceView(space) {
121
+ return this.spaceView(space, await this.communityPublished(space.orgId, space.communityId));
122
+ }
123
+ syncSpaceImages(space, published) {
124
+ return this.files.syncPublicImages(space.orgId, space.id, published ? spaceImageIds(space) : []);
100
125
  }
101
126
  pageWithThumbnails(page) {
102
127
  return {
@@ -1230,19 +1255,21 @@ var ContentService = class {
1230
1255
  }
1231
1256
  async getSpace(spaceId, actor) {
1232
1257
  const space = await this.repo.findSpace(actor.orgId, spaceId);
1233
- if (space) this.require(actor, "communities:read", space.communityId);
1234
- return space;
1258
+ if (!space) return null;
1259
+ this.require(actor, "communities:read", space.communityId);
1260
+ return this.oneSpaceView(space);
1235
1261
  }
1236
1262
  async getCommunitySpace(communityId, spaceId, actor) {
1237
1263
  this.require(actor, "communities:read", communityId);
1238
1264
  const space = await this.repo.findSpace(actor.orgId, spaceId);
1239
1265
  if (space?.communityId !== communityId) throw new NotFoundError("Space", spaceId);
1240
- return space;
1266
+ return this.oneSpaceView(space);
1241
1267
  }
1242
1268
  async listSpaces(communityId, actor) {
1243
1269
  this.requireAny(actor, COMMUNITY_READERS, communityId);
1244
- if (!await this.repo.findCommunityById(actor.orgId, communityId)) throw new NotFoundError("Community", communityId);
1245
- return this.repo.listSpaces(actor.orgId, communityId);
1270
+ const community = await this.repo.findCommunityById(actor.orgId, communityId);
1271
+ if (!community) throw new NotFoundError("Community", communityId);
1272
+ return (await this.repo.listSpaces(actor.orgId, communityId)).map((space) => this.spaceView(space, community.status === "published"));
1246
1273
  }
1247
1274
  async getDmSettings(communityId, actor) {
1248
1275
  this.require(actor, "communities:read", communityId);
@@ -1294,6 +1321,10 @@ var ContentService = class {
1294
1321
  actorId: actor.id
1295
1322
  });
1296
1323
  await this.syncThumbnail(community);
1324
+ if (patch.status !== void 0) {
1325
+ const spaces = await this.repo.listSpaces(orgId, id);
1326
+ await Promise.all(spaces.map((space) => this.syncSpaceImages(space, community.status === "published")));
1327
+ }
1297
1328
  return this.withThumbnail(community);
1298
1329
  }
1299
1330
  publishCommunity(id, actor) {
@@ -1305,7 +1336,7 @@ var ContentService = class {
1305
1336
  async deleteCommunity(id, actor) {
1306
1337
  this.require(actor, "communities:delete", id);
1307
1338
  const orgId = actor.orgId;
1308
- await this.uow.run(async ({ content, outbox }) => {
1339
+ const spaceIds = await this.uow.run(async ({ content, outbox }) => {
1309
1340
  const community = await content.findCommunityById(orgId, id);
1310
1341
  if (!community) {
1311
1342
  this.logger.warn("community delete rejected — not found", {
@@ -1316,6 +1347,7 @@ var ContentService = class {
1316
1347
  throw new NotFoundError("Community", id);
1317
1348
  }
1318
1349
  const linked = await content.spacesLinkingContent(orgId, id);
1350
+ const own = await content.listSpaces(orgId, id);
1319
1351
  if (!await content.deleteCommunity(orgId, id)) throw new NotFoundError("Community", id);
1320
1352
  await content.deleteCommunitySettings(orgId, id);
1321
1353
  await outbox.append([contentEvents.communityDeleted.make({
@@ -1323,6 +1355,7 @@ var ContentService = class {
1323
1355
  data: community,
1324
1356
  metadata: actorMetadata(actor)
1325
1357
  }), ...await this.spaceUpdates(content, orgId, linked, actor)]);
1358
+ return own.map((space) => space.id);
1326
1359
  });
1327
1360
  this.logger.info("community deleted", {
1328
1361
  orgId,
@@ -1330,6 +1363,7 @@ var ContentService = class {
1330
1363
  actorId: actor.id
1331
1364
  });
1332
1365
  await this.withdrawThumbnail(orgId, id);
1366
+ await Promise.all(spaceIds.map((spaceId) => this.files.syncPublicImages(orgId, spaceId, [])));
1333
1367
  }
1334
1368
  async patchCommunitySettings(id, patch, actor) {
1335
1369
  this.require(actor, "communities:write", id);
@@ -1390,11 +1424,19 @@ var ContentService = class {
1390
1424
  spaceId: space.id,
1391
1425
  actorId: actor.id
1392
1426
  });
1393
- return space;
1427
+ return this.oneSpaceView(space);
1394
1428
  }
1395
1429
  async updateSpace(communityId, spaceId, patch, actor) {
1396
1430
  this.require(actor, "communities:write", communityId);
1397
1431
  const orgId = actor.orgId;
1432
+ await this.assertAttachable(actor, communityId, [
1433
+ patch.coverAssetId,
1434
+ patch.backgroundAssetId,
1435
+ patch.iconAssetId
1436
+ ], async () => {
1437
+ const current = await this.repo.findSpace(orgId, spaceId);
1438
+ return current ? spaceImageIds(current) : [];
1439
+ }, "A space");
1398
1440
  const space = await this.uow.run(async ({ content, outbox }) => {
1399
1441
  const current = await content.findSpace(orgId, spaceId);
1400
1442
  if (!current || current.communityId !== communityId) {
@@ -1427,7 +1469,9 @@ var ContentService = class {
1427
1469
  spaceId,
1428
1470
  actorId: actor.id
1429
1471
  });
1430
- return space;
1472
+ const published = await this.communityPublished(orgId, communityId);
1473
+ await this.syncSpaceImages(space, published);
1474
+ return this.spaceView(space, published);
1431
1475
  }
1432
1476
  async deleteSpace(communityId, spaceId, actor) {
1433
1477
  this.require(actor, "communities:write", communityId);
@@ -1456,6 +1500,7 @@ var ContentService = class {
1456
1500
  spaceId,
1457
1501
  actorId: actor.id
1458
1502
  });
1503
+ await this.files.syncPublicImages(orgId, spaceId, []);
1459
1504
  }
1460
1505
  async reorderSpaces(communityId, orderedIds, actor) {
1461
1506
  this.require(actor, "communities:write", communityId);
@@ -1483,7 +1528,8 @@ var ContentService = class {
1483
1528
  communityId,
1484
1529
  actorId: actor.id
1485
1530
  });
1486
- return spaces;
1531
+ const published = await this.communityPublished(orgId, communityId);
1532
+ return spaces.map((space) => this.spaceView(space, published));
1487
1533
  }
1488
1534
  async setSpaceTopics(communityId, spaceId, input, actor) {
1489
1535
  this.require(actor, "communities:write", communityId);
@@ -1520,7 +1566,7 @@ var ContentService = class {
1520
1566
  spaceId,
1521
1567
  actorId: actor.id
1522
1568
  });
1523
- return space;
1569
+ return this.oneSpaceView(space);
1524
1570
  }
1525
1571
  async addSpaceLink(communityId, spaceId, contentId, actor) {
1526
1572
  this.require(actor, "communities:write", communityId);
@@ -1552,7 +1598,7 @@ var ContentService = class {
1552
1598
  contentId,
1553
1599
  actorId: actor.id
1554
1600
  });
1555
- return space;
1601
+ return this.oneSpaceView(space);
1556
1602
  }
1557
1603
  async removeSpaceLink(communityId, spaceId, linkId, actor) {
1558
1604
  this.require(actor, "communities:write", communityId);
@@ -1583,7 +1629,7 @@ var ContentService = class {
1583
1629
  linkId,
1584
1630
  actorId: actor.id
1585
1631
  });
1586
- return space;
1632
+ return this.oneSpaceView(space);
1587
1633
  }
1588
1634
  async reorderSpaceLinks(communityId, spaceId, orderedIds, actor) {
1589
1635
  this.require(actor, "communities:write", communityId);
@@ -1614,7 +1660,7 @@ var ContentService = class {
1614
1660
  spaceId,
1615
1661
  actorId: actor.id
1616
1662
  });
1617
- return space;
1663
+ return this.oneSpaceView(space);
1618
1664
  }
1619
1665
  };
1620
1666
  //#endregion