@headless-lms/core 0.7.0 → 0.8.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 (35) hide show
  1. package/dist/assets/file-urls.d.ts +5 -19
  2. package/dist/assets/file-urls.js +2 -23
  3. package/dist/assets/file-urls.js.map +1 -1
  4. package/dist/assets/index.d.ts +3 -3
  5. package/dist/assets/ports.d.ts +9 -10
  6. package/dist/assets/service.d.ts +10 -13
  7. package/dist/assets/service.js +41 -62
  8. package/dist/assets/service.js.map +1 -1
  9. package/dist/content/events.d.ts +13 -13
  10. package/dist/content/service.d.ts +4 -1
  11. package/dist/content/service.js +52 -29
  12. package/dist/content/service.js.map +1 -1
  13. package/dist/discussion/chats.d.ts +1 -2
  14. package/dist/discussion/chats.js +8 -17
  15. package/dist/discussion/chats.js.map +1 -1
  16. package/dist/discussion/ports.d.ts +0 -6
  17. package/dist/discussion/ports.js.map +1 -1
  18. package/dist/discussion/posts.d.ts +1 -4
  19. package/dist/discussion/posts.js +8 -21
  20. package/dist/discussion/posts.js.map +1 -1
  21. package/dist/entitlements/events.d.ts +33 -33
  22. package/dist/identity/events.d.ts +2 -2
  23. package/dist/integrations/events.d.ts +3 -3
  24. package/dist/organizations/events.d.ts +2 -2
  25. package/dist/reporting/member/ports.d.ts +1 -10
  26. package/dist/reporting/member/service.d.ts +2 -11
  27. package/dist/reporting/member/service.js +12 -62
  28. package/dist/reporting/member/service.js.map +1 -1
  29. package/dist/types/ports.d.ts +4 -2
  30. package/dist/types/ports.js.map +1 -1
  31. package/dist/types/schemas/content.d.ts +4 -4
  32. package/dist/types/schemas/discussion.d.ts +14 -14
  33. package/dist/types/schemas/entitlements.d.ts +8 -8
  34. package/dist/types/schemas/notifications.d.ts +3 -3
  35. package/package.json +1 -1
