@headless-lms/core 0.1.0 → 0.3.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.
- package/dist/assets/events.d.ts +90 -9
- package/dist/assets/events.js +19 -3
- package/dist/assets/events.js.map +1 -1
- package/dist/assets/file-urls.d.ts +20 -0
- package/dist/assets/file-urls.js +25 -0
- package/dist/assets/file-urls.js.map +1 -0
- package/dist/assets/index.d.ts +5 -4
- package/dist/assets/index.js +3 -2
- package/dist/assets/model.d.ts +2 -2
- package/dist/assets/ports.d.ts +45 -15
- package/dist/assets/service.d.ts +39 -7
- package/dist/assets/service.js +292 -37
- package/dist/assets/service.js.map +1 -1
- package/dist/automations/actions.d.ts +12 -15
- package/dist/automations/actions.js +188 -30
- package/dist/automations/actions.js.map +1 -1
- package/dist/automations/catalog.d.ts +5 -1
- package/dist/automations/catalog.js +514 -197
- package/dist/automations/catalog.js.map +1 -1
- package/dist/automations/community-derivations.d.ts +14 -0
- package/dist/automations/community-derivations.js +439 -0
- package/dist/automations/community-derivations.js.map +1 -0
- package/dist/automations/community-mail.d.ts +112 -0
- package/dist/automations/community-mail.js +90 -0
- package/dist/automations/community-mail.js.map +1 -0
- package/dist/automations/community-notifications.d.ts +16 -0
- package/dist/automations/community-notifications.js +84 -0
- package/dist/automations/community-notifications.js.map +1 -0
- package/dist/automations/events.d.ts +74 -24
- package/dist/automations/events.js +5 -5
- package/dist/automations/events.js.map +1 -1
- package/dist/automations/index.d.ts +7 -5
- package/dist/automations/index.js +3 -2
- package/dist/automations/model.d.ts +20 -3
- package/dist/automations/model.js +36 -3
- package/dist/automations/model.js.map +1 -1
- package/dist/automations/ports.d.ts +27 -8
- package/dist/automations/schedule.d.ts +6 -0
- package/dist/automations/schedule.js +41 -0
- package/dist/automations/schedule.js.map +1 -0
- package/dist/automations/seeds.d.ts +17 -0
- package/dist/automations/seeds.js +235 -0
- package/dist/automations/seeds.js.map +1 -0
- package/dist/automations/service.d.ts +41 -6
- package/dist/automations/service.js +542 -59
- package/dist/automations/service.js.map +1 -1
- package/dist/automations/types.d.ts +2 -2
- package/dist/automations/webhook-signing.d.ts +7 -0
- package/dist/automations/webhook-signing.js +22 -0
- package/dist/automations/webhook-signing.js.map +1 -0
- package/dist/content/events.d.ts +1013 -25
- package/dist/content/events.js +168 -19
- package/dist/content/events.js.map +1 -1
- package/dist/content/index.d.ts +5 -5
- package/dist/content/index.js +2 -2
- package/dist/content/model.d.ts +2 -2
- package/dist/content/ports.d.ts +109 -25
- package/dist/content/service.d.ts +68 -23
- package/dist/content/service.js +647 -60
- package/dist/content/service.js.map +1 -1
- package/dist/content/types.d.ts +2 -2
- package/dist/discussion/authors.d.ts +10 -0
- package/dist/discussion/authors.js +23 -0
- package/dist/discussion/authors.js.map +1 -0
- package/dist/discussion/chats.d.ts +104 -0
- package/dist/discussion/chats.js +798 -0
- package/dist/discussion/chats.js.map +1 -0
- package/dist/discussion/events.d.ts +633 -14
- package/dist/discussion/events.js +134 -5
- package/dist/discussion/events.js.map +1 -1
- package/dist/discussion/index.d.ts +7 -3
- package/dist/discussion/index.js +4 -1
- package/dist/discussion/model.d.ts +1 -2
- package/dist/discussion/ports.d.ts +288 -27
- package/dist/discussion/ports.js +6 -1
- package/dist/discussion/ports.js.map +1 -0
- package/dist/discussion/posts.d.ts +103 -0
- package/dist/discussion/posts.js +723 -0
- package/dist/discussion/posts.js.map +1 -0
- package/dist/discussion/service.d.ts +33 -11
- package/dist/discussion/service.js +297 -81
- package/dist/discussion/service.js.map +1 -1
- package/dist/entitlements/events.d.ts +264 -13
- package/dist/entitlements/events.js +49 -5
- package/dist/entitlements/events.js.map +1 -1
- package/dist/entitlements/index.d.ts +5 -4
- package/dist/entitlements/index.js +2 -1
- package/dist/entitlements/model.d.ts +3 -2
- package/dist/entitlements/ports.d.ts +124 -11
- package/dist/entitlements/rules.d.ts +12 -0
- package/dist/entitlements/rules.js +17 -0
- package/dist/entitlements/rules.js.map +1 -0
- package/dist/entitlements/service.d.ts +54 -3
- package/dist/entitlements/service.js +473 -2
- package/dist/entitlements/service.js.map +1 -1
- package/dist/identity/access.d.ts +6 -0
- package/dist/identity/access.js +7 -0
- package/dist/identity/access.js.map +1 -0
- package/dist/identity/events.d.ts +17 -3
- package/dist/identity/events.js +12 -2
- package/dist/identity/events.js.map +1 -1
- package/dist/identity/index.d.ts +6 -4
- package/dist/identity/index.js +3 -1
- package/dist/identity/model.d.ts +2 -1
- package/dist/identity/notifications.d.ts +27 -0
- package/dist/identity/notifications.js +101 -0
- package/dist/identity/notifications.js.map +1 -0
- package/dist/identity/ports.d.ts +76 -3
- package/dist/identity/service.d.ts +17 -3
- package/dist/identity/service.js +73 -5
- package/dist/identity/service.js.map +1 -1
- package/dist/integrations/events.d.ts +27 -3
- package/dist/integrations/events.js +15 -3
- package/dist/integrations/events.js.map +1 -1
- package/dist/integrations/model.js +1 -1
- package/dist/integrations/model.js.map +1 -1
- package/dist/integrations/service.js +2 -2
- package/dist/integrations/service.js.map +1 -1
- package/dist/organizations/access-scopes.d.ts +19 -0
- package/dist/organizations/access-scopes.js +89 -0
- package/dist/organizations/access-scopes.js.map +1 -0
- package/dist/organizations/events.d.ts +234 -25
- package/dist/organizations/events.js +58 -9
- package/dist/organizations/events.js.map +1 -1
- package/dist/organizations/index.d.ts +8 -7
- package/dist/organizations/index.js +4 -3
- package/dist/organizations/members.d.ts +8 -5
- package/dist/organizations/members.js.map +1 -1
- package/dist/organizations/ports.d.ts +20 -21
- package/dist/organizations/roles.d.ts +6 -10
- package/dist/organizations/roles.js +19 -7
- package/dist/organizations/roles.js.map +1 -1
- package/dist/organizations/service.d.ts +28 -14
- package/dist/organizations/service.js +274 -105
- package/dist/organizations/service.js.map +1 -1
- package/dist/organizations/types.d.ts +2 -11
- package/dist/progress/events.d.ts +34 -2
- package/dist/progress/events.js +15 -2
- package/dist/progress/events.js.map +1 -1
- package/dist/progress/index.d.ts +2 -2
- package/dist/progress/ports.d.ts +6 -1
- package/dist/progress/service.d.ts +5 -3
- package/dist/progress/service.js +9 -3
- package/dist/progress/service.js.map +1 -1
- package/dist/reporting/admin/index.d.ts +4 -0
- package/dist/reporting/admin/index.js +2 -0
- package/dist/reporting/admin/model.d.ts +108 -0
- package/dist/reporting/admin/ports.d.ts +27 -0
- package/dist/reporting/admin/service.d.ts +22 -0
- package/dist/reporting/admin/service.js +38 -0
- package/dist/reporting/admin/service.js.map +1 -0
- package/dist/reporting/member/index.d.ts +5 -0
- package/dist/reporting/member/index.js +2 -0
- package/dist/reporting/member/model.d.ts +124 -0
- package/dist/reporting/member/ports.d.ts +45 -0
- package/dist/reporting/member/service.d.ts +73 -0
- package/dist/reporting/member/service.js +286 -0
- package/dist/reporting/member/service.js.map +1 -0
- package/dist/shared/actor.d.ts +9 -0
- package/dist/shared/errors.d.ts +7 -1
- package/dist/shared/errors.js +10 -1
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/events.d.ts +5 -3
- package/dist/shared/events.js +1 -0
- package/dist/shared/events.js.map +1 -1
- package/dist/shared/id.d.ts +12 -0
- package/dist/shared/id.js +13 -1
- package/dist/shared/id.js.map +1 -1
- package/dist/shared/mailer.d.ts +6 -1
- package/dist/shared/mailer.js.map +1 -1
- package/dist/shared/network.d.ts +10 -0
- package/dist/shared/network.js +211 -0
- package/dist/shared/network.js.map +1 -0
- package/dist/shared/settings.js.map +1 -1
- package/dist/types/assets.d.ts +2 -2
- package/dist/types/automations.d.ts +21 -2
- package/dist/types/content.d.ts +2 -2
- package/dist/types/discussion.d.ts +12 -3
- package/dist/types/email-templates.d.ts +124 -1
- package/dist/types/entitlements.d.ts +2 -2
- package/dist/types/events.d.ts +3 -3
- package/dist/types/identity.d.ts +48 -2
- package/dist/types/index.d.ts +10 -10
- package/dist/types/organizations.d.ts +2 -2
- package/dist/types/ports.d.ts +7 -1
- package/dist/types/schemas/assets.d.ts +67 -36
- package/dist/types/schemas/assets.js +19 -13
- package/dist/types/schemas/assets.js.map +1 -1
- package/dist/types/schemas/automations.d.ts +88 -4
- package/dist/types/schemas/automations.js +46 -6
- package/dist/types/schemas/automations.js.map +1 -1
- package/dist/types/schemas/content.d.ts +385 -20
- package/dist/types/schemas/content.js +178 -15
- package/dist/types/schemas/content.js.map +1 -1
- package/dist/types/schemas/credentials.js.map +1 -1
- package/dist/types/schemas/discussion.d.ts +379 -4
- package/dist/types/schemas/discussion.js +209 -7
- package/dist/types/schemas/discussion.js.map +1 -1
- package/dist/types/schemas/entitlements.d.ts +44 -4
- package/dist/types/schemas/entitlements.js +32 -4
- package/dist/types/schemas/entitlements.js.map +1 -1
- package/dist/types/schemas/identity.d.ts +115 -5
- package/dist/types/schemas/identity.js +59 -6
- package/dist/types/schemas/identity.js.map +1 -1
- package/dist/types/schemas/index.d.ts +9 -9
- package/dist/types/schemas/index.js +9 -9
- package/dist/types/schemas/integrations.js.map +1 -1
- package/dist/types/schemas/organizations.d.ts +27 -5
- package/dist/types/schemas/organizations.js +14 -7
- package/dist/types/schemas/organizations.js.map +1 -1
- package/dist/types/schemas/outbox.d.ts +1 -0
- package/dist/types/schemas/outbox.js +1 -0
- package/dist/types/schemas/outbox.js.map +1 -1
- package/dist/types/schemas/progress.d.ts +1 -0
- package/dist/types/schemas/progress.js +1 -0
- package/dist/types/schemas/progress.js.map +1 -1
- package/dist/types/schemas/settings.js.map +1 -1
- package/dist/types/schemas/shared.d.ts +4 -1
- package/dist/types/schemas/shared.js +7 -1
- package/dist/types/schemas/shared.js.map +1 -1
- package/dist/types/shared.d.ts +1 -1
- package/package.json +2 -2
- package/dist/reporting/dashboard/index.d.ts +0 -4
- package/dist/reporting/dashboard/index.js +0 -2
- package/dist/reporting/dashboard/model.d.ts +0 -14
- package/dist/reporting/dashboard/ports.d.ts +0 -13
- package/dist/reporting/dashboard/service.d.ts +0 -19
- package/dist/reporting/dashboard/service.js +0 -20
- package/dist/reporting/dashboard/service.js.map +0 -1
- package/dist/reporting/learn/index.d.ts +0 -5
- package/dist/reporting/learn/index.js +0 -2
- package/dist/reporting/learn/model.d.ts +0 -23
- package/dist/reporting/learn/ports.d.ts +0 -42
- package/dist/reporting/learn/service.d.ts +0 -48
- package/dist/reporting/learn/service.js +0 -111
- package/dist/reporting/learn/service.js.map +0 -1
- package/dist/reporting/students/index.d.ts +0 -4
- package/dist/reporting/students/index.js +0 -2
- package/dist/reporting/students/model.d.ts +0 -31
- package/dist/reporting/students/ports.d.ts +0 -13
- package/dist/reporting/students/ports.js +0 -1
- package/dist/reporting/students/service.d.ts +0 -19
- package/dist/reporting/students/service.js +0 -20
- package/dist/reporting/students/service.js.map +0 -1
- /package/dist/reporting/{dashboard → admin}/model.js +0 -0
- /package/dist/reporting/{dashboard → admin}/ports.js +0 -0
- /package/dist/reporting/{learn → member}/model.js +0 -0
- /package/dist/reporting/{learn → member}/ports.js +0 -0
- /package/dist/{reporting/students/model.js → shared/actor.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","names":[],"sources":["../../src/content/service.ts"],"sourcesContent":["import type {\n Activity,\n Course,\n CourseSettings,\n Download,\n DownloadAsset,\n Module,\n SaveActivityInput,\n} from './model.js';\nimport type { ContentService, ContentRepository, ContentUnitOfWork } from './ports.js';\nimport type {\n AddDownloadAssetInput,\n CreateCourseInput,\n CreateDownloadInput,\n ListCoursesQuery,\n ListDownloadsQuery,\n Page,\n UpdateCourseInput,\n UpdateDownloadInput,\n} from './types.js';\nimport { contentEvents } from './events.js';\nimport type { Logger } from '../shared/ports.js';\nimport { SettingsNamespace, type SettingsService } from '../shared/settings.js';\nimport { NotFoundError, ConflictError } from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\n\n/** URL-safe slug derived from a title. Domain rule owned by the service. */\nfunction slugify(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n}\n\n/** Defaults for keys the stored blob doesn't carry (rows predating a setting). */\nconst settingsDefaults: CourseSettings = { transcriptDownloads: false };\n\nfunction toCourseSettings(stored: unknown): CourseSettings {\n return { ...settingsDefaults, ...(stored as Partial<CourseSettings> | null) };\n}\n\nexport type ContentServiceParams = {\n repo: ContentRepository;\n uow: ContentUnitOfWork;\n settings: SettingsService;\n logger?: Logger;\n};\n\nexport class ContentServiceImpl implements ContentService {\n private readonly repo: ContentRepository;\n private readonly uow: ContentUnitOfWork;\n private readonly settings: SettingsService;\n private readonly logger: Logger;\n\n constructor(params: ContentServiceParams) {\n this.repo = params.repo;\n this.uow = params.uow;\n this.settings = params.settings;\n this.logger = params.logger ?? noopLogger;\n }\n\n list(orgId: string, query: ListCoursesQuery): Promise<Page<Course>> {\n return this.repo.list(orgId, query);\n }\n\n async getCourse(orgId: string, id: string): Promise<Course | null> {\n const course = await this.repo.findById(orgId, id);\n if (!course) {\n return null;\n }\n const settings = await this.settings.get<Partial<CourseSettings>>(\n orgId,\n SettingsNamespace.content,\n id,\n );\n\n return {\n ...course,\n settings: {\n ...toCourseSettings(course.settings),\n ...settings,\n } as Course['settings'],\n };\n }\n\n async createCourse(orgId: string, input: CreateCourseInput): Promise<Course> {\n const course = await this.uow.run(async ({ content, outbox }) => {\n const created = await content.create(orgId, input, slugify(input.title));\n await outbox.append([\n contentEvents.courseCreated.make({ orgId, data: created }),\n ]);\n return created;\n });\n this.logger.info('course created', { orgId, courseId: course.id, title: course.title });\n return course;\n }\n\n async updateCourse(orgId: string, id: string, patch: UpdateCourseInput): Promise<Course> {\n const course = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.update(orgId, id, patch);\n if (!updated) {\n this.logger.warn('course update rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n await outbox.append([\n contentEvents.courseUpdated.make({ orgId, data: updated }),\n ]);\n return updated;\n });\n this.logger.info('course updated', { orgId, courseId: id, fields: Object.keys(patch) });\n return course;\n }\n\n async patchSettings(\n orgId: string,\n id: string,\n value: Partial<CourseSettings>,\n ): Promise<CourseSettings> {\n const course = await this.repo.findById(orgId, id);\n if (!course) {\n this.logger.warn('course settings patch rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n const merged = await this.settings.patch<Partial<CourseSettings>>(\n orgId,\n SettingsNamespace.content,\n id,\n value,\n );\n this.logger.info('course settings patched', { orgId, courseId: id, value });\n return { ...toCourseSettings(course.settings), ...merged };\n }\n\n async deleteCourse(orgId: string, id: string): Promise<void> {\n await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const course = await content.findById(orgId, id);\n if (!course) {\n this.logger.warn('course delete rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n const ok = await content.delete(orgId, id);\n if (!ok) {\n throw new NotFoundError('Course', id);\n }\n await outbox.append([contentEvents.courseDeleted.make({ orgId, data: course })]);\n });\n this.logger.info('course deleted', { orgId, courseId: id });\n }\n\n // --- modules & activities ------------------------------------------------\n\n listCourseModules(orgId: string, courseId: string): Promise<Module[]> {\n return this.repo.listForCourse(orgId, courseId);\n }\n listCourseActivities(orgId: string, courseId: string): Promise<Activity[]> {\n return this.repo.listActivitiesForCourse(orgId, courseId);\n }\n getActivity(orgId: string, activityId: string): Promise<Activity | null> {\n return this.repo.findActivity(orgId, activityId);\n }\n getModule(orgId: string, moduleId: string): Promise<Module | null> {\n return this.repo.findModule(orgId, moduleId);\n }\n\n async reorderModules(orgId: string, courseId: string, orderedIds: string[]): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const reordered = await content.reorderModules(orgId, courseId, orderedIds);\n await outbox.append([\n contentEvents.modulesReordered.make({ orgId, data: reordered }),\n ]);\n return reordered;\n });\n this.logger.debug('modules reordered', {\n orgId,\n courseId,\n moduleIds: modules.map((m) => m.id),\n });\n return modules;\n }\n\n async createModule(orgId: string, courseId: string, title: string): Promise<Module[]> {\n const { modules, created } = await this.uow.run(async ({ content, outbox }) => {\n const all = await content.createModule(orgId, courseId, title);\n // The list is ordered by seq and the new module is appended at max(seq)+1.\n const module = all.at(-1);\n if (!module) {\n throw new Error('failed to load created module');\n }\n await outbox.append([contentEvents.moduleCreated.make({ orgId, data: module })]);\n return { modules: all, created: module };\n });\n this.logger.info('module created', { orgId, courseId, moduleId: created.id, title });\n return modules;\n }\n\n async updateModule(\n orgId: string,\n courseId: string,\n moduleId: string,\n title: string,\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const existing = await content.findModule(orgId, moduleId);\n if (!existing || existing.courseId !== courseId) {\n this.logger.warn('module update rejected — not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n const all = await content.updateModule(orgId, courseId, moduleId, title);\n const module = all.find((m) => m.id === moduleId);\n if (!module) {\n throw new NotFoundError('Module', moduleId);\n }\n await outbox.append([contentEvents.moduleUpdated.make({ orgId, data: module })]);\n return all;\n });\n this.logger.info('module updated', { orgId, courseId, moduleId, title });\n return modules;\n }\n\n async deleteModule(orgId: string, courseId: string, moduleId: string): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const module = await content.findModule(orgId, moduleId);\n if (!module || module.courseId !== courseId) {\n this.logger.warn('module delete rejected — not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n const remaining = await content.deleteModule(orgId, courseId, moduleId);\n await outbox.append([contentEvents.moduleDeleted.make({ orgId, data: module })]);\n return remaining;\n });\n this.logger.info('module deleted', { orgId, courseId, moduleId });\n return modules;\n }\n\n async reorderActivities(\n orgId: string,\n courseId: string,\n moduleId: string,\n orderedIds: string[],\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const reordered = await content.reorderActivities(orgId, courseId, moduleId, orderedIds);\n const module = reordered.find((m) => m.id === moduleId);\n if (!module) {\n throw new NotFoundError('Module', moduleId);\n }\n await outbox.append([\n contentEvents.activitiesReordered.make({ orgId, data: module }),\n ]);\n return reordered;\n });\n this.logger.debug('activities reordered', { orgId, courseId, moduleId });\n return modules;\n }\n\n async saveActivity(\n orgId: string,\n courseId: string,\n moduleId: string,\n input: SaveActivityInput,\n activityId?: string,\n ): Promise<Module[]> {\n const { modules, activity } = await this.uow.run(async ({ content, outbox }) => {\n if (activityId) {\n const existing = await content.findActivity(orgId, activityId);\n if (!existing || existing.moduleId !== moduleId || existing.courseId !== courseId) {\n this.logger.warn('activity update rejected — not found in module', {\n orgId,\n courseId,\n moduleId,\n activityId,\n });\n throw new NotFoundError('Activity', activityId);\n }\n } else {\n const module = await content.findModule(orgId, moduleId);\n if (!module || module.courseId !== courseId) {\n this.logger.warn('activity create rejected — module not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n }\n\n const { modules: all, activity: saved } = await content.saveActivity(\n orgId,\n courseId,\n moduleId,\n input,\n activityId,\n );\n await outbox.append([\n activityId\n ? contentEvents.activityUpdated.make({ orgId, data: saved })\n : contentEvents.activityCreated.make({ orgId, data: saved }),\n ]);\n return { modules: all, activity: saved };\n });\n this.logger.info(activityId ? 'activity updated' : 'activity created', {\n orgId,\n courseId,\n moduleId,\n activityId: activity.id,\n });\n return modules;\n }\n\n async deleteActivity(\n orgId: string,\n courseId: string,\n moduleId: string,\n activityId: string,\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const activity = await content.findActivity(orgId, activityId);\n if (!activity || activity.moduleId !== moduleId || activity.courseId !== courseId) {\n this.logger.warn('activity delete rejected — not found in module', {\n orgId,\n courseId,\n moduleId,\n activityId,\n });\n throw new NotFoundError('Activity', activityId);\n }\n const remaining = await content.deleteActivity(orgId, courseId, moduleId, activityId);\n await outbox.append([\n contentEvents.activityDeleted.make({ orgId, data: activity }),\n ]);\n return remaining;\n });\n this.logger.info('activity deleted', { orgId, courseId, moduleId, activityId });\n return modules;\n }\n\n // --- downloads ------------------------------------------------------------\n\n listDownloads(orgId: string, query: ListDownloadsQuery): Promise<Page<Download>> {\n return this.repo.listDownloads(orgId, query);\n }\n\n getDownload(orgId: string, id: string): Promise<Download | null> {\n return this.repo.getDownload(orgId, id);\n }\n\n async createDownload(orgId: string, input: CreateDownloadInput): Promise<Download> {\n const download = await this.uow.run(async ({ content, outbox }) => {\n const created = await content.createDownload(orgId, input, slugify(input.title));\n await outbox.append([\n contentEvents.downloadCreated.make({ orgId, data: created }),\n ]);\n return created;\n });\n this.logger.info('download created', { orgId, downloadId: download.id, title: download.title });\n return download;\n }\n\n async updateDownload(orgId: string, id: string, patch: UpdateDownloadInput): Promise<Download> {\n const download = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.updateDownload(orgId, id, patch);\n if (!updated) {\n this.logger.warn('download update rejected — not found', { orgId, downloadId: id });\n throw new NotFoundError('Download', id);\n }\n await outbox.append([\n contentEvents.downloadUpdated.make({ orgId, data: updated }),\n ]);\n return updated;\n });\n this.logger.info('download updated', { orgId, downloadId: id, fields: Object.keys(patch) });\n return download;\n }\n\n async removeDownload(orgId: string, id: string): Promise<void> {\n await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const download = await content.getDownload(orgId, id);\n if (!download) {\n this.logger.warn('download delete rejected — not found', { orgId, downloadId: id });\n throw new NotFoundError('Download', id);\n }\n const ok = await content.deleteDownload(orgId, id);\n if (!ok) {\n throw new NotFoundError('Download', id);\n }\n await outbox.append([\n contentEvents.downloadDeleted.make({ orgId, data: download }),\n ]);\n });\n this.logger.info('download deleted', { orgId, downloadId: id });\n }\n\n // --- download asset links ------------------------------------------------\n\n listDownloadAssets(orgId: string, downloadId: string): Promise<DownloadAsset[]> {\n return this.repo.listDownloadAssets(orgId, downloadId);\n }\n\n async addDownloadAsset(\n orgId: string,\n downloadId: string,\n input: AddDownloadAssetInput,\n ): Promise<DownloadAsset[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.addDownloadAsset(orgId, downloadId, input);\n await outbox.append([\n contentEvents.downloadAssetAdded.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset added', { orgId, downloadId, assetId: input.assetId });\n return assets;\n }\n\n async removeDownloadAsset(\n orgId: string,\n downloadId: string,\n assetId: string,\n ): Promise<DownloadAsset[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.removeDownloadAsset(orgId, downloadId, assetId);\n await outbox.append([\n contentEvents.downloadAssetRemoved.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset removed', { orgId, downloadId, assetId });\n return assets;\n }\n\n async renameDownloadAsset(\n orgId: string,\n downloadId: string,\n assetId: string,\n displayName: string | null,\n ): Promise<DownloadAsset[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.renameDownloadAsset(orgId, downloadId, assetId, displayName);\n await outbox.append([\n contentEvents.downloadAssetRenamed.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset renamed', { orgId, downloadId, assetId });\n return assets;\n }\n\n /** The caller must send the COMPLETE ordered set — a partial list would\n * silently unlink whatever it omitted. */\n async reorderDownloadAssets(\n orgId: string,\n downloadId: string,\n assetIds: string[],\n ): Promise<DownloadAsset[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.listDownloadAssets(orgId, downloadId);\n const currentIds = new Set(current.map((a) => a.assetId));\n const requestedIds = new Set(assetIds);\n if (\n requestedIds.size !== assetIds.length ||\n requestedIds.size !== currentIds.size ||\n !assetIds.every((id) => currentIds.has(id))\n ) {\n this.logger.warn('download asset reorder rejected — id set mismatch', {\n orgId,\n downloadId,\n assetIds,\n currentIds: [...currentIds],\n });\n throw new ConflictError(\"Ordered asset ids does not match the download's current assets\");\n }\n const assets = await content.reorderDownloadAssets(orgId, downloadId, assetIds);\n await outbox.append([\n contentEvents.downloadAssetsReordered.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.debug('download assets reordered', { orgId, downloadId });\n return assets;\n }\n}\n"],"mappings":";;;;;;AA2BA,SAAS,QAAQ,OAAuB;CACtC,OAAO,MACJ,YAAY,CAAC,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,QAAQ,YAAY,EAAE;AAC3B;;AAGA,MAAM,mBAAmC,EAAE,qBAAqB,MAAM;AAEtE,SAAS,iBAAiB,QAAiC;CACzD,OAAO;EAAE,GAAG;EAAkB,GAAI;CAA0C;AAC9E;AASA,IAAa,qBAAb,MAA0D;CACxD;CACA;CACA;CACA;CAEA,YAAY,QAA8B;EACxC,KAAK,OAAO,OAAO;EACnB,KAAK,MAAM,OAAO;EAClB,KAAK,WAAW,OAAO;EACvB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,KAAK,OAAe,OAAgD;EAClE,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK;CACpC;CAEA,MAAM,UAAU,OAAe,IAAoC;EACjE,MAAM,SAAS,MAAM,KAAK,KAAK,SAAS,OAAO,EAAE;EACjD,IAAI,CAAC,QACH,OAAO;EAET,MAAM,WAAW,MAAM,KAAK,SAAS,IACnC,OAAA,WAEA,EACF;EAEA,OAAO;GACL,GAAG;GACH,UAAU;IACR,GAAG,iBAAiB,OAAO,QAAQ;IACnC,GAAG;GACL;EACF;CACF;CAEA,MAAM,aAAa,OAAe,OAA2C;EAC3E,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,OAAO,QAAQ,MAAM,KAAK,CAAC;GACvE,MAAM,OAAO,OAAO,CAClB,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAC3D,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU,OAAO;GAAI,OAAO,OAAO;EAAM,CAAC;EACtF,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,IAAY,OAA2C;EACvF,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,IAAI,KAAK;GACrD,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GACA,MAAM,OAAO,OAAO,CAClB,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAC3D,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;GAAI,QAAQ,OAAO,KAAK,KAAK;EAAE,CAAC;EACtF,OAAO;CACT;CAEA,MAAM,cACJ,OACA,IACA,OACyB;EACzB,MAAM,SAAS,MAAM,KAAK,KAAK,SAAS,OAAO,EAAE;EACjD,IAAI,CAAC,QAAQ;GACX,KAAK,OAAO,KAAK,8CAA8C;IAAE;IAAO,UAAU;GAAG,CAAC;GACtF,MAAM,IAAI,cAAc,UAAU,EAAE;EACtC;EACA,MAAM,SAAS,MAAM,KAAK,SAAS,MACjC,OAAA,WAEA,IACA,KACF;EACA,KAAK,OAAO,KAAK,2BAA2B;GAAE;GAAO,UAAU;GAAI;EAAM,CAAC;EAC1E,OAAO;GAAE,GAAG,iBAAiB,OAAO,QAAQ;GAAG,GAAG;EAAO;CAC3D;CAEA,MAAM,aAAa,OAAe,IAA2B;EAC3D,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhD,MAAM,SAAS,MAAM,QAAQ,SAAS,OAAO,EAAE;GAC/C,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GAEA,IAAI,CAAC,MADY,QAAQ,OAAO,OAAO,EAAE,GAEvC,MAAM,IAAI,cAAc,UAAU,EAAE;GAEtC,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;EACjF,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;EAAG,CAAC;CAC5D;CAIA,kBAAkB,OAAe,UAAqC;EACpE,OAAO,KAAK,KAAK,cAAc,OAAO,QAAQ;CAChD;CACA,qBAAqB,OAAe,UAAuC;EACzE,OAAO,KAAK,KAAK,wBAAwB,OAAO,QAAQ;CAC1D;CACA,YAAY,OAAe,YAA8C;EACvE,OAAO,KAAK,KAAK,aAAa,OAAO,UAAU;CACjD;CACA,UAAU,OAAe,UAA0C;EACjE,OAAO,KAAK,KAAK,WAAW,OAAO,QAAQ;CAC7C;CAEA,MAAM,eAAe,OAAe,UAAkB,YAAyC;EAC7F,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,YAAY,MAAM,QAAQ,eAAe,OAAO,UAAU,UAAU;GAC1E,MAAM,OAAO,OAAO,CAClB,cAAc,iBAAiB,KAAK;IAAE;IAAO,MAAM;GAAU,CAAC,CAChE,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,qBAAqB;GACrC;GACA;GACA,WAAW,QAAQ,KAAK,MAAM,EAAE,EAAE;EACpC,CAAC;EACD,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,UAAkB,OAAkC;EACpF,MAAM,EAAE,SAAS,YAAY,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC7E,MAAM,MAAM,MAAM,QAAQ,aAAa,OAAO,UAAU,KAAK;GAE7D,MAAM,SAAS,IAAI,GAAG,EAAE;GACxB,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,+BAA+B;GAEjD,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;IAAE,SAAS;IAAK,SAAS;GAAO;EACzC,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU,UAAU,QAAQ;GAAI;EAAM,CAAC;EACnF,OAAO;CACT;CAEA,MAAM,aACJ,OACA,UACA,UACA,OACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,WAAW,MAAM,QAAQ,WAAW,OAAO,QAAQ;GACzD,IAAI,CAAC,YAAY,SAAS,aAAa,UAAU;IAC/C,KAAK,OAAO,KAAK,gDAAgD;KAC/D;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,UAAU,QAAQ;GAC5C;GACA,MAAM,MAAM,MAAM,QAAQ,aAAa,OAAO,UAAU,UAAU,KAAK;GACvE,MAAM,SAAS,IAAI,MAAM,MAAM,EAAE,OAAO,QAAQ;GAChD,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,UAAU,QAAQ;GAE5C,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU;GAAU;EAAM,CAAC;EACvE,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,UAAkB,UAAqC;EACvF,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhE,MAAM,SAAS,MAAM,QAAQ,WAAW,OAAO,QAAQ;GACvD,IAAI,CAAC,UAAU,OAAO,aAAa,UAAU;IAC3C,KAAK,OAAO,KAAK,gDAAgD;KAC/D;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,UAAU,QAAQ;GAC5C;GACA,MAAM,YAAY,MAAM,QAAQ,aAAa,OAAO,UAAU,QAAQ;GACtE,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU;EAAS,CAAC;EAChE,OAAO;CACT;CAEA,MAAM,kBACJ,OACA,UACA,UACA,YACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,YAAY,MAAM,QAAQ,kBAAkB,OAAO,UAAU,UAAU,UAAU;GACvF,MAAM,SAAS,UAAU,MAAM,MAAM,EAAE,OAAO,QAAQ;GACtD,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,UAAU,QAAQ;GAE5C,MAAM,OAAO,OAAO,CAClB,cAAc,oBAAoB,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAChE,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,wBAAwB;GAAE;GAAO;GAAU;EAAS,CAAC;EACvE,OAAO;CACT;CAEA,MAAM,aACJ,OACA,UACA,UACA,OACA,YACmB;EACnB,MAAM,EAAE,SAAS,aAAa,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9E,IAAI,YAAY;IACd,MAAM,WAAW,MAAM,QAAQ,aAAa,OAAO,UAAU;IAC7D,IAAI,CAAC,YAAY,SAAS,aAAa,YAAY,SAAS,aAAa,UAAU;KACjF,KAAK,OAAO,KAAK,kDAAkD;MACjE;MACA;MACA;MACA;KACF,CAAC;KACD,MAAM,IAAI,cAAc,YAAY,UAAU;IAChD;GACF,OAAO;IACL,MAAM,SAAS,MAAM,QAAQ,WAAW,OAAO,QAAQ;IACvD,IAAI,CAAC,UAAU,OAAO,aAAa,UAAU;KAC3C,KAAK,OAAO,KAAK,yDAAyD;MACxE;MACA;MACA;KACF,CAAC;KACD,MAAM,IAAI,cAAc,UAAU,QAAQ;IAC5C;GACF;GAEA,MAAM,EAAE,SAAS,KAAK,UAAU,UAAU,MAAM,QAAQ,aACtD,OACA,UACA,UACA,OACA,UACF;GACA,MAAM,OAAO,OAAO,CAClB,aACI,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAM,CAAC,IACzD,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAM,CAAC,CAC/D,CAAC;GACD,OAAO;IAAE,SAAS;IAAK,UAAU;GAAM;EACzC,CAAC;EACD,KAAK,OAAO,KAAK,aAAa,qBAAqB,oBAAoB;GACrE;GACA;GACA;GACA,YAAY,SAAS;EACvB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,eACJ,OACA,UACA,UACA,YACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhE,MAAM,WAAW,MAAM,QAAQ,aAAa,OAAO,UAAU;GAC7D,IAAI,CAAC,YAAY,SAAS,aAAa,YAAY,SAAS,aAAa,UAAU;IACjF,KAAK,OAAO,KAAK,kDAAkD;KACjE;KACA;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,YAAY,UAAU;GAChD;GACA,MAAM,YAAY,MAAM,QAAQ,eAAe,OAAO,UAAU,UAAU,UAAU;GACpF,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAS,CAAC,CAC9D,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO;GAAU;GAAU;EAAW,CAAC;EAC9E,OAAO;CACT;CAIA,cAAc,OAAe,OAAoD;EAC/E,OAAO,KAAK,KAAK,cAAc,OAAO,KAAK;CAC7C;CAEA,YAAY,OAAe,IAAsC;EAC/D,OAAO,KAAK,KAAK,YAAY,OAAO,EAAE;CACxC;CAEA,MAAM,eAAe,OAAe,OAA+C;EACjF,MAAM,WAAW,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GACjE,MAAM,UAAU,MAAM,QAAQ,eAAe,OAAO,OAAO,QAAQ,MAAM,KAAK,CAAC;GAC/E,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAC7D,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY,SAAS;GAAI,OAAO,SAAS;EAAM,CAAC;EAC9F,OAAO;CACT;CAEA,MAAM,eAAe,OAAe,IAAY,OAA+C;EAC7F,MAAM,WAAW,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GACjE,MAAM,UAAU,MAAM,QAAQ,eAAe,OAAO,IAAI,KAAK;GAC7D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,wCAAwC;KAAE;KAAO,YAAY;IAAG,CAAC;IAClF,MAAM,IAAI,cAAc,YAAY,EAAE;GACxC;GACA,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAC7D,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY;GAAI,QAAQ,OAAO,KAAK,KAAK;EAAE,CAAC;EAC1F,OAAO;CACT;CAEA,MAAM,eAAe,OAAe,IAA2B;EAC7D,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhD,MAAM,WAAW,MAAM,QAAQ,YAAY,OAAO,EAAE;GACpD,IAAI,CAAC,UAAU;IACb,KAAK,OAAO,KAAK,wCAAwC;KAAE;KAAO,YAAY;IAAG,CAAC;IAClF,MAAM,IAAI,cAAc,YAAY,EAAE;GACxC;GAEA,IAAI,CAAC,MADY,QAAQ,eAAe,OAAO,EAAE,GAE/C,MAAM,IAAI,cAAc,YAAY,EAAE;GAExC,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAS,CAAC,CAC9D,CAAC;EACH,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY;EAAG,CAAC;CAChE;CAIA,mBAAmB,OAAe,YAA8C;EAC9E,OAAO,KAAK,KAAK,mBAAmB,OAAO,UAAU;CACvD;CAEA,MAAM,iBACJ,OACA,YACA,OAC0B;EAC1B,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,iBAAiB,OAAO,YAAY,KAAK;GACtE,MAAM,OAAO,OAAO,CAClB,cAAc,mBAAmB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CAC/E,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,wBAAwB;GAAE;GAAO;GAAY,SAAS,MAAM;EAAQ,CAAC;EACtF,OAAO;CACT;CAEA,MAAM,oBACJ,OACA,YACA,SAC0B;EAC1B,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,oBAAoB,OAAO,YAAY,OAAO;GAC3E,MAAM,OAAO,OAAO,CAClB,cAAc,qBAAqB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACjF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,0BAA0B;GAAE;GAAO;GAAY;EAAQ,CAAC;EACzE,OAAO;CACT;CAEA,MAAM,oBACJ,OACA,YACA,SACA,aAC0B;EAC1B,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,oBAAoB,OAAO,YAAY,SAAS,WAAW;GACxF,MAAM,OAAO,OAAO,CAClB,cAAc,qBAAqB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACjF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,0BAA0B;GAAE;GAAO;GAAY;EAAQ,CAAC;EACzE,OAAO;CACT;;;CAIA,MAAM,sBACJ,OACA,YACA,UAC0B;EAC1B,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,mBAAmB,OAAO,UAAU;GAClE,MAAM,aAAa,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,OAAO,CAAC;GACxD,MAAM,eAAe,IAAI,IAAI,QAAQ;GACrC,IACE,aAAa,SAAS,SAAS,UAC/B,aAAa,SAAS,WAAW,QACjC,CAAC,SAAS,OAAO,OAAO,WAAW,IAAI,EAAE,CAAC,GAC1C;IACA,KAAK,OAAO,KAAK,qDAAqD;KACpE;KACA;KACA;KACA,YAAY,CAAC,GAAG,UAAU;IAC5B,CAAC;IACD,MAAM,IAAI,cAAc,gEAAgE;GAC1F;GACA,MAAM,SAAS,MAAM,QAAQ,sBAAsB,OAAO,YAAY,QAAQ;GAC9E,MAAM,OAAO,OAAO,CAClB,cAAc,wBAAwB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACpF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,6BAA6B;GAAE;GAAO;EAAW,CAAC;EACpE,OAAO;CACT;AACF"}
|
|
1
|
+
{"version":3,"file":"service.js","names":[],"sources":["../../src/content/service.ts"],"sourcesContent":["import type {\n Activity,\n ActivityAsset,\n ActivityView,\n Bundle,\n BundleItem,\n Community,\n CommunityView,\n CourseSettings,\n CourseView,\n DmSettings,\n DownloadAsset,\n DownloadFile,\n DownloadView,\n Module,\n SaveActivityInput,\n Space,\n SpaceDetail,\n SpaceSettings,\n} from './model.js';\nimport type {\n BundlesService,\n CommunitiesService,\n CourseManagementService,\n ContentRepository,\n ContentUnitOfWork,\n DownloadablesService,\n} from './ports.js';\nimport type {\n AddDownloadAssetInput,\n CreateBundleInput,\n CreateCommunityInput,\n CreateCourseInput,\n CreateDownloadInput,\n CreateSpaceInput,\n ListBundlesQuery,\n ListCommunitiesQuery,\n ListCoursesQuery,\n ListDownloadsQuery,\n Page,\n PatchDmSettingsInput,\n SetSpaceTopicsInput,\n UpdateBundleInput,\n UpdateCommunityInput,\n UpdateCourseInput,\n UpdateDownloadInput,\n UpdateSpaceInput,\n} from './types.js';\nimport { contentEvents } from './events.js';\nimport type { Actor } from '../shared/actor.js';\nimport type { AssetFiles, FileUrls, LibraryAssetReader } from '../assets/index.js';\nimport type { Logger, NewDomainEvent } from '../shared/ports.js';\nimport {\n ConflictError,\n ForbiddenError,\n InvalidInputError,\n NotFoundError,\n} from '../shared/errors.js';\nimport { noopLogger } from '../shared/logger.js';\nimport { spaceSettingsDefaults } from '../types/schemas/content.js';\n\n/** URL-safe slug derived from a title. Domain rule owned by the service. */\nfunction slugify(title: string): string {\n return title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/(^-|-$)/g, '');\n}\n\nexport type ContentServiceParams = {\n repo: ContentRepository;\n uow: ContentUnitOfWork;\n libraryAssets: LibraryAssetReader;\n files: Pick<AssetFiles, 'readyFiles'>;\n fileUrls: FileUrls;\n logger?: Logger;\n};\n\nfunction actorMetadata(actor: Actor): { actorOrgUserId: string } {\n return { actorOrgUserId: actor.id };\n}\n\nfunction assertConfigurator(actor: Actor): void {\n if (actor.role !== 'owner' && actor.role !== 'admin') {\n throw new ForbiddenError('Only an owner or an admin can configure a community');\n }\n}\n\ntype WithThumbnail = {\n id: string;\n type: 'course' | 'download' | 'community';\n thumbnailAssetId: string | null;\n};\n\nfunction sameIdSet(current: string[], requested: string[]): boolean {\n if (current.length !== requested.length) {\n return false;\n }\n const have = new Set(current);\n return requested.every((id) => have.has(id)) && new Set(requested).size === requested.length;\n}\n\nexport class ContentService\n implements CourseManagementService, DownloadablesService, BundlesService, CommunitiesService\n{\n private readonly repo: ContentRepository;\n private readonly uow: ContentUnitOfWork;\n private readonly libraryAssets: LibraryAssetReader;\n private readonly files: Pick<AssetFiles, 'readyFiles'>;\n private readonly fileUrls: FileUrls;\n private readonly logger: Logger;\n\n constructor(params: ContentServiceParams) {\n this.repo = params.repo;\n this.uow = params.uow;\n this.libraryAssets = params.libraryAssets;\n this.files = params.files;\n this.fileUrls = params.fileUrls;\n this.logger = params.logger ?? noopLogger;\n }\n\n private withThumbnail<T extends WithThumbnail>(item: T): T & { thumbnailUrl: string | null } {\n return {\n ...item,\n thumbnailUrl: item.thumbnailAssetId ? this.fileUrls.thumbnail(item.type, item.id) : null,\n };\n }\n\n private pageWithThumbnails<T extends WithThumbnail>(\n page: Page<T>,\n ): Page<T & { thumbnailUrl: string | null }> {\n return { ...page, rows: page.rows.map((row) => this.withThumbnail(row)) };\n }\n\n private async downloadFiles(orgId: string, links: DownloadAsset[]): Promise<DownloadFile[]> {\n const ready = await this.files.readyFiles(\n orgId,\n links.map((link) => link.assetId),\n );\n return links.flatMap((link) => {\n const file = ready[link.assetId];\n return file\n ? [{ ...link, ...file, url: this.fileUrls.downloadFile(link.downloadId, link.assetId) }]\n : [];\n });\n }\n\n async listCourses(orgId: string, query: ListCoursesQuery): Promise<Page<CourseView>> {\n return this.pageWithThumbnails(await this.repo.listCourses(orgId, query));\n }\n\n async getCourse(orgId: string, id: string): Promise<CourseView | null> {\n const course = await this.repo.findCourseById(orgId, id);\n return course ? this.withThumbnail(course) : null;\n }\n\n async createCourse(orgId: string, input: CreateCourseInput): Promise<CourseView> {\n const course = await this.uow.run(async ({ content, outbox }) => {\n const created = await content.createCourse(orgId, input, slugify(input.title));\n await outbox.append([contentEvents.courseCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('course created', { orgId, courseId: course.id, title: course.title });\n return this.withThumbnail(course);\n }\n\n async updateCourse(orgId: string, id: string, patch: UpdateCourseInput): Promise<CourseView> {\n await this.assertLibraryAssets(orgId, [patch.thumbnailAssetId], 'A course');\n const course = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.updateCourse(orgId, id, patch);\n if (!updated) {\n this.logger.warn('course update rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n await outbox.append([contentEvents.courseUpdated.make({ orgId, data: updated })]);\n return updated;\n });\n this.logger.info('course updated', { orgId, courseId: id, fields: Object.keys(patch) });\n return this.withThumbnail(course);\n }\n\n async patchCourseSettings(\n orgId: string,\n id: string,\n value: Partial<CourseSettings>,\n ): Promise<CourseSettings> {\n const merged = await this.uow.run(async ({ content, outbox }) => {\n const course = await content.findCourseById(orgId, id);\n if (!course) {\n this.logger.warn('course settings patch rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n const settings = await content.patchCourseSettings(orgId, id, value);\n await outbox.append([\n contentEvents.courseUpdated.make({ orgId, data: { ...course, settings } }),\n ]);\n return settings;\n });\n this.logger.info('course settings patched', { orgId, courseId: id, value });\n return merged;\n }\n\n async deleteCourse(orgId: string, id: string, actor: Actor): Promise<void> {\n await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const course = await content.findCourseById(orgId, id);\n if (!course) {\n this.logger.warn('course delete rejected — not found', { orgId, courseId: id });\n throw new NotFoundError('Course', id);\n }\n const linked = await content.spacesLinkingContent(orgId, id);\n const ok = await content.deleteCourse(orgId, id);\n if (!ok) {\n throw new NotFoundError('Course', id);\n }\n await outbox.append([\n contentEvents.courseDeleted.make({ orgId, data: course }),\n ...(await this.spaceUpdates(content, orgId, linked, actor)),\n ]);\n });\n this.logger.info('course deleted', { orgId, courseId: id });\n }\n\n // --- modules & activities ------------------------------------------------\n\n listCourseModules(orgId: string, courseId: string): Promise<Module[]> {\n return this.repo.listCourseModules(orgId, courseId);\n }\n listCourseActivities(orgId: string, courseId: string): Promise<Activity[]> {\n return this.repo.listActivitiesForCourse(orgId, courseId);\n }\n async listCourseActivityViews(orgId: string, courseId: string): Promise<ActivityView[]> {\n const [activities, links] = await Promise.all([\n this.repo.listActivitiesForCourse(orgId, courseId),\n this.repo.listActivityAssetsForCourse(orgId, courseId),\n ]);\n return activities.map((activity) => ({\n ...activity,\n assetUrls: Object.fromEntries(\n links\n .filter((link) => link.activityId === activity.id)\n .map((link) => [link.assetId, this.fileUrls.activityAsset(activity.id, link.assetId)]),\n ),\n }));\n }\n listCourseActivityAssets(orgId: string, courseId: string): Promise<ActivityAsset[]> {\n return this.repo.listActivityAssetsForCourse(orgId, courseId);\n }\n getActivity(orgId: string, activityId: string): Promise<Activity | null> {\n return this.repo.findActivity(orgId, activityId);\n }\n getModule(orgId: string, moduleId: string): Promise<Module | null> {\n return this.repo.findModule(orgId, moduleId);\n }\n\n async reorderModules(orgId: string, courseId: string, orderedIds: string[]): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const reordered = await content.reorderModules(orgId, courseId, orderedIds);\n await outbox.append([contentEvents.modulesReordered.make({ orgId, data: reordered })]);\n return reordered;\n });\n this.logger.debug('modules reordered', {\n orgId,\n courseId,\n moduleIds: modules.map((m) => m.id),\n });\n return modules;\n }\n\n async createModule(orgId: string, courseId: string, title: string): Promise<Module[]> {\n const { modules, created } = await this.uow.run(async ({ content, outbox }) => {\n const all = await content.createModule(orgId, courseId, title);\n // The list is ordered by seq and the new module is appended at max(seq)+1.\n const module = all.at(-1);\n if (!module) {\n throw new Error('failed to load created module');\n }\n await outbox.append([contentEvents.moduleCreated.make({ orgId, data: module })]);\n return { modules: all, created: module };\n });\n this.logger.info('module created', { orgId, courseId, moduleId: created.id, title });\n return modules;\n }\n\n async updateModule(\n orgId: string,\n courseId: string,\n moduleId: string,\n title: string,\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const existing = await content.findModule(orgId, moduleId);\n if (!existing || existing.courseId !== courseId) {\n this.logger.warn('module update rejected — not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n const all = await content.updateModule(orgId, courseId, moduleId, title);\n const module = all.find((m) => m.id === moduleId);\n if (!module) {\n throw new NotFoundError('Module', moduleId);\n }\n await outbox.append([contentEvents.moduleUpdated.make({ orgId, data: module })]);\n return all;\n });\n this.logger.info('module updated', { orgId, courseId, moduleId, title });\n return modules;\n }\n\n async deleteModule(orgId: string, courseId: string, moduleId: string): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const module = await content.findModule(orgId, moduleId);\n if (!module || module.courseId !== courseId) {\n this.logger.warn('module delete rejected — not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n const remaining = await content.deleteModule(orgId, courseId, moduleId);\n await outbox.append([contentEvents.moduleDeleted.make({ orgId, data: module })]);\n return remaining;\n });\n this.logger.info('module deleted', { orgId, courseId, moduleId });\n return modules;\n }\n\n async reorderActivities(\n orgId: string,\n courseId: string,\n moduleId: string,\n orderedIds: string[],\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n const reordered = await content.reorderActivities(orgId, courseId, moduleId, orderedIds);\n const module = reordered.find((m) => m.id === moduleId);\n if (!module) {\n throw new NotFoundError('Module', moduleId);\n }\n await outbox.append([contentEvents.activitiesReordered.make({ orgId, data: module })]);\n return reordered;\n });\n this.logger.debug('activities reordered', { orgId, courseId, moduleId });\n return modules;\n }\n\n private async assertLibraryAssets(\n orgId: string,\n assetIds: (string | null | undefined)[],\n user = 'An activity',\n ): Promise<void> {\n const ids = assetIds.filter((id): id is string => typeof id === 'string');\n if (ids.length === 0) {\n return;\n }\n const library = new Set(await this.libraryAssets.libraryAssetsAmong(orgId, ids));\n const refused = ids.filter((id) => !library.has(id));\n if (refused.length > 0) {\n this.logger.warn('library assets refused', { orgId, assetIds: refused });\n throw new ConflictError(\n `${user} can only use ready files from the media library. Not available: ${refused.join(', ')}`,\n );\n }\n }\n\n async saveActivity(\n orgId: string,\n courseId: string,\n moduleId: string,\n input: SaveActivityInput,\n activityId?: string,\n ): Promise<Module[]> {\n await this.assertLibraryAssets(orgId, input.assetIds ?? []);\n const { modules, activity } = await this.uow.run(async ({ content, outbox }) => {\n if (activityId) {\n const existing = await content.findActivity(orgId, activityId);\n if (!existing || existing.moduleId !== moduleId || existing.courseId !== courseId) {\n this.logger.warn('activity update rejected — not found in module', {\n orgId,\n courseId,\n moduleId,\n activityId,\n });\n throw new NotFoundError('Activity', activityId);\n }\n } else {\n const module = await content.findModule(orgId, moduleId);\n if (!module || module.courseId !== courseId) {\n this.logger.warn('activity create rejected — module not found in course', {\n orgId,\n courseId,\n moduleId,\n });\n throw new NotFoundError('Module', moduleId);\n }\n }\n\n const { modules: all, activity: saved } = await content.saveActivity(\n orgId,\n courseId,\n moduleId,\n input,\n activityId,\n );\n await outbox.append([\n activityId\n ? contentEvents.activityUpdated.make({ orgId, data: saved })\n : contentEvents.activityCreated.make({ orgId, data: saved }),\n ]);\n return { modules: all, activity: saved };\n });\n this.logger.info(activityId ? 'activity updated' : 'activity created', {\n orgId,\n courseId,\n moduleId,\n activityId: activity.id,\n });\n return modules;\n }\n\n async deleteActivity(\n orgId: string,\n courseId: string,\n moduleId: string,\n activityId: string,\n ): Promise<Module[]> {\n const modules = await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const activity = await content.findActivity(orgId, activityId);\n if (!activity || activity.moduleId !== moduleId || activity.courseId !== courseId) {\n this.logger.warn('activity delete rejected — not found in module', {\n orgId,\n courseId,\n moduleId,\n activityId,\n });\n throw new NotFoundError('Activity', activityId);\n }\n const remaining = await content.deleteActivity(orgId, courseId, moduleId, activityId);\n await outbox.append([contentEvents.activityDeleted.make({ orgId, data: activity })]);\n return remaining;\n });\n this.logger.info('activity deleted', { orgId, courseId, moduleId, activityId });\n return modules;\n }\n\n // --- downloads ------------------------------------------------------------\n\n async listDownloads(orgId: string, query: ListDownloadsQuery): Promise<Page<DownloadView>> {\n return this.pageWithThumbnails(await this.repo.listDownloads(orgId, query));\n }\n\n async getDownload(orgId: string, id: string): Promise<DownloadView | null> {\n const download = await this.repo.getDownload(orgId, id);\n return download ? this.withThumbnail(download) : null;\n }\n\n async createDownload(orgId: string, input: CreateDownloadInput): Promise<DownloadView> {\n const download = await this.uow.run(async ({ content, outbox }) => {\n const created = await content.createDownload(orgId, input, slugify(input.title));\n await outbox.append([contentEvents.downloadCreated.make({ orgId, data: created })]);\n return created;\n });\n this.logger.info('download created', { orgId, downloadId: download.id, title: download.title });\n return this.withThumbnail(download);\n }\n\n async updateDownload(\n orgId: string,\n id: string,\n patch: UpdateDownloadInput,\n ): Promise<DownloadView> {\n await this.assertLibraryAssets(orgId, [patch.thumbnailAssetId], 'A download');\n const download = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.updateDownload(orgId, id, patch);\n if (!updated) {\n this.logger.warn('download update rejected — not found', { orgId, downloadId: id });\n throw new NotFoundError('Download', id);\n }\n await outbox.append([contentEvents.downloadUpdated.make({ orgId, data: updated })]);\n return updated;\n });\n this.logger.info('download updated', { orgId, downloadId: id, fields: Object.keys(patch) });\n return this.withThumbnail(download);\n }\n\n async removeDownload(orgId: string, id: string, actor: Actor): Promise<void> {\n await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const download = await content.getDownload(orgId, id);\n if (!download) {\n this.logger.warn('download delete rejected — not found', { orgId, downloadId: id });\n throw new NotFoundError('Download', id);\n }\n const linked = await content.spacesLinkingContent(orgId, id);\n const ok = await content.deleteDownload(orgId, id);\n if (!ok) {\n throw new NotFoundError('Download', id);\n }\n await outbox.append([\n contentEvents.downloadDeleted.make({ orgId, data: download }),\n ...(await this.spaceUpdates(content, orgId, linked, actor)),\n ]);\n });\n this.logger.info('download deleted', { orgId, downloadId: id });\n }\n\n // --- download asset links ------------------------------------------------\n\n async listDownloadAssets(orgId: string, downloadId: string): Promise<DownloadFile[]> {\n return this.downloadFiles(orgId, await this.repo.listDownloadAssets(orgId, downloadId));\n }\n\n async addDownloadAsset(\n orgId: string,\n downloadId: string,\n input: AddDownloadAssetInput,\n ): Promise<DownloadFile[]> {\n await this.assertLibraryAssets(orgId, [input.assetId], 'A download');\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.addDownloadAsset(orgId, downloadId, input);\n await outbox.append([\n contentEvents.downloadAssetAdded.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset added', { orgId, downloadId, assetId: input.assetId });\n return this.downloadFiles(orgId, assets);\n }\n\n async removeDownloadAsset(\n orgId: string,\n downloadId: string,\n assetId: string,\n ): Promise<DownloadFile[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.removeDownloadAsset(orgId, downloadId, assetId);\n await outbox.append([\n contentEvents.downloadAssetRemoved.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset removed', { orgId, downloadId, assetId });\n return this.downloadFiles(orgId, assets);\n }\n\n async renameDownloadAsset(\n orgId: string,\n downloadId: string,\n assetId: string,\n displayName: string | null,\n ): Promise<DownloadFile[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const assets = await content.renameDownloadAsset(orgId, downloadId, assetId, displayName);\n await outbox.append([\n contentEvents.downloadAssetRenamed.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.info('download asset renamed', { orgId, downloadId, assetId });\n return this.downloadFiles(orgId, assets);\n }\n\n /** The caller must send the COMPLETE ordered set — a partial list would\n * silently unlink whatever it omitted. */\n async reorderDownloadAssets(\n orgId: string,\n downloadId: string,\n assetIds: string[],\n ): Promise<DownloadFile[]> {\n const assets = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.listDownloadAssets(orgId, downloadId);\n const currentIds = new Set(current.map((a) => a.assetId));\n const requestedIds = new Set(assetIds);\n if (\n requestedIds.size !== assetIds.length ||\n requestedIds.size !== currentIds.size ||\n !assetIds.every((id) => currentIds.has(id))\n ) {\n this.logger.warn('download asset reorder rejected — id set mismatch', {\n orgId,\n downloadId,\n assetIds,\n currentIds: [...currentIds],\n });\n throw new ConflictError(\"Ordered asset ids does not match the download's current assets\");\n }\n const assets = await content.reorderDownloadAssets(orgId, downloadId, assetIds);\n await outbox.append([\n contentEvents.downloadAssetsReordered.make({ orgId, data: { downloadId, assets } }),\n ]);\n return assets;\n });\n this.logger.debug('download assets reordered', { orgId, downloadId });\n return this.downloadFiles(orgId, assets);\n }\n\n // --- bundles --------------------------------------------------------------\n\n listBundles(orgId: string, query: ListBundlesQuery): Promise<Page<Bundle>> {\n return this.repo.listBundles(orgId, query);\n }\n\n getBundle(orgId: string, id: string): Promise<Bundle | null> {\n return this.repo.findBundleById(orgId, id);\n }\n\n async createBundle(orgId: string, input: CreateBundleInput): Promise<Bundle> {\n const { bundle, items } = await this.uow.run(async ({ content, outbox }) => {\n // The repository writes the bundle and its initial items as one unit —\n // an unknown content id throws and nothing is created.\n const created = await content.createBundle(orgId, input);\n const initial = input.contentIds?.length\n ? await content.listBundleItems(orgId, created.id)\n : [];\n await outbox.append([\n contentEvents.bundleCreated.make({ orgId, data: created }),\n ...(initial.length > 0\n ? [\n contentEvents.bundleItemAdded.make({\n orgId,\n data: { bundleId: created.id, items: initial },\n }),\n ]\n : []),\n ]);\n return { bundle: created, items: initial };\n });\n this.logger.info('bundle created', {\n orgId,\n bundleId: bundle.id,\n name: bundle.name,\n itemCount: items.length,\n });\n return bundle;\n }\n\n async updateBundle(orgId: string, id: string, patch: UpdateBundleInput): Promise<Bundle> {\n const bundle = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.updateBundle(orgId, id, patch);\n if (!updated) {\n this.logger.warn('bundle update rejected — not found', { orgId, bundleId: id });\n throw new NotFoundError('Bundle', id);\n }\n await outbox.append([contentEvents.bundleUpdated.make({ orgId, data: updated })]);\n return updated;\n });\n this.logger.info('bundle updated', { orgId, bundleId: id, fields: Object.keys(patch) });\n return bundle;\n }\n\n async deleteBundle(orgId: string, id: string): Promise<void> {\n await this.uow.run(async ({ content, outbox }) => {\n // Snapshot before the delete — the event carries the last known state.\n const bundle = await content.findBundleById(orgId, id);\n if (!bundle) {\n this.logger.warn('bundle delete rejected — not found', { orgId, bundleId: id });\n throw new NotFoundError('Bundle', id);\n }\n const ok = await content.deleteBundle(orgId, id);\n if (!ok) {\n throw new NotFoundError('Bundle', id);\n }\n await outbox.append([contentEvents.bundleDeleted.make({ orgId, data: bundle })]);\n });\n this.logger.info('bundle deleted', { orgId, bundleId: id });\n }\n\n listBundleItems(orgId: string, bundleId: string): Promise<BundleItem[]> {\n return this.repo.listBundleItems(orgId, bundleId);\n }\n\n async addBundleItem(orgId: string, bundleId: string, contentId: string): Promise<BundleItem[]> {\n const items = await this.uow.run(async ({ content, outbox }) => {\n const all = await content.addBundleItem(orgId, bundleId, contentId);\n await outbox.append([\n contentEvents.bundleItemAdded.make({ orgId, data: { bundleId, items: all } }),\n ]);\n return all;\n });\n this.logger.info('bundle item added', { orgId, bundleId, contentId });\n return items;\n }\n\n async removeBundleItem(\n orgId: string,\n bundleId: string,\n contentId: string,\n ): Promise<BundleItem[]> {\n const items = await this.uow.run(async ({ content, outbox }) => {\n const all = await content.removeBundleItem(orgId, bundleId, contentId);\n await outbox.append([\n contentEvents.bundleItemRemoved.make({ orgId, data: { bundleId, items: all } }),\n ]);\n return all;\n });\n this.logger.info('bundle item removed', { orgId, bundleId, contentId });\n return items;\n }\n\n private async spaceUpdates(\n content: ContentRepository,\n orgId: string,\n spaceIds: string[],\n actor: Actor,\n ): Promise<NewDomainEvent[]> {\n const events: NewDomainEvent[] = [];\n for (const spaceId of spaceIds) {\n const space = await content.findSpace(orgId, spaceId);\n if (space) {\n events.push(\n contentEvents.spaceUpdated.make({ orgId, data: space, metadata: actorMetadata(actor) }),\n );\n }\n }\n return events;\n }\n\n private resolvedSpace(\n input: CreateSpaceInput | UpdateSpaceInput,\n current?: Space,\n ): {\n accessRule: Space['accessRule'];\n capacity: number | null;\n settings: SpaceSettings;\n } {\n const accessRule = input.accessRule ?? current?.accessRule ?? 'all_members';\n let capacity = input.capacity !== undefined ? input.capacity : (current?.capacity ?? null);\n if (accessRule === 'all_members') {\n if (input.capacity != null) {\n throw new InvalidInputError('An all-members space has no capacity');\n }\n capacity = null;\n }\n const settings = {\n ...(current?.settings ?? spaceSettingsDefaults),\n ...input.settings,\n };\n return { accessRule, capacity, settings };\n }\n\n async listCommunities(orgId: string, query: ListCommunitiesQuery): Promise<Page<CommunityView>> {\n return this.pageWithThumbnails(await this.repo.listCommunities(orgId, query));\n }\n\n async getCommunity(orgId: string, id: string): Promise<CommunityView | null> {\n const community = await this.repo.findCommunityById(orgId, id);\n return community ? this.withThumbnail(community) : null;\n }\n\n listPublishedCommunityIds(orgId: string): Promise<string[]> {\n return this.repo.listPublishedCommunityIds(orgId);\n }\n\n listCommunitiesById(orgId: string, ids: string[]): Promise<Community[]> {\n return ids.length ? this.repo.findCommunitiesByIds(orgId, ids) : Promise.resolve([]);\n }\n\n getSpace(orgId: string, spaceId: string): Promise<SpaceDetail | null> {\n return this.repo.findSpace(orgId, spaceId);\n }\n\n async getCommunitySpace(\n orgId: string,\n communityId: string,\n spaceId: string,\n ): Promise<SpaceDetail | null> {\n const space = await this.repo.findSpace(orgId, spaceId);\n return space?.communityId === communityId ? space : null;\n }\n\n async listSpaces(orgId: string, communityId: string): Promise<SpaceDetail[]> {\n if (!(await this.getCommunity(orgId, communityId))) {\n throw new NotFoundError('Community', communityId);\n }\n return this.repo.listSpaces(orgId, communityId);\n }\n\n async getDmSettings(orgId: string, communityId: string): Promise<DmSettings | null> {\n const community = await this.repo.findCommunityById(orgId, communityId);\n return community?.settings.dm ?? null;\n }\n\n async createCommunity(\n orgId: string,\n input: CreateCommunityInput,\n actor: Actor,\n ): Promise<CommunityView> {\n assertConfigurator(actor);\n const community = await this.uow.run(async ({ content, outbox }) => {\n const created = await content.createCommunity(orgId, input, slugify(input.title));\n await outbox.append([\n contentEvents.communityCreated.make({\n orgId,\n data: created,\n metadata: actorMetadata(actor),\n }),\n ]);\n return created;\n });\n this.logger.info('community created', {\n orgId,\n communityId: community.id,\n actorId: actor.id,\n });\n return this.withThumbnail(community);\n }\n\n async updateCommunity(\n orgId: string,\n id: string,\n patch: UpdateCommunityInput,\n actor: Actor,\n ): Promise<CommunityView> {\n assertConfigurator(actor);\n await this.assertLibraryAssets(orgId, [patch.thumbnailAssetId], 'A community');\n const community = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.updateCommunity(orgId, id, patch);\n if (!updated) {\n this.logger.warn('community update rejected — not found', {\n orgId,\n communityId: id,\n actorId: actor.id,\n });\n throw new NotFoundError('Community', id);\n }\n await outbox.append([\n contentEvents.communityUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('community updated', { orgId, communityId: id, actorId: actor.id });\n return this.withThumbnail(community);\n }\n\n publishCommunity(orgId: string, id: string, actor: Actor): Promise<CommunityView> {\n return this.updateCommunity(orgId, id, { status: 'published' }, actor);\n }\n\n unpublishCommunity(orgId: string, id: string, actor: Actor): Promise<CommunityView> {\n return this.updateCommunity(orgId, id, { status: 'draft' }, actor);\n }\n\n async deleteCommunity(orgId: string, id: string, actor: Actor): Promise<void> {\n assertConfigurator(actor);\n await this.uow.run(async ({ content, outbox }) => {\n const community = await content.findCommunityById(orgId, id);\n if (!community) {\n this.logger.warn('community delete rejected — not found', {\n orgId,\n communityId: id,\n actorId: actor.id,\n });\n throw new NotFoundError('Community', id);\n }\n const linked = await content.spacesLinkingContent(orgId, id);\n const ok = await content.deleteCommunity(orgId, id);\n if (!ok) {\n throw new NotFoundError('Community', id);\n }\n await content.deleteCommunitySettings(orgId, id);\n await outbox.append([\n contentEvents.communityDeleted.make({\n orgId,\n data: community,\n metadata: actorMetadata(actor),\n }),\n ...(await this.spaceUpdates(content, orgId, linked, actor)),\n ]);\n });\n this.logger.info('community deleted', { orgId, communityId: id, actorId: actor.id });\n }\n\n async patchDmSettings(\n orgId: string,\n id: string,\n patch: PatchDmSettingsInput,\n actor: Actor,\n ): Promise<CommunityView> {\n assertConfigurator(actor);\n const community = await this.uow.run(async ({ content, outbox }) => {\n const updated = await content.patchDmSettings(orgId, id, patch);\n if (!updated) {\n this.logger.warn('community dm settings patch rejected — not found', {\n orgId,\n communityId: id,\n actorId: actor.id,\n });\n throw new NotFoundError('Community', id);\n }\n await outbox.append([\n contentEvents.communityUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('community dm settings patched', {\n orgId,\n communityId: id,\n actorId: actor.id,\n });\n return this.withThumbnail(community);\n }\n\n async createSpace(\n orgId: string,\n communityId: string,\n input: CreateSpaceInput,\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const resolved = this.resolvedSpace(input);\n const space = await this.uow.run(async ({ content, outbox }) => {\n const community = await content.findCommunityById(orgId, communityId);\n if (!community) {\n this.logger.warn('space create rejected — community not found', {\n orgId,\n communityId,\n actorId: actor.id,\n });\n throw new NotFoundError('Community', communityId);\n }\n const created = await content.createSpace(orgId, communityId, {\n ...input,\n accessRule: resolved.accessRule,\n capacity: resolved.capacity,\n settings: resolved.settings,\n });\n await outbox.append([\n contentEvents.spaceCreated.make({\n orgId,\n data: created,\n metadata: actorMetadata(actor),\n }),\n ]);\n return created;\n });\n this.logger.info('space created', {\n orgId,\n communityId,\n spaceId: space.id,\n actorId: actor.id,\n });\n return space;\n }\n\n async updateSpace(\n orgId: string,\n communityId: string,\n spaceId: string,\n patch: UpdateSpaceInput,\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const space = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.findSpace(orgId, spaceId);\n if (!current || current.communityId !== communityId) {\n this.logger.warn('space update rejected — not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n const resolved = this.resolvedSpace(patch, current);\n const updated = await content.updateSpace(orgId, communityId, spaceId, {\n ...patch,\n accessRule: resolved.accessRule,\n capacity: resolved.capacity,\n settings: resolved.settings,\n });\n if (!updated) {\n throw new NotFoundError('Space', spaceId);\n }\n await outbox.append([\n contentEvents.spaceUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('space updated', { orgId, communityId, spaceId, actorId: actor.id });\n return space;\n }\n\n async deleteSpace(\n orgId: string,\n communityId: string,\n spaceId: string,\n actor: Actor,\n ): Promise<void> {\n assertConfigurator(actor);\n await this.uow.run(async ({ content, outbox }) => {\n const space = await content.findSpace(orgId, spaceId);\n if (!space || space.communityId !== communityId) {\n this.logger.warn('space delete rejected — not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n const ok = await content.deleteSpace(orgId, communityId, spaceId);\n if (!ok) {\n throw new NotFoundError('Space', spaceId);\n }\n await outbox.append([\n contentEvents.spaceDeleted.make({\n orgId,\n data: space,\n metadata: actorMetadata(actor),\n }),\n ]);\n });\n this.logger.info('space deleted', { orgId, communityId, spaceId, actorId: actor.id });\n }\n\n async reorderSpaces(\n orgId: string,\n communityId: string,\n orderedIds: string[],\n actor: Actor,\n ): Promise<SpaceDetail[]> {\n assertConfigurator(actor);\n const spaces = await this.uow.run(async ({ content, outbox }) => {\n const community = await content.findCommunityById(orgId, communityId);\n if (!community) {\n this.logger.warn('spaces reorder rejected — community not found', {\n orgId,\n communityId,\n actorId: actor.id,\n });\n throw new NotFoundError('Community', communityId);\n }\n const current = await content.listSpaces(orgId, communityId);\n if (\n !sameIdSet(\n current.map((space) => space.id),\n orderedIds,\n )\n ) {\n throw new ConflictError(\"Ordered space ids do not match the community's spaces\");\n }\n const reordered = await content.reorderSpaces(orgId, communityId, orderedIds);\n await outbox.append([\n contentEvents.spacesReordered.make({\n orgId,\n data: reordered,\n metadata: actorMetadata(actor),\n }),\n ]);\n return reordered;\n });\n this.logger.info('spaces reordered', { orgId, communityId, actorId: actor.id });\n return spaces;\n }\n\n async setSpaceTopics(\n orgId: string,\n communityId: string,\n spaceId: string,\n input: SetSpaceTopicsInput,\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const names = input.topics.map((topic) => topic.name);\n if (new Set(names).size !== names.length) {\n throw new InvalidInputError('A space topic name is already used');\n }\n const space = await this.uow.run(async ({ content, outbox }) => {\n const locked = await content.lockSpace(orgId, spaceId);\n if (!locked || locked.communityId !== communityId) {\n this.logger.warn('space topics rejected — space not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n const current = await content.findSpace(orgId, spaceId);\n if (!current) {\n throw new NotFoundError('Space', spaceId);\n }\n const kept = new Set(input.topics.flatMap((topic) => (topic.id ? [topic.id] : [])));\n const removed = current.topics\n .filter((topic) => !kept.has(topic.id))\n .map((topic) => topic.id);\n if (removed.length > 0 && (await content.topicsInUse(orgId, spaceId, removed)).length > 0) {\n throw new ConflictError('A topic used by a post cannot be removed');\n }\n const updated = await content.setSpaceTopics(orgId, spaceId, input);\n await outbox.append([\n contentEvents.spaceUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('space topics set', { orgId, communityId, spaceId, actorId: actor.id });\n return space;\n }\n\n async addSpaceLink(\n orgId: string,\n communityId: string,\n spaceId: string,\n contentId: string,\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const space = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.findSpace(orgId, spaceId);\n if (!current || current.communityId !== communityId) {\n this.logger.warn('space link add rejected — space not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n if (current.links.some((link) => link.contentId === contentId)) {\n throw new ConflictError('This space already links to that content');\n }\n const updated = await content.addSpaceLink(orgId, spaceId, contentId);\n await outbox.append([\n contentEvents.spaceUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('space link added', {\n orgId,\n communityId,\n spaceId,\n contentId,\n actorId: actor.id,\n });\n return space;\n }\n\n async removeSpaceLink(\n orgId: string,\n communityId: string,\n spaceId: string,\n linkId: string,\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const space = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.findSpace(orgId, spaceId);\n if (!current || current.communityId !== communityId) {\n this.logger.warn('space link remove rejected — space not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n const updated = await content.removeSpaceLink(orgId, spaceId, linkId);\n await outbox.append([\n contentEvents.spaceUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('space link removed', {\n orgId,\n communityId,\n spaceId,\n linkId,\n actorId: actor.id,\n });\n return space;\n }\n\n async reorderSpaceLinks(\n orgId: string,\n communityId: string,\n spaceId: string,\n orderedIds: string[],\n actor: Actor,\n ): Promise<SpaceDetail> {\n assertConfigurator(actor);\n const space = await this.uow.run(async ({ content, outbox }) => {\n const current = await content.findSpace(orgId, spaceId);\n if (!current || current.communityId !== communityId) {\n this.logger.warn('space links reorder rejected — space not found', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n throw new NotFoundError('Space', spaceId);\n }\n if (\n !sameIdSet(\n current.links.map((link) => link.id),\n orderedIds,\n )\n ) {\n throw new ConflictError(\"Ordered link ids do not match the space's links\");\n }\n const updated = await content.reorderSpaceLinks(orgId, spaceId, orderedIds);\n await outbox.append([\n contentEvents.spaceUpdated.make({\n orgId,\n data: updated,\n metadata: actorMetadata(actor),\n }),\n ]);\n return updated;\n });\n this.logger.info('space links reordered', {\n orgId,\n communityId,\n spaceId,\n actorId: actor.id,\n });\n return space;\n }\n}\n"],"mappings":";;;;;;AA8DA,SAAS,QAAQ,OAAuB;CACtC,OAAO,MACJ,YAAY,CAAC,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,QAAQ,YAAY,EAAE;AAC3B;AAWA,SAAS,cAAc,OAA0C;CAC/D,OAAO,EAAE,gBAAgB,MAAM,GAAG;AACpC;AAEA,SAAS,mBAAmB,OAAoB;CAC9C,IAAI,MAAM,SAAS,WAAW,MAAM,SAAS,SAC3C,MAAM,IAAI,eAAe,qDAAqD;AAElF;AAQA,SAAS,UAAU,SAAmB,WAA8B;CAClE,IAAI,QAAQ,WAAW,UAAU,QAC/B,OAAO;CAET,MAAM,OAAO,IAAI,IAAI,OAAO;CAC5B,OAAO,UAAU,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC,KAAK,IAAI,IAAI,SAAS,CAAC,CAAC,SAAS,UAAU;AACxF;AAEA,IAAa,iBAAb,MAEA;CACE;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,QAA8B;EACxC,KAAK,OAAO,OAAO;EACnB,KAAK,MAAM,OAAO;EAClB,KAAK,gBAAgB,OAAO;EAC5B,KAAK,QAAQ,OAAO;EACpB,KAAK,WAAW,OAAO;EACvB,KAAK,SAAS,OAAO,UAAU;CACjC;CAEA,cAA+C,MAA8C;EAC3F,OAAO;GACL,GAAG;GACH,cAAc,KAAK,mBAAmB,KAAK,SAAS,UAAU,KAAK,MAAM,KAAK,EAAE,IAAI;EACtF;CACF;CAEA,mBACE,MAC2C;EAC3C,OAAO;GAAE,GAAG;GAAM,MAAM,KAAK,KAAK,KAAK,QAAQ,KAAK,cAAc,GAAG,CAAC;EAAE;CAC1E;CAEA,MAAc,cAAc,OAAe,OAAiD;EAC1F,MAAM,QAAQ,MAAM,KAAK,MAAM,WAC7B,OACA,MAAM,KAAK,SAAS,KAAK,OAAO,CAClC;EACA,OAAO,MAAM,SAAS,SAAS;GAC7B,MAAM,OAAO,MAAM,KAAK;GACxB,OAAO,OACH,CAAC;IAAE,GAAG;IAAM,GAAG;IAAM,KAAK,KAAK,SAAS,aAAa,KAAK,YAAY,KAAK,OAAO;GAAE,CAAC,IACrF,CAAC;EACP,CAAC;CACH;CAEA,MAAM,YAAY,OAAe,OAAoD;EACnF,OAAO,KAAK,mBAAmB,MAAM,KAAK,KAAK,YAAY,OAAO,KAAK,CAAC;CAC1E;CAEA,MAAM,UAAU,OAAe,IAAwC;EACrE,MAAM,SAAS,MAAM,KAAK,KAAK,eAAe,OAAO,EAAE;EACvD,OAAO,SAAS,KAAK,cAAc,MAAM,IAAI;CAC/C;CAEA,MAAM,aAAa,OAAe,OAA+C;EAC/E,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,aAAa,OAAO,OAAO,QAAQ,MAAM,KAAK,CAAC;GAC7E,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAAC,CAAC;GAChF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU,OAAO;GAAI,OAAO,OAAO;EAAM,CAAC;EACtF,OAAO,KAAK,cAAc,MAAM;CAClC;CAEA,MAAM,aAAa,OAAe,IAAY,OAA+C;EAC3F,MAAM,KAAK,oBAAoB,OAAO,CAAC,MAAM,gBAAgB,GAAG,UAAU;EAC1E,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,aAAa,OAAO,IAAI,KAAK;GAC3D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GACA,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAAC,CAAC;GAChF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;GAAI,QAAQ,OAAO,KAAK,KAAK;EAAE,CAAC;EACtF,OAAO,KAAK,cAAc,MAAM;CAClC;CAEA,MAAM,oBACJ,OACA,IACA,OACyB;EACzB,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,eAAe,OAAO,EAAE;GACrD,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,KAAK,8CAA8C;KAAE;KAAO,UAAU;IAAG,CAAC;IACtF,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GACA,MAAM,WAAW,MAAM,QAAQ,oBAAoB,OAAO,IAAI,KAAK;GACnE,MAAM,OAAO,OAAO,CAClB,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;KAAE,GAAG;KAAQ;IAAS;GAAE,CAAC,CAC3E,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,2BAA2B;GAAE;GAAO,UAAU;GAAI;EAAM,CAAC;EAC1E,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,IAAY,OAA6B;EACzE,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhD,MAAM,SAAS,MAAM,QAAQ,eAAe,OAAO,EAAE;GACrD,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GACA,MAAM,SAAS,MAAM,QAAQ,qBAAqB,OAAO,EAAE;GAE3D,IAAI,CAAC,MADY,QAAQ,aAAa,OAAO,EAAE,GAE7C,MAAM,IAAI,cAAc,UAAU,EAAE;GAEtC,MAAM,OAAO,OAAO,CAClB,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,GACxD,GAAI,MAAM,KAAK,aAAa,SAAS,OAAO,QAAQ,KAAK,CAC3D,CAAC;EACH,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;EAAG,CAAC;CAC5D;CAIA,kBAAkB,OAAe,UAAqC;EACpE,OAAO,KAAK,KAAK,kBAAkB,OAAO,QAAQ;CACpD;CACA,qBAAqB,OAAe,UAAuC;EACzE,OAAO,KAAK,KAAK,wBAAwB,OAAO,QAAQ;CAC1D;CACA,MAAM,wBAAwB,OAAe,UAA2C;EACtF,MAAM,CAAC,YAAY,SAAS,MAAM,QAAQ,IAAI,CAC5C,KAAK,KAAK,wBAAwB,OAAO,QAAQ,GACjD,KAAK,KAAK,4BAA4B,OAAO,QAAQ,CACvD,CAAC;EACD,OAAO,WAAW,KAAK,cAAc;GACnC,GAAG;GACH,WAAW,OAAO,YAChB,MACG,QAAQ,SAAS,KAAK,eAAe,SAAS,EAAE,CAAC,CACjD,KAAK,SAAS,CAAC,KAAK,SAAS,KAAK,SAAS,cAAc,SAAS,IAAI,KAAK,OAAO,CAAC,CAAC,CACzF;EACF,EAAE;CACJ;CACA,yBAAyB,OAAe,UAA4C;EAClF,OAAO,KAAK,KAAK,4BAA4B,OAAO,QAAQ;CAC9D;CACA,YAAY,OAAe,YAA8C;EACvE,OAAO,KAAK,KAAK,aAAa,OAAO,UAAU;CACjD;CACA,UAAU,OAAe,UAA0C;EACjE,OAAO,KAAK,KAAK,WAAW,OAAO,QAAQ;CAC7C;CAEA,MAAM,eAAe,OAAe,UAAkB,YAAyC;EAC7F,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,YAAY,MAAM,QAAQ,eAAe,OAAO,UAAU,UAAU;GAC1E,MAAM,OAAO,OAAO,CAAC,cAAc,iBAAiB,KAAK;IAAE;IAAO,MAAM;GAAU,CAAC,CAAC,CAAC;GACrF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,qBAAqB;GACrC;GACA;GACA,WAAW,QAAQ,KAAK,MAAM,EAAE,EAAE;EACpC,CAAC;EACD,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,UAAkB,OAAkC;EACpF,MAAM,EAAE,SAAS,YAAY,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC7E,MAAM,MAAM,MAAM,QAAQ,aAAa,OAAO,UAAU,KAAK;GAE7D,MAAM,SAAS,IAAI,GAAG,EAAE;GACxB,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,+BAA+B;GAEjD,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;IAAE,SAAS;IAAK,SAAS;GAAO;EACzC,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU,UAAU,QAAQ;GAAI;EAAM,CAAC;EACnF,OAAO;CACT;CAEA,MAAM,aACJ,OACA,UACA,UACA,OACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,WAAW,MAAM,QAAQ,WAAW,OAAO,QAAQ;GACzD,IAAI,CAAC,YAAY,SAAS,aAAa,UAAU;IAC/C,KAAK,OAAO,KAAK,gDAAgD;KAC/D;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,UAAU,QAAQ;GAC5C;GACA,MAAM,MAAM,MAAM,QAAQ,aAAa,OAAO,UAAU,UAAU,KAAK;GACvE,MAAM,SAAS,IAAI,MAAM,MAAM,EAAE,OAAO,QAAQ;GAChD,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,UAAU,QAAQ;GAE5C,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU;GAAU;EAAM,CAAC;EACvE,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,UAAkB,UAAqC;EACvF,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhE,MAAM,SAAS,MAAM,QAAQ,WAAW,OAAO,QAAQ;GACvD,IAAI,CAAC,UAAU,OAAO,aAAa,UAAU;IAC3C,KAAK,OAAO,KAAK,gDAAgD;KAC/D;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,UAAU,QAAQ;GAC5C;GACA,MAAM,YAAY,MAAM,QAAQ,aAAa,OAAO,UAAU,QAAQ;GACtE,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GAC/E,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO;GAAU;EAAS,CAAC;EAChE,OAAO;CACT;CAEA,MAAM,kBACJ,OACA,UACA,UACA,YACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChE,MAAM,YAAY,MAAM,QAAQ,kBAAkB,OAAO,UAAU,UAAU,UAAU;GACvF,MAAM,SAAS,UAAU,MAAM,MAAM,EAAE,OAAO,QAAQ;GACtD,IAAI,CAAC,QACH,MAAM,IAAI,cAAc,UAAU,QAAQ;GAE5C,MAAM,OAAO,OAAO,CAAC,cAAc,oBAAoB,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;GACrF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,wBAAwB;GAAE;GAAO;GAAU;EAAS,CAAC;EACvE,OAAO;CACT;CAEA,MAAc,oBACZ,OACA,UACA,OAAO,eACQ;EACf,MAAM,MAAM,SAAS,QAAQ,OAAqB,OAAO,OAAO,QAAQ;EACxE,IAAI,IAAI,WAAW,GACjB;EAEF,MAAM,UAAU,IAAI,IAAI,MAAM,KAAK,cAAc,mBAAmB,OAAO,GAAG,CAAC;EAC/E,MAAM,UAAU,IAAI,QAAQ,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;EACnD,IAAI,QAAQ,SAAS,GAAG;GACtB,KAAK,OAAO,KAAK,0BAA0B;IAAE;IAAO,UAAU;GAAQ,CAAC;GACvE,MAAM,IAAI,cACR,GAAG,KAAK,mEAAmE,QAAQ,KAAK,IAAI,GAC9F;EACF;CACF;CAEA,MAAM,aACJ,OACA,UACA,UACA,OACA,YACmB;EACnB,MAAM,KAAK,oBAAoB,OAAO,MAAM,YAAY,CAAC,CAAC;EAC1D,MAAM,EAAE,SAAS,aAAa,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9E,IAAI,YAAY;IACd,MAAM,WAAW,MAAM,QAAQ,aAAa,OAAO,UAAU;IAC7D,IAAI,CAAC,YAAY,SAAS,aAAa,YAAY,SAAS,aAAa,UAAU;KACjF,KAAK,OAAO,KAAK,kDAAkD;MACjE;MACA;MACA;MACA;KACF,CAAC;KACD,MAAM,IAAI,cAAc,YAAY,UAAU;IAChD;GACF,OAAO;IACL,MAAM,SAAS,MAAM,QAAQ,WAAW,OAAO,QAAQ;IACvD,IAAI,CAAC,UAAU,OAAO,aAAa,UAAU;KAC3C,KAAK,OAAO,KAAK,yDAAyD;MACxE;MACA;MACA;KACF,CAAC;KACD,MAAM,IAAI,cAAc,UAAU,QAAQ;IAC5C;GACF;GAEA,MAAM,EAAE,SAAS,KAAK,UAAU,UAAU,MAAM,QAAQ,aACtD,OACA,UACA,UACA,OACA,UACF;GACA,MAAM,OAAO,OAAO,CAClB,aACI,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAM,CAAC,IACzD,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAM,CAAC,CAC/D,CAAC;GACD,OAAO;IAAE,SAAS;IAAK,UAAU;GAAM;EACzC,CAAC;EACD,KAAK,OAAO,KAAK,aAAa,qBAAqB,oBAAoB;GACrE;GACA;GACA;GACA,YAAY,SAAS;EACvB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,eACJ,OACA,UACA,UACA,YACmB;EACnB,MAAM,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhE,MAAM,WAAW,MAAM,QAAQ,aAAa,OAAO,UAAU;GAC7D,IAAI,CAAC,YAAY,SAAS,aAAa,YAAY,SAAS,aAAa,UAAU;IACjF,KAAK,OAAO,KAAK,kDAAkD;KACjE;KACA;KACA;KACA;IACF,CAAC;IACD,MAAM,IAAI,cAAc,YAAY,UAAU;GAChD;GACA,MAAM,YAAY,MAAM,QAAQ,eAAe,OAAO,UAAU,UAAU,UAAU;GACpF,MAAM,OAAO,OAAO,CAAC,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAS,CAAC,CAAC,CAAC;GACnF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO;GAAU;GAAU;EAAW,CAAC;EAC9E,OAAO;CACT;CAIA,MAAM,cAAc,OAAe,OAAwD;EACzF,OAAO,KAAK,mBAAmB,MAAM,KAAK,KAAK,cAAc,OAAO,KAAK,CAAC;CAC5E;CAEA,MAAM,YAAY,OAAe,IAA0C;EACzE,MAAM,WAAW,MAAM,KAAK,KAAK,YAAY,OAAO,EAAE;EACtD,OAAO,WAAW,KAAK,cAAc,QAAQ,IAAI;CACnD;CAEA,MAAM,eAAe,OAAe,OAAmD;EACrF,MAAM,WAAW,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GACjE,MAAM,UAAU,MAAM,QAAQ,eAAe,OAAO,OAAO,QAAQ,MAAM,KAAK,CAAC;GAC/E,MAAM,OAAO,OAAO,CAAC,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAAC,CAAC;GAClF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY,SAAS;GAAI,OAAO,SAAS;EAAM,CAAC;EAC9F,OAAO,KAAK,cAAc,QAAQ;CACpC;CAEA,MAAM,eACJ,OACA,IACA,OACuB;EACvB,MAAM,KAAK,oBAAoB,OAAO,CAAC,MAAM,gBAAgB,GAAG,YAAY;EAC5E,MAAM,WAAW,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GACjE,MAAM,UAAU,MAAM,QAAQ,eAAe,OAAO,IAAI,KAAK;GAC7D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,wCAAwC;KAAE;KAAO,YAAY;IAAG,CAAC;IAClF,MAAM,IAAI,cAAc,YAAY,EAAE;GACxC;GACA,MAAM,OAAO,OAAO,CAAC,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAAC,CAAC;GAClF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY;GAAI,QAAQ,OAAO,KAAK,KAAK;EAAE,CAAC;EAC1F,OAAO,KAAK,cAAc,QAAQ;CACpC;CAEA,MAAM,eAAe,OAAe,IAAY,OAA6B;EAC3E,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhD,MAAM,WAAW,MAAM,QAAQ,YAAY,OAAO,EAAE;GACpD,IAAI,CAAC,UAAU;IACb,KAAK,OAAO,KAAK,wCAAwC;KAAE;KAAO,YAAY;IAAG,CAAC;IAClF,MAAM,IAAI,cAAc,YAAY,EAAE;GACxC;GACA,MAAM,SAAS,MAAM,QAAQ,qBAAqB,OAAO,EAAE;GAE3D,IAAI,CAAC,MADY,QAAQ,eAAe,OAAO,EAAE,GAE/C,MAAM,IAAI,cAAc,YAAY,EAAE;GAExC,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;GAAS,CAAC,GAC5D,GAAI,MAAM,KAAK,aAAa,SAAS,OAAO,QAAQ,KAAK,CAC3D,CAAC;EACH,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO,YAAY;EAAG,CAAC;CAChE;CAIA,MAAM,mBAAmB,OAAe,YAA6C;EACnF,OAAO,KAAK,cAAc,OAAO,MAAM,KAAK,KAAK,mBAAmB,OAAO,UAAU,CAAC;CACxF;CAEA,MAAM,iBACJ,OACA,YACA,OACyB;EACzB,MAAM,KAAK,oBAAoB,OAAO,CAAC,MAAM,OAAO,GAAG,YAAY;EACnE,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,iBAAiB,OAAO,YAAY,KAAK;GACtE,MAAM,OAAO,OAAO,CAClB,cAAc,mBAAmB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CAC/E,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,wBAAwB;GAAE;GAAO;GAAY,SAAS,MAAM;EAAQ,CAAC;EACtF,OAAO,KAAK,cAAc,OAAO,MAAM;CACzC;CAEA,MAAM,oBACJ,OACA,YACA,SACyB;EACzB,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,oBAAoB,OAAO,YAAY,OAAO;GAC3E,MAAM,OAAO,OAAO,CAClB,cAAc,qBAAqB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACjF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,0BAA0B;GAAE;GAAO;GAAY;EAAQ,CAAC;EACzE,OAAO,KAAK,cAAc,OAAO,MAAM;CACzC;CAEA,MAAM,oBACJ,OACA,YACA,SACA,aACyB;EACzB,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,SAAS,MAAM,QAAQ,oBAAoB,OAAO,YAAY,SAAS,WAAW;GACxF,MAAM,OAAO,OAAO,CAClB,cAAc,qBAAqB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACjF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,0BAA0B;GAAE;GAAO;GAAY;EAAQ,CAAC;EACzE,OAAO,KAAK,cAAc,OAAO,MAAM;CACzC;;;CAIA,MAAM,sBACJ,OACA,YACA,UACyB;EACzB,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,mBAAmB,OAAO,UAAU;GAClE,MAAM,aAAa,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,OAAO,CAAC;GACxD,MAAM,eAAe,IAAI,IAAI,QAAQ;GACrC,IACE,aAAa,SAAS,SAAS,UAC/B,aAAa,SAAS,WAAW,QACjC,CAAC,SAAS,OAAO,OAAO,WAAW,IAAI,EAAE,CAAC,GAC1C;IACA,KAAK,OAAO,KAAK,qDAAqD;KACpE;KACA;KACA;KACA,YAAY,CAAC,GAAG,UAAU;IAC5B,CAAC;IACD,MAAM,IAAI,cAAc,gEAAgE;GAC1F;GACA,MAAM,SAAS,MAAM,QAAQ,sBAAsB,OAAO,YAAY,QAAQ;GAC9E,MAAM,OAAO,OAAO,CAClB,cAAc,wBAAwB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAY;IAAO;GAAE,CAAC,CACpF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,MAAM,6BAA6B;GAAE;GAAO;EAAW,CAAC;EACpE,OAAO,KAAK,cAAc,OAAO,MAAM;CACzC;CAIA,YAAY,OAAe,OAAgD;EACzE,OAAO,KAAK,KAAK,YAAY,OAAO,KAAK;CAC3C;CAEA,UAAU,OAAe,IAAoC;EAC3D,OAAO,KAAK,KAAK,eAAe,OAAO,EAAE;CAC3C;CAEA,MAAM,aAAa,OAAe,OAA2C;EAC3E,MAAM,EAAE,QAAQ,UAAU,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAG1E,MAAM,UAAU,MAAM,QAAQ,aAAa,OAAO,KAAK;GACvD,MAAM,UAAU,MAAM,YAAY,SAC9B,MAAM,QAAQ,gBAAgB,OAAO,QAAQ,EAAE,IAC/C,CAAC;GACL,MAAM,OAAO,OAAO,CAClB,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,GACzD,GAAI,QAAQ,SAAS,IACjB,CACE,cAAc,gBAAgB,KAAK;IACjC;IACA,MAAM;KAAE,UAAU,QAAQ;KAAI,OAAO;IAAQ;GAC/C,CAAC,CACH,IACA,CAAC,CACP,CAAC;GACD,OAAO;IAAE,QAAQ;IAAS,OAAO;GAAQ;EAC3C,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GACjC;GACA,UAAU,OAAO;GACjB,MAAM,OAAO;GACb,WAAW,MAAM;EACnB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,IAAY,OAA2C;EACvF,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC/D,MAAM,UAAU,MAAM,QAAQ,aAAa,OAAO,IAAI,KAAK;GAC3D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GACA,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAQ,CAAC,CAAC,CAAC;GAChF,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;GAAI,QAAQ,OAAO,KAAK,KAAK;EAAE,CAAC;EACtF,OAAO;CACT;CAEA,MAAM,aAAa,OAAe,IAA2B;EAC3D,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAEhD,MAAM,SAAS,MAAM,QAAQ,eAAe,OAAO,EAAE;GACrD,IAAI,CAAC,QAAQ;IACX,KAAK,OAAO,KAAK,sCAAsC;KAAE;KAAO,UAAU;IAAG,CAAC;IAC9E,MAAM,IAAI,cAAc,UAAU,EAAE;GACtC;GAEA,IAAI,CAAC,MADY,QAAQ,aAAa,OAAO,EAAE,GAE7C,MAAM,IAAI,cAAc,UAAU,EAAE;GAEtC,MAAM,OAAO,OAAO,CAAC,cAAc,cAAc,KAAK;IAAE;IAAO,MAAM;GAAO,CAAC,CAAC,CAAC;EACjF,CAAC;EACD,KAAK,OAAO,KAAK,kBAAkB;GAAE;GAAO,UAAU;EAAG,CAAC;CAC5D;CAEA,gBAAgB,OAAe,UAAyC;EACtE,OAAO,KAAK,KAAK,gBAAgB,OAAO,QAAQ;CAClD;CAEA,MAAM,cAAc,OAAe,UAAkB,WAA0C;EAC7F,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,MAAM,MAAM,QAAQ,cAAc,OAAO,UAAU,SAAS;GAClE,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAU,OAAO;IAAI;GAAE,CAAC,CAC9E,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,qBAAqB;GAAE;GAAO;GAAU;EAAU,CAAC;EACpE,OAAO;CACT;CAEA,MAAM,iBACJ,OACA,UACA,WACuB;EACvB,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,MAAM,MAAM,QAAQ,iBAAiB,OAAO,UAAU,SAAS;GACrE,MAAM,OAAO,OAAO,CAClB,cAAc,kBAAkB,KAAK;IAAE;IAAO,MAAM;KAAE;KAAU,OAAO;IAAI;GAAE,CAAC,CAChF,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,uBAAuB;GAAE;GAAO;GAAU;EAAU,CAAC;EACtE,OAAO;CACT;CAEA,MAAc,aACZ,SACA,OACA,UACA,OAC2B;EAC3B,MAAM,SAA2B,CAAC;EAClC,KAAK,MAAM,WAAW,UAAU;GAC9B,MAAM,QAAQ,MAAM,QAAQ,UAAU,OAAO,OAAO;GACpD,IAAI,OACF,OAAO,KACL,cAAc,aAAa,KAAK;IAAE;IAAO,MAAM;IAAO,UAAU,cAAc,KAAK;GAAE,CAAC,CACxF;EAEJ;EACA,OAAO;CACT;CAEA,cACE,OACA,SAKA;EACA,MAAM,aAAa,MAAM,cAAc,SAAS,cAAc;EAC9D,IAAI,WAAW,MAAM,aAAa,KAAA,IAAY,MAAM,WAAY,SAAS,YAAY;EACrF,IAAI,eAAe,eAAe;GAChC,IAAI,MAAM,YAAY,MACpB,MAAM,IAAI,kBAAkB,sCAAsC;GAEpE,WAAW;EACb;EACA,MAAM,WAAW;GACf,GAAI,SAAS,YAAY;GACzB,GAAG,MAAM;EACX;EACA,OAAO;GAAE;GAAY;GAAU;EAAS;CAC1C;CAEA,MAAM,gBAAgB,OAAe,OAA2D;EAC9F,OAAO,KAAK,mBAAmB,MAAM,KAAK,KAAK,gBAAgB,OAAO,KAAK,CAAC;CAC9E;CAEA,MAAM,aAAa,OAAe,IAA2C;EAC3E,MAAM,YAAY,MAAM,KAAK,KAAK,kBAAkB,OAAO,EAAE;EAC7D,OAAO,YAAY,KAAK,cAAc,SAAS,IAAI;CACrD;CAEA,0BAA0B,OAAkC;EAC1D,OAAO,KAAK,KAAK,0BAA0B,KAAK;CAClD;CAEA,oBAAoB,OAAe,KAAqC;EACtE,OAAO,IAAI,SAAS,KAAK,KAAK,qBAAqB,OAAO,GAAG,IAAI,QAAQ,QAAQ,CAAC,CAAC;CACrF;CAEA,SAAS,OAAe,SAA8C;EACpE,OAAO,KAAK,KAAK,UAAU,OAAO,OAAO;CAC3C;CAEA,MAAM,kBACJ,OACA,aACA,SAC6B;EAC7B,MAAM,QAAQ,MAAM,KAAK,KAAK,UAAU,OAAO,OAAO;EACtD,OAAO,OAAO,gBAAgB,cAAc,QAAQ;CACtD;CAEA,MAAM,WAAW,OAAe,aAA6C;EAC3E,IAAI,CAAE,MAAM,KAAK,aAAa,OAAO,WAAW,GAC9C,MAAM,IAAI,cAAc,aAAa,WAAW;EAElD,OAAO,KAAK,KAAK,WAAW,OAAO,WAAW;CAChD;CAEA,MAAM,cAAc,OAAe,aAAiD;EAElF,QAAO,MADiB,KAAK,KAAK,kBAAkB,OAAO,WAAW,EAAA,EACpD,SAAS,MAAM;CACnC;CAEA,MAAM,gBACJ,OACA,OACA,OACwB;EACxB,mBAAmB,KAAK;EACxB,MAAM,YAAY,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAClE,MAAM,UAAU,MAAM,QAAQ,gBAAgB,OAAO,OAAO,QAAQ,MAAM,KAAK,CAAC;GAChF,MAAM,OAAO,OAAO,CAClB,cAAc,iBAAiB,KAAK;IAClC;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,qBAAqB;GACpC;GACA,aAAa,UAAU;GACvB,SAAS,MAAM;EACjB,CAAC;EACD,OAAO,KAAK,cAAc,SAAS;CACrC;CAEA,MAAM,gBACJ,OACA,IACA,OACA,OACwB;EACxB,mBAAmB,KAAK;EACxB,MAAM,KAAK,oBAAoB,OAAO,CAAC,MAAM,gBAAgB,GAAG,aAAa;EAC7E,MAAM,YAAY,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAClE,MAAM,UAAU,MAAM,QAAQ,gBAAgB,OAAO,IAAI,KAAK;GAC9D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,yCAAyC;KACxD;KACA,aAAa;KACb,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,aAAa,EAAE;GACzC;GACA,MAAM,OAAO,OAAO,CAClB,cAAc,iBAAiB,KAAK;IAClC;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,qBAAqB;GAAE;GAAO,aAAa;GAAI,SAAS,MAAM;EAAG,CAAC;EACnF,OAAO,KAAK,cAAc,SAAS;CACrC;CAEA,iBAAiB,OAAe,IAAY,OAAsC;EAChF,OAAO,KAAK,gBAAgB,OAAO,IAAI,EAAE,QAAQ,YAAY,GAAG,KAAK;CACvE;CAEA,mBAAmB,OAAe,IAAY,OAAsC;EAClF,OAAO,KAAK,gBAAgB,OAAO,IAAI,EAAE,QAAQ,QAAQ,GAAG,KAAK;CACnE;CAEA,MAAM,gBAAgB,OAAe,IAAY,OAA6B;EAC5E,mBAAmB,KAAK;EACxB,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChD,MAAM,YAAY,MAAM,QAAQ,kBAAkB,OAAO,EAAE;GAC3D,IAAI,CAAC,WAAW;IACd,KAAK,OAAO,KAAK,yCAAyC;KACxD;KACA,aAAa;KACb,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,aAAa,EAAE;GACzC;GACA,MAAM,SAAS,MAAM,QAAQ,qBAAqB,OAAO,EAAE;GAE3D,IAAI,CAAC,MADY,QAAQ,gBAAgB,OAAO,EAAE,GAEhD,MAAM,IAAI,cAAc,aAAa,EAAE;GAEzC,MAAM,QAAQ,wBAAwB,OAAO,EAAE;GAC/C,MAAM,OAAO,OAAO,CAClB,cAAc,iBAAiB,KAAK;IAClC;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,GACD,GAAI,MAAM,KAAK,aAAa,SAAS,OAAO,QAAQ,KAAK,CAC3D,CAAC;EACH,CAAC;EACD,KAAK,OAAO,KAAK,qBAAqB;GAAE;GAAO,aAAa;GAAI,SAAS,MAAM;EAAG,CAAC;CACrF;CAEA,MAAM,gBACJ,OACA,IACA,OACA,OACwB;EACxB,mBAAmB,KAAK;EACxB,MAAM,YAAY,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAClE,MAAM,UAAU,MAAM,QAAQ,gBAAgB,OAAO,IAAI,KAAK;GAC9D,IAAI,CAAC,SAAS;IACZ,KAAK,OAAO,KAAK,oDAAoD;KACnE;KACA,aAAa;KACb,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,aAAa,EAAE;GACzC;GACA,MAAM,OAAO,OAAO,CAClB,cAAc,iBAAiB,KAAK;IAClC;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,iCAAiC;GAChD;GACA,aAAa;GACb,SAAS,MAAM;EACjB,CAAC;EACD,OAAO,KAAK,cAAc,SAAS;CACrC;CAEA,MAAM,YACJ,OACA,aACA,OACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,WAAW,KAAK,cAAc,KAAK;EACzC,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAE9D,IAAI,CAAC,MADmB,QAAQ,kBAAkB,OAAO,WAAW,GACpD;IACd,KAAK,OAAO,KAAK,+CAA+C;KAC9D;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,aAAa,WAAW;GAClD;GACA,MAAM,UAAU,MAAM,QAAQ,YAAY,OAAO,aAAa;IAC5D,GAAG;IACH,YAAY,SAAS;IACrB,UAAU,SAAS;IACnB,UAAU,SAAS;GACrB,CAAC;GACD,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,iBAAiB;GAChC;GACA;GACA,SAAS,MAAM;GACf,SAAS,MAAM;EACjB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,YACJ,OACA,aACA,SACA,OACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,OAAO;GACtD,IAAI,CAAC,WAAW,QAAQ,gBAAgB,aAAa;IACnD,KAAK,OAAO,KAAK,qCAAqC;KACpD;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GACA,MAAM,WAAW,KAAK,cAAc,OAAO,OAAO;GAClD,MAAM,UAAU,MAAM,QAAQ,YAAY,OAAO,aAAa,SAAS;IACrE,GAAG;IACH,YAAY,SAAS;IACrB,UAAU,SAAS;IACnB,UAAU,SAAS;GACrB,CAAC;GACD,IAAI,CAAC,SACH,MAAM,IAAI,cAAc,SAAS,OAAO;GAE1C,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,iBAAiB;GAAE;GAAO;GAAa;GAAS,SAAS,MAAM;EAAG,CAAC;EACpF,OAAO;CACT;CAEA,MAAM,YACJ,OACA,aACA,SACA,OACe;EACf,mBAAmB,KAAK;EACxB,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAChD,MAAM,QAAQ,MAAM,QAAQ,UAAU,OAAO,OAAO;GACpD,IAAI,CAAC,SAAS,MAAM,gBAAgB,aAAa;IAC/C,KAAK,OAAO,KAAK,qCAAqC;KACpD;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GAEA,IAAI,CAAC,MADY,QAAQ,YAAY,OAAO,aAAa,OAAO,GAE9D,MAAM,IAAI,cAAc,SAAS,OAAO;GAE1C,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;EACH,CAAC;EACD,KAAK,OAAO,KAAK,iBAAiB;GAAE;GAAO;GAAa;GAAS,SAAS,MAAM;EAAG,CAAC;CACtF;CAEA,MAAM,cACJ,OACA,aACA,YACA,OACwB;EACxB,mBAAmB,KAAK;EACxB,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAE/D,IAAI,CAAC,MADmB,QAAQ,kBAAkB,OAAO,WAAW,GACpD;IACd,KAAK,OAAO,KAAK,iDAAiD;KAChE;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,aAAa,WAAW;GAClD;GAEA,IACE,CAAC,WACC,MAHkB,QAAQ,WAAW,OAAO,WAAW,EAAA,CAG/C,KAAK,UAAU,MAAM,EAAE,GAC/B,UACF,GAEA,MAAM,IAAI,cAAc,uDAAuD;GAEjF,MAAM,YAAY,MAAM,QAAQ,cAAc,OAAO,aAAa,UAAU;GAC5E,MAAM,OAAO,OAAO,CAClB,cAAc,gBAAgB,KAAK;IACjC;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO;GAAa,SAAS,MAAM;EAAG,CAAC;EAC9E,OAAO;CACT;CAEA,MAAM,eACJ,OACA,aACA,SACA,OACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,QAAQ,MAAM,OAAO,KAAK,UAAU,MAAM,IAAI;EACpD,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,SAAS,MAAM,QAChC,MAAM,IAAI,kBAAkB,oCAAoC;EAElE,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,SAAS,MAAM,QAAQ,UAAU,OAAO,OAAO;GACrD,IAAI,CAAC,UAAU,OAAO,gBAAgB,aAAa;IACjD,KAAK,OAAO,KAAK,2CAA2C;KAC1D;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GACA,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,OAAO;GACtD,IAAI,CAAC,SACH,MAAM,IAAI,cAAc,SAAS,OAAO;GAE1C,MAAM,OAAO,IAAI,IAAI,MAAM,OAAO,SAAS,UAAW,MAAM,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAE,CAAC;GAClF,MAAM,UAAU,QAAQ,OACrB,QAAQ,UAAU,CAAC,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC,CACtC,KAAK,UAAU,MAAM,EAAE;GAC1B,IAAI,QAAQ,SAAS,MAAM,MAAM,QAAQ,YAAY,OAAO,SAAS,OAAO,EAAA,CAAG,SAAS,GACtF,MAAM,IAAI,cAAc,0CAA0C;GAEpE,MAAM,UAAU,MAAM,QAAQ,eAAe,OAAO,SAAS,KAAK;GAClE,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GAAE;GAAO;GAAa;GAAS,SAAS,MAAM;EAAG,CAAC;EACvF,OAAO;CACT;CAEA,MAAM,aACJ,OACA,aACA,SACA,WACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,OAAO;GACtD,IAAI,CAAC,WAAW,QAAQ,gBAAgB,aAAa;IACnD,KAAK,OAAO,KAAK,6CAA6C;KAC5D;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GACA,IAAI,QAAQ,MAAM,MAAM,SAAS,KAAK,cAAc,SAAS,GAC3D,MAAM,IAAI,cAAc,0CAA0C;GAEpE,MAAM,UAAU,MAAM,QAAQ,aAAa,OAAO,SAAS,SAAS;GACpE,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,oBAAoB;GACnC;GACA;GACA;GACA;GACA,SAAS,MAAM;EACjB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,gBACJ,OACA,aACA,SACA,QACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,OAAO;GACtD,IAAI,CAAC,WAAW,QAAQ,gBAAgB,aAAa;IACnD,KAAK,OAAO,KAAK,gDAAgD;KAC/D;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GACA,MAAM,UAAU,MAAM,QAAQ,gBAAgB,OAAO,SAAS,MAAM;GACpE,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,sBAAsB;GACrC;GACA;GACA;GACA;GACA,SAAS,MAAM;EACjB,CAAC;EACD,OAAO;CACT;CAEA,MAAM,kBACJ,OACA,aACA,SACA,YACA,OACsB;EACtB,mBAAmB,KAAK;EACxB,MAAM,QAAQ,MAAM,KAAK,IAAI,IAAI,OAAO,EAAE,SAAS,aAAa;GAC9D,MAAM,UAAU,MAAM,QAAQ,UAAU,OAAO,OAAO;GACtD,IAAI,CAAC,WAAW,QAAQ,gBAAgB,aAAa;IACnD,KAAK,OAAO,KAAK,kDAAkD;KACjE;KACA;KACA;KACA,SAAS,MAAM;IACjB,CAAC;IACD,MAAM,IAAI,cAAc,SAAS,OAAO;GAC1C;GACA,IACE,CAAC,UACC,QAAQ,MAAM,KAAK,SAAS,KAAK,EAAE,GACnC,UACF,GAEA,MAAM,IAAI,cAAc,iDAAiD;GAE3E,MAAM,UAAU,MAAM,QAAQ,kBAAkB,OAAO,SAAS,UAAU;GAC1E,MAAM,OAAO,OAAO,CAClB,cAAc,aAAa,KAAK;IAC9B;IACA,MAAM;IACN,UAAU,cAAc,KAAK;GAC/B,CAAC,CACH,CAAC;GACD,OAAO;EACT,CAAC;EACD,KAAK,OAAO,KAAK,yBAAyB;GACxC;GACA;GACA;GACA,SAAS,MAAM;EACjB,CAAC;EACD,OAAO;CACT;AACF"}
|
package/dist/content/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Page } from "../types/shared.js";
|
|
2
|
-
import { AddDownloadAssetInput, CreateCourseInput, CreateDownloadInput, ListCoursesQuery, ListDownloadsQuery, ReorderDownloadAssetsInput, UpdateCourseInput, UpdateDownloadInput } from "../types/schemas/content.js";
|
|
2
|
+
import { AddDownloadAssetInput, CreateBundleInput, CreateCommunityInput, CreateCourseInput, CreateDownloadInput, CreateSpaceInput, ListBundlesQuery, ListCommunitiesQuery, ListCoursesQuery, ListDownloadsQuery, PatchDmSettingsInput, ReorderDownloadAssetsInput, SetSpaceTopicsInput, UpdateBundleInput, UpdateCommunityInput, UpdateCourseInput, UpdateDownloadInput, UpdateSpaceInput } from "../types/schemas/content.js";
|
|
3
3
|
import "../types/index.js";
|
|
4
|
-
export type { AddDownloadAssetInput, CreateCourseInput, CreateDownloadInput, ListCoursesQuery, ListDownloadsQuery, Page, ReorderDownloadAssetsInput, UpdateCourseInput, UpdateDownloadInput };
|
|
4
|
+
export type { AddDownloadAssetInput, CreateBundleInput, CreateCommunityInput, CreateCourseInput, CreateDownloadInput, CreateSpaceInput, ListBundlesQuery, ListCommunitiesQuery, ListCoursesQuery, ListDownloadsQuery, Page, PatchDmSettingsInput, ReorderDownloadAssetsInput, SetSpaceTopicsInput, UpdateBundleInput, UpdateCommunityInput, UpdateCourseInput, UpdateDownloadInput, UpdateSpaceInput };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CommentAuthor } from "../types/discussion.js";
|
|
2
|
+
import { FileUrls } from "../assets/file-urls.js";
|
|
3
|
+
import "../assets/index.js";
|
|
4
|
+
import "./model.js";
|
|
5
|
+
import { AuthorRecord } from "./ports.js";
|
|
6
|
+
//#region src/discussion/authors.d.ts
|
|
7
|
+
declare function authorView(orgId: string, record: AuthorRecord, fileUrls: FileUrls | null): CommentAuthor;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { authorView };
|
|
10
|
+
//# sourceMappingURL=authors.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//#region src/discussion/authors.ts
|
|
2
|
+
function imageOf(orgId, record) {
|
|
3
|
+
return record.imageAssetOrgId === orgId ? record.imageAssetId : null;
|
|
4
|
+
}
|
|
5
|
+
function authorView(orgId, record, fileUrls) {
|
|
6
|
+
const fullName = [record.firstName, record.lastName].filter(Boolean).join(" ");
|
|
7
|
+
const imageAssetId = imageOf(orgId, record);
|
|
8
|
+
return {
|
|
9
|
+
id: record.id,
|
|
10
|
+
firstName: record.firstName,
|
|
11
|
+
lastName: record.lastName,
|
|
12
|
+
displayName: record.displayName?.trim() || fullName || null,
|
|
13
|
+
headline: record.headline,
|
|
14
|
+
image: record.image,
|
|
15
|
+
imageAssetId,
|
|
16
|
+
imageUrl: imageAssetId && fileUrls ? fileUrls.personImage(record.id) : null,
|
|
17
|
+
role: record.role
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { authorView };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=authors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authors.js","names":[],"sources":["../../src/discussion/authors.ts"],"sourcesContent":["import type { FileUrls } from '../assets/index.js';\nimport type { CommentAuthor } from './model.js';\nimport type { AuthorRecord } from './ports.js';\n\nfunction imageOf(orgId: string, record: AuthorRecord): string | null {\n return record.imageAssetOrgId === orgId ? record.imageAssetId : null;\n}\n\nexport function authorView(\n orgId: string,\n record: AuthorRecord,\n fileUrls: FileUrls | null,\n): CommentAuthor {\n const fullName = [record.firstName, record.lastName].filter(Boolean).join(' ');\n const imageAssetId = imageOf(orgId, record);\n return {\n id: record.id,\n firstName: record.firstName,\n lastName: record.lastName,\n displayName: record.displayName?.trim() || fullName || null,\n headline: record.headline,\n image: record.image,\n imageAssetId,\n imageUrl: imageAssetId && fileUrls ? fileUrls.personImage(record.id) : null,\n role: record.role,\n };\n}\n"],"mappings":";AAIA,SAAS,QAAQ,OAAe,QAAqC;CACnE,OAAO,OAAO,oBAAoB,QAAQ,OAAO,eAAe;AAClE;AAEA,SAAgB,WACd,OACA,QACA,UACe;CACf,MAAM,WAAW,CAAC,OAAO,WAAW,OAAO,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;CAC7E,MAAM,eAAe,QAAQ,OAAO,MAAM;CAC1C,OAAO;EACL,IAAI,OAAO;EACX,WAAW,OAAO;EAClB,UAAU,OAAO;EACjB,aAAa,OAAO,aAAa,KAAK,KAAK,YAAY;EACvD,UAAU,OAAO;EACjB,OAAO,OAAO;EACd;EACA,UAAU,gBAAgB,WAAW,SAAS,YAAY,OAAO,EAAE,IAAI;EACvE,MAAM,OAAO;CACf;AACF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { Page } from "../types/shared.js";
|
|
2
|
+
import { Logger } from "../types/ports.js";
|
|
3
|
+
import { Chat, ChatUser, MessageFlag, MessageFlagResolution, MessageView, ReactionEmoji } from "../types/schemas/discussion.js";
|
|
4
|
+
import "../types/index.js";
|
|
5
|
+
import "../shared/ports.js";
|
|
6
|
+
import { FileUrls } from "../assets/file-urls.js";
|
|
7
|
+
import { AssetFiles, MemberImageReader } from "../assets/ports.js";
|
|
8
|
+
import "../assets/index.js";
|
|
9
|
+
import { Actor } from "../shared/actor.js";
|
|
10
|
+
import { CommunityReader } from "../content/ports.js";
|
|
11
|
+
import "../content/index.js";
|
|
12
|
+
import { CommunityAccessReader } from "../entitlements/ports.js";
|
|
13
|
+
import "../entitlements/index.js";
|
|
14
|
+
import { AuthorProfileReader, AuthorRoleReader, ChatListItem, ChatRepository, ChatService, ChatUnitOfWork, MessageQueue, MessageReactions, PageQuery, SendMessageInput, StartDirectInput, StartGroupInput } from "./ports.js";
|
|
15
|
+
//#region src/discussion/chats.d.ts
|
|
16
|
+
type ChatServiceParams = {
|
|
17
|
+
repo: ChatRepository;
|
|
18
|
+
access: CommunityAccessReader;
|
|
19
|
+
content: CommunityReader;
|
|
20
|
+
authors: AuthorRoleReader;
|
|
21
|
+
profiles: AuthorProfileReader;
|
|
22
|
+
images: MemberImageReader & Pick<AssetFiles, 'signFile'>;
|
|
23
|
+
fileUrls: FileUrls;
|
|
24
|
+
uow: ChatUnitOfWork;
|
|
25
|
+
logger?: Logger;
|
|
26
|
+
};
|
|
27
|
+
declare class ChatServiceImpl implements ChatService {
|
|
28
|
+
private readonly repo;
|
|
29
|
+
private readonly access;
|
|
30
|
+
private readonly content;
|
|
31
|
+
private readonly authors;
|
|
32
|
+
private readonly profiles;
|
|
33
|
+
private readonly images;
|
|
34
|
+
private readonly fileUrls;
|
|
35
|
+
private readonly uow;
|
|
36
|
+
private readonly logger;
|
|
37
|
+
constructor(params: ChatServiceParams);
|
|
38
|
+
startDirect(orgId: string, actor: Actor, input: StartDirectInput): Promise<Chat>;
|
|
39
|
+
startGroup(orgId: string, actor: Actor, input: StartGroupInput): Promise<Chat>;
|
|
40
|
+
addParticipant(orgId: string, actor: Actor, chatId: string, orgUserId: string): Promise<Chat>;
|
|
41
|
+
leave(orgId: string, actor: Actor, chatId: string): Promise<Chat>;
|
|
42
|
+
accept(orgId: string, actor: Actor, chatId: string): Promise<Chat>;
|
|
43
|
+
send(orgId: string, actor: Actor, chatId: string, input: SendMessageInput): Promise<MessageView>;
|
|
44
|
+
editMessage(orgId: string, actor: Actor, messageId: string, body: string): Promise<MessageView>;
|
|
45
|
+
deleteMessage(orgId: string, actor: Actor, messageId: string): Promise<MessageView>;
|
|
46
|
+
setReaction(orgId: string, actor: Actor, messageId: string, emoji: ReactionEmoji | null): Promise<MessageReactions>;
|
|
47
|
+
markRead(orgId: string, actor: Actor, chatId: string, messageId: string): Promise<void>;
|
|
48
|
+
mute(orgId: string, actor: Actor, chatId: string, until?: Date): Promise<void>;
|
|
49
|
+
unmute(orgId: string, actor: Actor, chatId: string): Promise<void>;
|
|
50
|
+
block(orgId: string, actor: Actor, communityId: string, orgUserId: string): Promise<void>;
|
|
51
|
+
unblock(orgId: string, actor: Actor, communityId: string, orgUserId: string): Promise<void>;
|
|
52
|
+
flagMessage(orgId: string, actor: Actor, messageId: string, reason: string): Promise<MessageFlag>;
|
|
53
|
+
resolveMessageFlags(orgId: string, actor: Actor, messageId: string, resolution: Extract<MessageFlagResolution, 'dismissed'>, communityId?: string): Promise<void>;
|
|
54
|
+
lock(orgId: string, actor: Actor, chatId: string, communityId?: string): Promise<Chat>;
|
|
55
|
+
unlock(orgId: string, actor: Actor, chatId: string, communityId?: string): Promise<Chat>;
|
|
56
|
+
listChats(orgId: string, actor: Actor, communityId: string, query: PageQuery): Promise<Page<ChatListItem>>;
|
|
57
|
+
messages(orgId: string, actor: Actor, chatId: string, query: {
|
|
58
|
+
page: number;
|
|
59
|
+
pageSize: number;
|
|
60
|
+
}): Promise<Page<MessageView>>;
|
|
61
|
+
attachmentFile(orgId: string, actor: Actor, chatId: string, messageId: string, assetId: string): Promise<string | null>;
|
|
62
|
+
messageQueue(orgId: string, actor: Actor, communityId: string): Promise<MessageQueue>;
|
|
63
|
+
chatSummary(orgId: string, chatId: string): Promise<{
|
|
64
|
+
chat: Chat;
|
|
65
|
+
participants: ChatUser[];
|
|
66
|
+
} | null>;
|
|
67
|
+
titlesFor(orgId: string, actor: Actor, chatIds: string[]): Promise<Record<string, string>>;
|
|
68
|
+
latestMessageBody(orgId: string, chatId: string): Promise<string | null>;
|
|
69
|
+
isBlocked(orgId: string, communityId: string, a: string, b: string): Promise<boolean>;
|
|
70
|
+
private setLock;
|
|
71
|
+
private requireSettings;
|
|
72
|
+
private requireActor;
|
|
73
|
+
private requirePerson;
|
|
74
|
+
private personRole;
|
|
75
|
+
private personRoles;
|
|
76
|
+
private assertMaySend;
|
|
77
|
+
private writeMessage;
|
|
78
|
+
private assertMayMessage;
|
|
79
|
+
private assertGroup;
|
|
80
|
+
private mayMessage;
|
|
81
|
+
private requireActive;
|
|
82
|
+
private assertActive;
|
|
83
|
+
private requireOwnedImages;
|
|
84
|
+
private requireWritableChat;
|
|
85
|
+
private pendingCreator;
|
|
86
|
+
private mustChat;
|
|
87
|
+
private mustMessage;
|
|
88
|
+
private mustUpdate;
|
|
89
|
+
private memberRow;
|
|
90
|
+
private newMessage;
|
|
91
|
+
private activeIds;
|
|
92
|
+
private chatData;
|
|
93
|
+
private meta;
|
|
94
|
+
private createdEvent;
|
|
95
|
+
private updatedEvent;
|
|
96
|
+
private addedEvent;
|
|
97
|
+
private sentEvent;
|
|
98
|
+
private viewOf;
|
|
99
|
+
private withSenders;
|
|
100
|
+
private present;
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { ChatServiceImpl, ChatServiceParams };
|
|
104
|
+
//# sourceMappingURL=chats.d.ts.map
|