@@ -58,7 +58,6 @@ declare const contentEvents: {
58
58
  updatedAt: z.ZodCoercedDate<unknown>;
59
59
  title: z.ZodString;
60
60
  description: z.ZodString;
61
- category: z.ZodString;
62
61
  settings: z.ZodObject<{
63
62
  transcriptDownloads: z.ZodBoolean;
64
63
  comments: z.ZodOptional<z.ZodObject<{
@@ -69,6 +68,7 @@ declare const contentEvents: {
69
68
  }, z.core.$strict>>;
70
69
  }, z.core.$strict>;
71
70
  slug: z.ZodString;
71
+ category: z.ZodString;
72
72
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
73
73
  }, z.core.$strip>>;
74
74
  courseUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -125,7 +125,6 @@ declare const contentEvents: {
125
125
  updatedAt: z.ZodCoercedDate<unknown>;
126
126
  title: z.ZodString;
127
127
  description: z.ZodString;
128
- category: z.ZodString;
129
128
  settings: z.ZodObject<{
130
129
  transcriptDownloads: z.ZodBoolean;
131
130
  comments: z.ZodOptional<z.ZodObject<{
@@ -136,6 +135,7 @@ declare const contentEvents: {
136
135
  }, z.core.$strict>>;
137
136
  }, z.core.$strict>;
138
137
  slug: z.ZodString;
138
+ category: z.ZodString;
139
139
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
140
140
  }, z.core.$strip>>;
141
141
  courseDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -192,7 +192,6 @@ declare const contentEvents: {
192
192
  updatedAt: z.ZodCoercedDate<unknown>;
193
193
  title: z.ZodString;
194
194
  description: z.ZodString;
195
- category: z.ZodString;
196
195
  settings: z.ZodObject<{
197
196
  transcriptDownloads: z.ZodBoolean;
198
197
  comments: z.ZodOptional<z.ZodObject<{
@@ -203,6 +202,7 @@ declare const contentEvents: {
203
202
  }, z.core.$strict>>;
204
203
  }, z.core.$strict>;
205
204
  slug: z.ZodString;
205
+ category: z.ZodString;
206
206
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
207
207
  }, z.core.$strip>>;
208
208
  moduleCreated: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -328,9 +328,9 @@ declare const contentEvents: {
328
328
  id: z.ZodString;
329
329
  createdAt: z.ZodCoercedDate<unknown>;
330
330
  updatedAt: z.ZodCoercedDate<unknown>;
331
- moduleId: z.ZodString;
332
331
  courseId: z.ZodString;
333
332
  seq: z.ZodNumber;
333
+ moduleId: z.ZodString;
334
334
  }, z.core.$strip>>;
335
335
  activityUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
336
336
  orgId: string;
@@ -355,9 +355,9 @@ declare const contentEvents: {
355
355
  id: z.ZodString;
356
356
  createdAt: z.ZodCoercedDate<unknown>;
357
357
  updatedAt: z.ZodCoercedDate<unknown>;
358
- moduleId: z.ZodString;
359
358
  courseId: z.ZodString;
360
359
  seq: z.ZodNumber;
360
+ moduleId: z.ZodString;
361
361
  }, z.core.$strip>>;
362
362
  activityDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
363
363
  orgId: string;
@@ -382,9 +382,9 @@ declare const contentEvents: {
382
382
  id: z.ZodString;
383
383
  createdAt: z.ZodCoercedDate<unknown>;
384
384
  updatedAt: z.ZodCoercedDate<unknown>;
385
- moduleId: z.ZodString;
386
385
  courseId: z.ZodString;
387
386
  seq: z.ZodNumber;
387
+ moduleId: z.ZodString;
388
388
  }, z.core.$strip>>;
389
389
  activityPublished: RuntimeEventDefinition<VersionedDomainEvent<{
390
390
  activityId: string;
@@ -460,8 +460,8 @@ declare const contentEvents: {
460
460
  updatedAt: z.ZodCoercedDate<unknown>;
461
461
  title: z.ZodString;
462
462
  description: z.ZodString;
463
- category: z.ZodString;
464
463
  slug: z.ZodString;
464
+ category: z.ZodString;
465
465
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
466
466
  }, z.core.$strip>>;
467
467
  downloadUpdated: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -500,8 +500,8 @@ declare const contentEvents: {
500
500
  updatedAt: z.ZodCoercedDate<unknown>;
501
501
  title: z.ZodString;
502
502
  description: z.ZodString;
503
- category: z.ZodString;
504
503
  slug: z.ZodString;
504
+ category: z.ZodString;
505
505
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
506
506
  }, z.core.$strip>>;
507
507
  downloadDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -540,8 +540,8 @@ declare const contentEvents: {
540
540
  updatedAt: z.ZodCoercedDate<unknown>;
541
541
  title: z.ZodString;
542
542
  description: z.ZodString;
543
- category: z.ZodString;
544
543
  slug: z.ZodString;
544
+ category: z.ZodString;
545
545
  thumbnailAssetId: z.ZodNullable<z.ZodString>;
546
546
  }, z.core.$strip>>;
547
547
  downloadAssetAdded: RuntimeEventDefinition<VersionedDomainEvent<{
@@ -576,8 +576,8 @@ declare const contentEvents: {
576
576
  createdAt: z.ZodCoercedDate<unknown>;
577
577
  updatedAt: z.ZodCoercedDate<unknown>;
578
578
  seq: z.ZodNumber;
579
- assetId: z.ZodString;
580
579
  downloadId: z.ZodString;
580
+ assetId: z.ZodString;
581
581
  displayName: z.ZodNullable<z.ZodString>;
582
582
  }, z.core.$strip>>;
583
583
  }, z.core.$strip>>;
@@ -613,8 +613,8 @@ declare const contentEvents: {
613
613
  createdAt: z.ZodCoercedDate<unknown>;
614
614
  updatedAt: z.ZodCoercedDate<unknown>;
615
615
  seq: z.ZodNumber;
616
- assetId: z.ZodString;
617
616
  downloadId: z.ZodString;
617
+ assetId: z.ZodString;
618
618
  displayName: z.ZodNullable<z.ZodString>;
619
619
  }, z.core.$strip>>;
620
620
  }, z.core.$strip>>;
@@ -650,8 +650,8 @@ declare const contentEvents: {
650
650
  createdAt: z.ZodCoercedDate<unknown>;
651
651
  updatedAt: z.ZodCoercedDate<unknown>;
652
652
  seq: z.ZodNumber;
653
- assetId: z.ZodString;
654
653
  downloadId: z.ZodString;
654
+ assetId: z.ZodString;
655
655
  displayName: z.ZodNullable<z.ZodString>;
656
656
  }, z.core.$strip>>;
657
657
  }, z.core.$strip>>;
@@ -687,8 +687,8 @@ declare const contentEvents: {
687
687
  createdAt: z.ZodCoercedDate<unknown>;
688
688
  updatedAt: z.ZodCoercedDate<unknown>;
689
689
  seq: z.ZodNumber;
690
- assetId: z.ZodString;
691
690
  downloadId: z.ZodString;
691
+ assetId: z.ZodString;
692
692
  displayName: z.ZodNullable<z.ZodString>;
693
693
  }, z.core.$strip>>;
694
694
  }, z.core.$strip>>;
@@ -14,7 +14,7 @@ type ContentServiceParams = {
14
14
  repo: ContentRepository;
15
15
  uow: ContentUnitOfWork;
16
16
  libraryAssets: ContentAssetReader;
17
- files: Pick<AssetFiles, 'readyFiles' | 'syncPublicImages'>;
17
+ files: Pick<AssetFiles, 'readyFiles' | 'fileLinks' | 'syncPublicImages'>;
18
18
  fileUrls: FileUrls;
19
19
  scheduler: Pick<Scheduler, 'at' | 'cancel'>;
20
20
  logger?: Logger;
@@ -32,15 +32,18 @@ declare class ContentService implements CourseManagementService, DownloadablesSe
32
32
  private requireAny;
33
33
  private visibleIds;
34
34
  private withThumbnail;
35
+ private withThumbnails;
35
36
  private syncThumbnail;
36
37
  private withdrawThumbnail;
37
38
  private spaceView;
39
+ private spaceViews;
38
40
  private communityPublished;
39
41
  private oneSpaceView;
40
42
  private syncSpaceImages;
41
43
  private pageWithThumbnails;
42
44
  private downloadFiles;
43
45
  private eventFiles;
46
+ private listedFiles;
44
47
  private assertAttachable;
45
48
  private courseAssetIds;
46
49
  private downloadAssetIds;
@@ -93,11 +93,17 @@ var ContentService = class {
93
93
  }
94
94
  return ids;
95
95
  }
96
- withThumbnail(item) {
97
- return {
96
+ async withThumbnail(item) {
97
+ const [view] = await this.withThumbnails([item]);
98
+ return view;
99
+ }
100
+ async withThumbnails(items) {
101
+ const gated = items.flatMap((item) => item.thumbnailAssetId && !shownPublicly(item) ? [{ assetId: item.thumbnailAssetId }] : []);
102
+ const links = gated.length > 0 ? await this.files.fileLinks(items[0].orgId, gated) : {};
103
+ return items.map((item) => ({
98
104
  ...item,
99
- thumbnailUrl: !item.thumbnailAssetId ? null : shownPublicly(item) ? this.fileUrls.publicImage(item.orgId, item.id, item.thumbnailAssetId) : this.fileUrls.thumbnail(item.type, item.id)
100
- };
105
+ thumbnailUrl: !item.thumbnailAssetId ? null : shownPublicly(item) ? this.fileUrls.publicImage(item.orgId, item.id, item.thumbnailAssetId) : links[item.thumbnailAssetId] ?? null
106
+ }));
101
107
  }
102
108
  syncThumbnail(item) {
103
109
  return this.files.syncPublicImages(item.orgId, item.id, shownPublicly(item) && item.thumbnailAssetId ? [item.thumbnailAssetId] : []);
@@ -105,14 +111,22 @@ var ContentService = class {
105
111
  withdrawThumbnail(orgId, id) {
106
112
  return this.files.syncPublicImages(orgId, id, []);
107
113
  }
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
- };
114
+ async spaceView(space, published) {
115
+ const [view] = await this.spaceViews([space], published);
116
+ return view;
117
+ }
118
+ async spaceViews(spaces, published) {
119
+ const gated = published ? [] : spaces.flatMap((space) => spaceImageIds(space));
120
+ const links = gated.length > 0 ? await this.files.fileLinks(spaces[0].orgId, gated.map((assetId) => ({ assetId }))) : {};
121
+ return spaces.map((space) => {
122
+ const url = (assetId) => !assetId ? null : published ? this.fileUrls.publicImage(space.orgId, space.id, assetId) : links[assetId] ?? null;
123
+ return {
124
+ ...space,
125
+ coverUrl: url(space.coverAssetId),
126
+ backgroundUrl: url(space.backgroundAssetId),
127
+ iconUrl: url(space.iconAssetId)
128
+ };
129
+ });
116
130
  }
117
131
  async communityPublished(orgId, communityId) {
118
132
  return (await this.repo.findCommunityById(orgId, communityId))?.status === "published";
@@ -123,31 +137,34 @@ var ContentService = class {
123
137
  syncSpaceImages(space, published) {
124
138
  return this.files.syncPublicImages(space.orgId, space.id, published ? spaceImageIds(space) : []);
125
139
  }
126
- pageWithThumbnails(page) {
140
+ async pageWithThumbnails(page) {
127
141
  return {
128
142
  ...page,
129
- rows: page.rows.map((row) => this.withThumbnail(row))
143
+ rows: await this.withThumbnails(page.rows)
130
144
  };
131
145
  }
132
- async downloadFiles(orgId, links) {
146
+ downloadFiles(orgId, links) {
147
+ return this.listedFiles(orgId, links);
148
+ }
149
+ eventFiles(orgId, links) {
150
+ return this.listedFiles(orgId, links);
151
+ }
152
+ async listedFiles(orgId, links) {
133
153
  const ready = await this.files.readyFiles(orgId, links.map((link) => link.assetId));
134
- return links.flatMap((link) => {
154
+ const urls = await this.files.fileLinks(orgId, links.flatMap((link) => {
135
155
  const file = ready[link.assetId];
136
156
  return file ? [{
137
- ...link,
138
- ...file,
139
- url: this.fileUrls.downloadFile(link.downloadId, link.assetId)
157
+ assetId: link.assetId,
158
+ saveAs: link.displayName ?? file.filename
140
159
  }] : [];
141
- });
142
- }
143
- async eventFiles(orgId, links) {
144
- const ready = await this.files.readyFiles(orgId, links.map((link) => link.assetId));
160
+ }));
145
161
  return links.flatMap((link) => {
146
162
  const file = ready[link.assetId];
147
- return file ? [{
163
+ const url = urls[link.assetId];
164
+ return file && url ? [{
148
165
  ...link,
149
166
  ...file,
150
- url: this.fileUrls.eventFile(link.eventId, link.assetId)
167
+ url
151
168
  }] : [];
152
169
  });
153
170
  }
@@ -321,9 +338,13 @@ var ContentService = class {
321
338
  async listCourseActivityViews(courseId, actor) {
322
339
  this.require(actor, "courses:read", courseId);
323
340
  const [activities, links] = await Promise.all([this.repo.listActivitiesForCourse(actor.orgId, courseId), this.repo.listActivityAssetsForCourse(actor.orgId, courseId)]);
341
+ const urls = await this.files.fileLinks(actor.orgId, links.map((link) => ({ assetId: link.assetId })));
324
342
  return activities.map((activity) => ({
325
343
  ...activity,
326
- assetUrls: Object.fromEntries(links.filter((link) => link.activityId === activity.id).map((link) => [link.assetId, this.fileUrls.activityAsset(activity.id, link.assetId)]))
344
+ assetUrls: Object.fromEntries(links.flatMap((link) => {
345
+ const url = urls[link.assetId];
346
+ return link.activityId === activity.id && url ? [[link.assetId, url]] : [];
347
+ }))
327
348
  }));
328
349
  }
329
350
  async listCourseActivityAssets(courseId, actor) {
@@ -763,7 +784,8 @@ var ContentService = class {
763
784
  async findEvents(ids, actor) {
764
785
  for (const id of ids) this.require(actor, "events:read", id);
765
786
  if (ids.length === 0) return [];
766
- return (await this.repo.findEventsByIds(actor.orgId, ids)).map((event) => this.withThumbnail(event));
787
+ const found = await this.repo.findEventsByIds(actor.orgId, ids);
788
+ return this.withThumbnails(found);
767
789
  }
768
790
  async createEvent(input, actor) {
769
791
  this.require(actor, "events:write");
@@ -1269,7 +1291,8 @@ var ContentService = class {
1269
1291
  this.requireAny(actor, COMMUNITY_READERS, communityId);
1270
1292
  const community = await this.repo.findCommunityById(actor.orgId, communityId);
1271
1293
  if (!community) throw new NotFoundError("Community", communityId);
1272
- return (await this.repo.listSpaces(actor.orgId, communityId)).map((space) => this.spaceView(space, community.status === "published"));
1294
+ const spaces = await this.repo.listSpaces(actor.orgId, communityId);
1295
+ return this.spaceViews(spaces, community.status === "published");
1273
1296
  }
1274
1297
  async getDmSettings(communityId, actor) {
1275
1298
  this.require(actor, "communities:read", communityId);
@@ -1529,7 +1552,7 @@ var ContentService = class {
1529
1552
  actorId: actor.id
1530
1553
  });
1531
1554
  const published = await this.communityPublished(orgId, communityId);
1532
- return spaces.map((space) => this.spaceView(space, published));
1555
+ return this.spaceViews(spaces, published);
1533
1556
  }
1534
1557
  async setSpaceTopics(communityId, spaceId, input, actor) {
1535
1558
  this.require(actor, "communities:write", communityId);