@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.
Files changed (249) hide show
  1. package/dist/assets/events.d.ts +90 -9
  2. package/dist/assets/events.js +19 -3
  3. package/dist/assets/events.js.map +1 -1
  4. package/dist/assets/file-urls.d.ts +20 -0
  5. package/dist/assets/file-urls.js +25 -0
  6. package/dist/assets/file-urls.js.map +1 -0
  7. package/dist/assets/index.d.ts +5 -4
  8. package/dist/assets/index.js +3 -2
  9. package/dist/assets/model.d.ts +2 -2
  10. package/dist/assets/ports.d.ts +45 -15
  11. package/dist/assets/service.d.ts +39 -7
  12. package/dist/assets/service.js +292 -37
  13. package/dist/assets/service.js.map +1 -1
  14. package/dist/automations/actions.d.ts +12 -15
  15. package/dist/automations/actions.js +188 -30
  16. package/dist/automations/actions.js.map +1 -1
  17. package/dist/automations/catalog.d.ts +5 -1
  18. package/dist/automations/catalog.js +514 -197
  19. package/dist/automations/catalog.js.map +1 -1
  20. package/dist/automations/community-derivations.d.ts +14 -0
  21. package/dist/automations/community-derivations.js +439 -0
  22. package/dist/automations/community-derivations.js.map +1 -0
  23. package/dist/automations/community-mail.d.ts +112 -0
  24. package/dist/automations/community-mail.js +90 -0
  25. package/dist/automations/community-mail.js.map +1 -0
  26. package/dist/automations/community-notifications.d.ts +16 -0
  27. package/dist/automations/community-notifications.js +84 -0
  28. package/dist/automations/community-notifications.js.map +1 -0
  29. package/dist/automations/events.d.ts +74 -24
  30. package/dist/automations/events.js +5 -5
  31. package/dist/automations/events.js.map +1 -1
  32. package/dist/automations/index.d.ts +7 -5
  33. package/dist/automations/index.js +3 -2
  34. package/dist/automations/model.d.ts +20 -3
  35. package/dist/automations/model.js +36 -3
  36. package/dist/automations/model.js.map +1 -1
  37. package/dist/automations/ports.d.ts +27 -8
  38. package/dist/automations/schedule.d.ts +6 -0
  39. package/dist/automations/schedule.js +41 -0
  40. package/dist/automations/schedule.js.map +1 -0
  41. package/dist/automations/seeds.d.ts +17 -0
  42. package/dist/automations/seeds.js +235 -0
  43. package/dist/automations/seeds.js.map +1 -0
  44. package/dist/automations/service.d.ts +41 -6
  45. package/dist/automations/service.js +542 -59
  46. package/dist/automations/service.js.map +1 -1
  47. package/dist/automations/types.d.ts +2 -2
  48. package/dist/automations/webhook-signing.d.ts +7 -0
  49. package/dist/automations/webhook-signing.js +22 -0
  50. package/dist/automations/webhook-signing.js.map +1 -0
  51. package/dist/content/events.d.ts +1013 -25
  52. package/dist/content/events.js +168 -19
  53. package/dist/content/events.js.map +1 -1
  54. package/dist/content/index.d.ts +5 -5
  55. package/dist/content/index.js +2 -2
  56. package/dist/content/model.d.ts +2 -2
  57. package/dist/content/ports.d.ts +109 -25
  58. package/dist/content/service.d.ts +68 -23
  59. package/dist/content/service.js +647 -60
  60. package/dist/content/service.js.map +1 -1
  61. package/dist/content/types.d.ts +2 -2
  62. package/dist/discussion/authors.d.ts +10 -0
  63. package/dist/discussion/authors.js +23 -0
  64. package/dist/discussion/authors.js.map +1 -0
  65. package/dist/discussion/chats.d.ts +104 -0
  66. package/dist/discussion/chats.js +798 -0
  67. package/dist/discussion/chats.js.map +1 -0
  68. package/dist/discussion/events.d.ts +633 -14
  69. package/dist/discussion/events.js +134 -5
  70. package/dist/discussion/events.js.map +1 -1
  71. package/dist/discussion/index.d.ts +7 -3
  72. package/dist/discussion/index.js +4 -1
  73. package/dist/discussion/model.d.ts +1 -2
  74. package/dist/discussion/ports.d.ts +288 -27
  75. package/dist/discussion/ports.js +6 -1
  76. package/dist/discussion/ports.js.map +1 -0
  77. package/dist/discussion/posts.d.ts +103 -0
  78. package/dist/discussion/posts.js +723 -0
  79. package/dist/discussion/posts.js.map +1 -0
  80. package/dist/discussion/service.d.ts +33 -11
  81. package/dist/discussion/service.js +297 -81
  82. package/dist/discussion/service.js.map +1 -1
  83. package/dist/entitlements/events.d.ts +264 -13
  84. package/dist/entitlements/events.js +49 -5
  85. package/dist/entitlements/events.js.map +1 -1
  86. package/dist/entitlements/index.d.ts +5 -4
  87. package/dist/entitlements/index.js +2 -1
  88. package/dist/entitlements/model.d.ts +3 -2
  89. package/dist/entitlements/ports.d.ts +124 -11
  90. package/dist/entitlements/rules.d.ts +12 -0
  91. package/dist/entitlements/rules.js +17 -0
  92. package/dist/entitlements/rules.js.map +1 -0
  93. package/dist/entitlements/service.d.ts +54 -3
  94. package/dist/entitlements/service.js +473 -2
  95. package/dist/entitlements/service.js.map +1 -1
  96. package/dist/identity/access.d.ts +6 -0
  97. package/dist/identity/access.js +7 -0
  98. package/dist/identity/access.js.map +1 -0
  99. package/dist/identity/events.d.ts +17 -3
  100. package/dist/identity/events.js +12 -2
  101. package/dist/identity/events.js.map +1 -1
  102. package/dist/identity/index.d.ts +6 -4
  103. package/dist/identity/index.js +3 -1
  104. package/dist/identity/model.d.ts +2 -1
  105. package/dist/identity/notifications.d.ts +27 -0
  106. package/dist/identity/notifications.js +101 -0
  107. package/dist/identity/notifications.js.map +1 -0
  108. package/dist/identity/ports.d.ts +76 -3
  109. package/dist/identity/service.d.ts +17 -3
  110. package/dist/identity/service.js +73 -5
  111. package/dist/identity/service.js.map +1 -1
  112. package/dist/integrations/events.d.ts +27 -3
  113. package/dist/integrations/events.js +15 -3
  114. package/dist/integrations/events.js.map +1 -1
  115. package/dist/integrations/model.js +1 -1
  116. package/dist/integrations/model.js.map +1 -1
  117. package/dist/integrations/service.js +2 -2
  118. package/dist/integrations/service.js.map +1 -1
  119. package/dist/organizations/access-scopes.d.ts +19 -0
  120. package/dist/organizations/access-scopes.js +89 -0
  121. package/dist/organizations/access-scopes.js.map +1 -0
  122. package/dist/organizations/events.d.ts +234 -25
  123. package/dist/organizations/events.js +58 -9
  124. package/dist/organizations/events.js.map +1 -1
  125. package/dist/organizations/index.d.ts +8 -7
  126. package/dist/organizations/index.js +4 -3
  127. package/dist/organizations/members.d.ts +8 -5
  128. package/dist/organizations/members.js.map +1 -1
  129. package/dist/organizations/ports.d.ts +20 -21
  130. package/dist/organizations/roles.d.ts +6 -10
  131. package/dist/organizations/roles.js +19 -7
  132. package/dist/organizations/roles.js.map +1 -1
  133. package/dist/organizations/service.d.ts +28 -14
  134. package/dist/organizations/service.js +274 -105
  135. package/dist/organizations/service.js.map +1 -1
  136. package/dist/organizations/types.d.ts +2 -11
  137. package/dist/progress/events.d.ts +34 -2
  138. package/dist/progress/events.js +15 -2
  139. package/dist/progress/events.js.map +1 -1
  140. package/dist/progress/index.d.ts +2 -2
  141. package/dist/progress/ports.d.ts +6 -1
  142. package/dist/progress/service.d.ts +5 -3
  143. package/dist/progress/service.js +9 -3
  144. package/dist/progress/service.js.map +1 -1
  145. package/dist/reporting/admin/index.d.ts +4 -0
  146. package/dist/reporting/admin/index.js +2 -0
  147. package/dist/reporting/admin/model.d.ts +108 -0
  148. package/dist/reporting/admin/ports.d.ts +27 -0
  149. package/dist/reporting/admin/service.d.ts +22 -0
  150. package/dist/reporting/admin/service.js +38 -0
  151. package/dist/reporting/admin/service.js.map +1 -0
  152. package/dist/reporting/member/index.d.ts +5 -0
  153. package/dist/reporting/member/index.js +2 -0
  154. package/dist/reporting/member/model.d.ts +124 -0
  155. package/dist/reporting/member/ports.d.ts +45 -0
  156. package/dist/reporting/member/service.d.ts +73 -0
  157. package/dist/reporting/member/service.js +286 -0
  158. package/dist/reporting/member/service.js.map +1 -0
  159. package/dist/shared/actor.d.ts +9 -0
  160. package/dist/shared/errors.d.ts +7 -1
  161. package/dist/shared/errors.js +10 -1
  162. package/dist/shared/errors.js.map +1 -1
  163. package/dist/shared/events.d.ts +5 -3
  164. package/dist/shared/events.js +1 -0
  165. package/dist/shared/events.js.map +1 -1
  166. package/dist/shared/id.d.ts +12 -0
  167. package/dist/shared/id.js +13 -1
  168. package/dist/shared/id.js.map +1 -1
  169. package/dist/shared/mailer.d.ts +6 -1
  170. package/dist/shared/mailer.js.map +1 -1
  171. package/dist/shared/network.d.ts +10 -0
  172. package/dist/shared/network.js +211 -0
  173. package/dist/shared/network.js.map +1 -0
  174. package/dist/shared/settings.js.map +1 -1
  175. package/dist/types/assets.d.ts +2 -2
  176. package/dist/types/automations.d.ts +21 -2
  177. package/dist/types/content.d.ts +2 -2
  178. package/dist/types/discussion.d.ts +12 -3
  179. package/dist/types/email-templates.d.ts +124 -1
  180. package/dist/types/entitlements.d.ts +2 -2
  181. package/dist/types/events.d.ts +3 -3
  182. package/dist/types/identity.d.ts +48 -2
  183. package/dist/types/index.d.ts +10 -10
  184. package/dist/types/organizations.d.ts +2 -2
  185. package/dist/types/ports.d.ts +7 -1
  186. package/dist/types/schemas/assets.d.ts +67 -36
  187. package/dist/types/schemas/assets.js +19 -13
  188. package/dist/types/schemas/assets.js.map +1 -1
  189. package/dist/types/schemas/automations.d.ts +88 -4
  190. package/dist/types/schemas/automations.js +46 -6
  191. package/dist/types/schemas/automations.js.map +1 -1
  192. package/dist/types/schemas/content.d.ts +385 -20
  193. package/dist/types/schemas/content.js +178 -15
  194. package/dist/types/schemas/content.js.map +1 -1
  195. package/dist/types/schemas/credentials.js.map +1 -1
  196. package/dist/types/schemas/discussion.d.ts +379 -4
  197. package/dist/types/schemas/discussion.js +209 -7
  198. package/dist/types/schemas/discussion.js.map +1 -1
  199. package/dist/types/schemas/entitlements.d.ts +44 -4
  200. package/dist/types/schemas/entitlements.js +32 -4
  201. package/dist/types/schemas/entitlements.js.map +1 -1
  202. package/dist/types/schemas/identity.d.ts +115 -5
  203. package/dist/types/schemas/identity.js +59 -6
  204. package/dist/types/schemas/identity.js.map +1 -1
  205. package/dist/types/schemas/index.d.ts +9 -9
  206. package/dist/types/schemas/index.js +9 -9
  207. package/dist/types/schemas/integrations.js.map +1 -1
  208. package/dist/types/schemas/organizations.d.ts +27 -5
  209. package/dist/types/schemas/organizations.js +14 -7
  210. package/dist/types/schemas/organizations.js.map +1 -1
  211. package/dist/types/schemas/outbox.d.ts +1 -0
  212. package/dist/types/schemas/outbox.js +1 -0
  213. package/dist/types/schemas/outbox.js.map +1 -1
  214. package/dist/types/schemas/progress.d.ts +1 -0
  215. package/dist/types/schemas/progress.js +1 -0
  216. package/dist/types/schemas/progress.js.map +1 -1
  217. package/dist/types/schemas/settings.js.map +1 -1
  218. package/dist/types/schemas/shared.d.ts +4 -1
  219. package/dist/types/schemas/shared.js +7 -1
  220. package/dist/types/schemas/shared.js.map +1 -1
  221. package/dist/types/shared.d.ts +1 -1
  222. package/package.json +2 -2
  223. package/dist/reporting/dashboard/index.d.ts +0 -4
  224. package/dist/reporting/dashboard/index.js +0 -2
  225. package/dist/reporting/dashboard/model.d.ts +0 -14
  226. package/dist/reporting/dashboard/ports.d.ts +0 -13
  227. package/dist/reporting/dashboard/service.d.ts +0 -19
  228. package/dist/reporting/dashboard/service.js +0 -20
  229. package/dist/reporting/dashboard/service.js.map +0 -1
  230. package/dist/reporting/learn/index.d.ts +0 -5
  231. package/dist/reporting/learn/index.js +0 -2
  232. package/dist/reporting/learn/model.d.ts +0 -23
  233. package/dist/reporting/learn/ports.d.ts +0 -42
  234. package/dist/reporting/learn/service.d.ts +0 -48
  235. package/dist/reporting/learn/service.js +0 -111
  236. package/dist/reporting/learn/service.js.map +0 -1
  237. package/dist/reporting/students/index.d.ts +0 -4
  238. package/dist/reporting/students/index.js +0 -2
  239. package/dist/reporting/students/model.d.ts +0 -31
  240. package/dist/reporting/students/ports.d.ts +0 -13
  241. package/dist/reporting/students/ports.js +0 -1
  242. package/dist/reporting/students/service.d.ts +0 -19
  243. package/dist/reporting/students/service.js +0 -20
  244. package/dist/reporting/students/service.js.map +0 -1
  245. /package/dist/reporting/{dashboard → admin}/model.js +0 -0
  246. /package/dist/reporting/{dashboard → admin}/ports.js +0 -0
  247. /package/dist/reporting/{learn → member}/model.js +0 -0
  248. /package/dist/reporting/{learn → member}/ports.js +0 -0
  249. /package/dist/{reporting/students/model.js → shared/actor.js} +0 -0
@@ -6,71 +6,152 @@ declare const assetEvents: {
6
6
  orgId: string;
7
7
  id: string;
8
8
  key: string;
9
- kind: "video" | "download" | "content";
9
+ kind: "image" | "video" | "audio" | "document";
10
+ source: "library" | "member";
10
11
  filename: string;
11
12
  contentType: string;
12
13
  size: number;
13
14
  status: "pending" | "ready";
14
15
  uploadedBy: string;
15
16
  createdAt: Date;
17
+ updatedAt: Date;
16
18
  }, "asset.created", 1>, {
17
19
  orgId: string;
18
20
  id: string;
19
21
  key: string;
20
- kind: "video" | "download" | "content";
22
+ kind: "image" | "video" | "audio" | "document";
23
+ source: "library" | "member";
21
24
  filename: string;
22
25
  contentType: string;
23
26
  size: number;
24
27
  status: "pending" | "ready";
25
28
  uploadedBy: string;
26
29
  createdAt: unknown;
27
- }>;
30
+ updatedAt: unknown;
31
+ }, import("zod").ZodObject<{
32
+ orgId: import("zod").ZodString;
33
+ id: import("zod").ZodString;
34
+ kind: import("zod").ZodEnum<{
35
+ image: "image";
36
+ video: "video";
37
+ audio: "audio";
38
+ document: "document";
39
+ }>;
40
+ source: import("zod").ZodEnum<{
41
+ library: "library";
42
+ member: "member";
43
+ }>;
44
+ status: import("zod").ZodEnum<{
45
+ pending: "pending";
46
+ ready: "ready";
47
+ }>;
48
+ uploadedBy: import("zod").ZodString;
49
+ filename: import("zod").ZodString;
50
+ contentType: import("zod").ZodString;
51
+ size: import("zod").ZodNumber;
52
+ createdAt: import("zod").ZodCoercedDate<unknown>;
53
+ updatedAt: import("zod").ZodCoercedDate<unknown>;
54
+ }, import("zod/v4/core").$strip>>;
28
55
  assetReady: RuntimeEventDefinition<VersionedDomainEvent<{
29
56
  orgId: string;
30
57
  id: string;
31
58
  key: string;
32
- kind: "video" | "download" | "content";
59
+ kind: "image" | "video" | "audio" | "document";
60
+ source: "library" | "member";
33
61
  filename: string;
34
62
  contentType: string;
35
63
  size: number;
36
64
  status: "pending" | "ready";
37
65
  uploadedBy: string;
38
66
  createdAt: Date;
67
+ updatedAt: Date;
39
68
  }, "asset.ready", 1>, {
40
69
  orgId: string;
41
70
  id: string;
42
71
  key: string;
43
- kind: "video" | "download" | "content";
72
+ kind: "image" | "video" | "audio" | "document";
73
+ source: "library" | "member";
44
74
  filename: string;
45
75
  contentType: string;
46
76
  size: number;
47
77
  status: "pending" | "ready";
48
78
  uploadedBy: string;
49
79
  createdAt: unknown;
50
- }>;
80
+ updatedAt: unknown;
81
+ }, import("zod").ZodObject<{
82
+ orgId: import("zod").ZodString;
83
+ id: import("zod").ZodString;
84
+ kind: import("zod").ZodEnum<{
85
+ image: "image";
86
+ video: "video";
87
+ audio: "audio";
88
+ document: "document";
89
+ }>;
90
+ source: import("zod").ZodEnum<{
91
+ library: "library";
92
+ member: "member";
93
+ }>;
94
+ status: import("zod").ZodEnum<{
95
+ pending: "pending";
96
+ ready: "ready";
97
+ }>;
98
+ uploadedBy: import("zod").ZodString;
99
+ filename: import("zod").ZodString;
100
+ contentType: import("zod").ZodString;
101
+ size: import("zod").ZodNumber;
102
+ createdAt: import("zod").ZodCoercedDate<unknown>;
103
+ updatedAt: import("zod").ZodCoercedDate<unknown>;
104
+ }, import("zod/v4/core").$strip>>;
51
105
  assetDeleted: RuntimeEventDefinition<VersionedDomainEvent<{
52
106
  orgId: string;
53
107
  id: string;
54
108
  key: string;
55
- kind: "video" | "download" | "content";
109
+ kind: "image" | "video" | "audio" | "document";
110
+ source: "library" | "member";
56
111
  filename: string;
57
112
  contentType: string;
58
113
  size: number;
59
114
  status: "pending" | "ready";
60
115
  uploadedBy: string;
61
116
  createdAt: Date;
117
+ updatedAt: Date;
62
118
  }, "asset.deleted", 1>, {
63
119
  orgId: string;
64
120
  id: string;
65
121
  key: string;
66
- kind: "video" | "download" | "content";
122
+ kind: "image" | "video" | "audio" | "document";
123
+ source: "library" | "member";
67
124
  filename: string;
68
125
  contentType: string;
69
126
  size: number;
70
127
  status: "pending" | "ready";
71
128
  uploadedBy: string;
72
129
  createdAt: unknown;
73
- }>;
130
+ updatedAt: unknown;
131
+ }, import("zod").ZodObject<{
132
+ orgId: import("zod").ZodString;
133
+ id: import("zod").ZodString;
134
+ kind: import("zod").ZodEnum<{
135
+ image: "image";
136
+ video: "video";
137
+ audio: "audio";
138
+ document: "document";
139
+ }>;
140
+ source: import("zod").ZodEnum<{
141
+ library: "library";
142
+ member: "member";
143
+ }>;
144
+ status: import("zod").ZodEnum<{
145
+ pending: "pending";
146
+ ready: "ready";
147
+ }>;
148
+ uploadedBy: import("zod").ZodString;
149
+ filename: import("zod").ZodString;
150
+ contentType: import("zod").ZodString;
151
+ size: import("zod").ZodNumber;
152
+ createdAt: import("zod").ZodCoercedDate<unknown>;
153
+ updatedAt: import("zod").ZodCoercedDate<unknown>;
154
+ }, import("zod/v4/core").$strip>>;
74
155
  };
75
156
  type AssetCreated = EventOf<typeof assetEvents.assetCreated>;
76
157
  type AssetReady = EventOf<typeof assetEvents.assetReady>;
@@ -1,21 +1,37 @@
1
1
  import { assetSchema } from "../types/schemas/assets.js";
2
2
  import { defineEvent } from "../shared/events.js";
3
3
  //#region src/assets/events.ts
4
+ const publicAsset = assetSchema.pick({
5
+ orgId: true,
6
+ id: true,
7
+ kind: true,
8
+ source: true,
9
+ filename: true,
10
+ contentType: true,
11
+ size: true,
12
+ status: true,
13
+ uploadedBy: true,
14
+ createdAt: true,
15
+ updatedAt: true
16
+ }).strip();
4
17
  const assetEvents = {
5
18
  assetCreated: defineEvent({
6
19
  type: "asset.created",
7
20
  version: 1,
8
- data: assetSchema
21
+ data: assetSchema,
22
+ publicData: publicAsset
9
23
  }),
10
24
  assetReady: defineEvent({
11
25
  type: "asset.ready",
12
26
  version: 1,
13
- data: assetSchema
27
+ data: assetSchema,
28
+ publicData: publicAsset
14
29
  }),
15
30
  assetDeleted: defineEvent({
16
31
  type: "asset.deleted",
17
32
  version: 1,
18
- data: assetSchema
33
+ data: assetSchema,
34
+ publicData: publicAsset
19
35
  })
20
36
  };
21
37
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../src/assets/events.ts"],"sourcesContent":["import { assetSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nexport const assetEvents = {\n assetCreated: defineEvent({\n type: 'asset.created',\n version: 1,\n data: assetSchema,\n }),\n assetReady: defineEvent({\n type: 'asset.ready',\n version: 1,\n data: assetSchema,\n }),\n assetDeleted: defineEvent({\n type: 'asset.deleted',\n version: 1,\n data: assetSchema,\n }),\n};\n\nexport type AssetCreated = EventOf<typeof assetEvents.assetCreated>;\nexport type AssetReady = EventOf<typeof assetEvents.assetReady>;\nexport type AssetDeleted = EventOf<typeof assetEvents.assetDeleted>;\nexport type AssetEvent = EventOfValues<typeof assetEvents>;\n"],"mappings":";;;AAGA,MAAa,cAAc;CACzB,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,YAAY,YAAY;EACtB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;CACD,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;CACR,CAAC;AACH"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../src/assets/events.ts"],"sourcesContent":["import { assetSchema } from '../types/schemas/index.js';\nimport { defineEvent, type EventOf, type EventOfValues } from '../shared/ports.js';\n\nconst publicAsset = assetSchema\n .pick({\n orgId: true,\n id: true,\n kind: true,\n source: true,\n filename: true,\n contentType: true,\n size: true,\n status: true,\n uploadedBy: true,\n createdAt: true,\n updatedAt: true,\n })\n .strip();\n\nexport const assetEvents = {\n assetCreated: defineEvent({\n type: 'asset.created',\n version: 1,\n data: assetSchema,\n publicData: publicAsset,\n }),\n assetReady: defineEvent({\n type: 'asset.ready',\n version: 1,\n data: assetSchema,\n publicData: publicAsset,\n }),\n assetDeleted: defineEvent({\n type: 'asset.deleted',\n version: 1,\n data: assetSchema,\n publicData: publicAsset,\n }),\n};\n\nexport type AssetCreated = EventOf<typeof assetEvents.assetCreated>;\nexport type AssetReady = EventOf<typeof assetEvents.assetReady>;\nexport type AssetDeleted = EventOf<typeof assetEvents.assetDeleted>;\nexport type AssetEvent = EventOfValues<typeof assetEvents>;\n"],"mappings":";;;AAGA,MAAM,cAAc,YACjB,KAAK;CACJ,OAAO;CACP,IAAI;CACJ,MAAM;CACN,QAAQ;CACR,UAAU;CACV,aAAa;CACb,MAAM;CACN,QAAQ;CACR,YAAY;CACZ,WAAW;CACX,WAAW;AACb,CAAC,CAAC,CACD,MAAM;AAET,MAAa,cAAc;CACzB,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,YAAY,YAAY;EACtB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;CACD,cAAc,YAAY;EACxB,MAAM;EACN,SAAS;EACT,MAAM;EACN,YAAY;CACd,CAAC;AACH"}
@@ -0,0 +1,20 @@
1
+ //#region src/assets/file-urls.d.ts
2
+ type ThumbnailOwner = 'course' | 'download' | 'community';
3
+ /** Stable, access-checked URLs on the API for every file a response refers to.
4
+ * Each one is answered by a route that checks access, then redirects to a
5
+ * signed storage URL; none of them expires. */
6
+ interface FileUrls {
7
+ thumbnail(owner: ThumbnailOwner, ownerId: string): string;
8
+ activityAsset(activityId: string, assetId: string): string;
9
+ downloadFile(downloadId: string, assetId: string): string;
10
+ postCover(postId: string): string;
11
+ messageAttachment(chatId: string, messageId: string, assetId: string): string;
12
+ personImage(orgUserId: string): string;
13
+ memberUpload(assetId: string): string;
14
+ libraryFile(assetId: string): string;
15
+ libraryDownload(assetId: string): string;
16
+ }
17
+ declare function createFileUrls(apiUrl: string): FileUrls;
18
+ //#endregion
19
+ export { FileUrls, ThumbnailOwner, createFileUrls };
20
+ //# sourceMappingURL=file-urls.d.ts.map
@@ -0,0 +1,25 @@
1
+ //#region src/assets/file-urls.ts
2
+ const THUMBNAIL_PATHS = {
3
+ course: "courses",
4
+ download: "downloads",
5
+ community: "communities"
6
+ };
7
+ function createFileUrls(apiUrl) {
8
+ const base = apiUrl.replace(/\/+$/, "");
9
+ const at = (...segments) => `${base}/api/${segments.map((s) => encodeURIComponent(s)).join("/")}`;
10
+ return {
11
+ thumbnail: (owner, ownerId) => at("member", THUMBNAIL_PATHS[owner], ownerId, "thumbnail"),
12
+ activityAsset: (activityId, assetId) => at("member", "activities", activityId, "assets", assetId),
13
+ downloadFile: (downloadId, assetId) => at("member", "downloads", downloadId, "assets", assetId),
14
+ postCover: (postId) => at("member", "posts", postId, "cover"),
15
+ messageAttachment: (chatId, messageId, assetId) => at("member", "chats", chatId, "messages", messageId, "attachments", assetId),
16
+ personImage: (orgUserId) => at("member", "people", orgUserId, "image"),
17
+ memberUpload: (assetId) => at("member", "uploads", assetId, "file"),
18
+ libraryFile: (assetId) => at("assets", assetId, "file"),
19
+ libraryDownload: (assetId) => at("assets", assetId, "download")
20
+ };
21
+ }
22
+ //#endregion
23
+ export { createFileUrls };
24
+
25
+ //# sourceMappingURL=file-urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-urls.js","names":[],"sources":["../../src/assets/file-urls.ts"],"sourcesContent":["export type ThumbnailOwner = 'course' | 'download' | 'community';\n\n/** Stable, access-checked URLs on the API for every file a response refers to.\n * Each one is answered by a route that checks access, then redirects to a\n * signed storage URL; none of them expires. */\nexport interface FileUrls {\n thumbnail(owner: ThumbnailOwner, ownerId: string): string;\n activityAsset(activityId: string, assetId: string): string;\n downloadFile(downloadId: string, assetId: string): string;\n postCover(postId: string): string;\n messageAttachment(chatId: string, messageId: string, assetId: string): string;\n personImage(orgUserId: string): string;\n memberUpload(assetId: string): string;\n libraryFile(assetId: string): string;\n libraryDownload(assetId: string): string;\n}\n\nconst THUMBNAIL_PATHS: Record<ThumbnailOwner, string> = {\n course: 'courses',\n download: 'downloads',\n community: 'communities',\n};\n\nexport function createFileUrls(apiUrl: string): FileUrls {\n const base = apiUrl.replace(/\\/+$/, '');\n const at = (...segments: string[]) =>\n `${base}/api/${segments.map((s) => encodeURIComponent(s)).join('/')}`;\n return {\n thumbnail: (owner, ownerId) => at('member', THUMBNAIL_PATHS[owner], ownerId, 'thumbnail'),\n activityAsset: (activityId, assetId) =>\n at('member', 'activities', activityId, 'assets', assetId),\n downloadFile: (downloadId, assetId) => at('member', 'downloads', downloadId, 'assets', assetId),\n postCover: (postId) => at('member', 'posts', postId, 'cover'),\n messageAttachment: (chatId, messageId, assetId) =>\n at('member', 'chats', chatId, 'messages', messageId, 'attachments', assetId),\n personImage: (orgUserId) => at('member', 'people', orgUserId, 'image'),\n memberUpload: (assetId) => at('member', 'uploads', assetId, 'file'),\n libraryFile: (assetId) => at('assets', assetId, 'file'),\n libraryDownload: (assetId) => at('assets', assetId, 'download'),\n };\n}\n"],"mappings":";AAiBA,MAAM,kBAAkD;CACtD,QAAQ;CACR,UAAU;CACV,WAAW;AACb;AAEA,SAAgB,eAAe,QAA0B;CACvD,MAAM,OAAO,OAAO,QAAQ,QAAQ,EAAE;CACtC,MAAM,MAAM,GAAG,aACb,GAAG,KAAK,OAAO,SAAS,KAAK,MAAM,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG;CACpE,OAAO;EACL,YAAY,OAAO,YAAY,GAAG,UAAU,gBAAgB,QAAQ,SAAS,WAAW;EACxF,gBAAgB,YAAY,YAC1B,GAAG,UAAU,cAAc,YAAY,UAAU,OAAO;EAC1D,eAAe,YAAY,YAAY,GAAG,UAAU,aAAa,YAAY,UAAU,OAAO;EAC9F,YAAY,WAAW,GAAG,UAAU,SAAS,QAAQ,OAAO;EAC5D,oBAAoB,QAAQ,WAAW,YACrC,GAAG,UAAU,SAAS,QAAQ,YAAY,WAAW,eAAe,OAAO;EAC7E,cAAc,cAAc,GAAG,UAAU,UAAU,WAAW,OAAO;EACrE,eAAe,YAAY,GAAG,UAAU,WAAW,SAAS,MAAM;EAClE,cAAc,YAAY,GAAG,UAAU,SAAS,MAAM;EACtD,kBAAkB,YAAY,GAAG,UAAU,SAAS,UAAU;CAChE;AACF"}
@@ -1,7 +1,8 @@
1
1
  import { Page } from "../types/shared.js";
2
- import { Asset, AssetKind, AssetStatus, AssetsQuery, DownloadTicket, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
2
+ import { Asset, AssetKind, AssetSource, AssetStatus, AssetUrls, AssetView, AssetsQuery, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
3
3
  import { AssetCreated, AssetDeleted, AssetEvent, AssetReady, assetEvents } from "./events.js";
4
+ import { FileUrls, ThumbnailOwner, createFileUrls } from "./file-urls.js";
4
5
  import "./model.js";
5
- import { AssetsRepository, AssetsService } from "./ports.js";
6
- import { AssetsServiceImpl } from "./service.js";
7
- export { type Asset, type AssetCreated, type AssetDeleted, type AssetEvent, type AssetKind, type AssetReady, type AssetStatus, type AssetsQuery, type AssetsRepository, type AssetsService, AssetsServiceImpl, type DownloadTicket, type Page, type RequestUploadInput, type UploadTicket, assetEvents };
6
+ import { AssetFiles, AssetsRepository, AssetsService, LibraryAssetReader, MemberImageReader, MemberUploadInput, ReadyFile } from "./ports.js";
7
+ import { AssetsServiceImpl, MEMBER_IMAGE_TYPE, isMemberImageType, kindOf } from "./service.js";
8
+ export { type Asset, type AssetCreated, type AssetDeleted, type AssetEvent, type AssetFiles, type AssetKind, type AssetReady, type AssetSource, type AssetStatus, type AssetUrls, type AssetView, type AssetsQuery, type AssetsRepository, type AssetsService, AssetsServiceImpl, type FileUrls, type LibraryAssetReader, MEMBER_IMAGE_TYPE, type MemberImageReader, type MemberUploadInput, type Page, type ReadyFile, type RequestUploadInput, type ThumbnailOwner, type UploadTicket, assetEvents, createFileUrls, isMemberImageType, kindOf };
@@ -1,3 +1,4 @@
1
1
  import { assetEvents } from "./events.js";
2
- import { AssetsServiceImpl } from "./service.js";
3
- export { AssetsServiceImpl, assetEvents };
2
+ import { createFileUrls } from "./file-urls.js";
3
+ import { AssetsServiceImpl, MEMBER_IMAGE_TYPE, isMemberImageType, kindOf } from "./service.js";
4
+ export { AssetsServiceImpl, MEMBER_IMAGE_TYPE, assetEvents, createFileUrls, isMemberImageType, kindOf };
@@ -1,4 +1,4 @@
1
1
  import { Page } from "../types/shared.js";
2
- import { Asset, AssetKind, AssetStatus, AssetsQuery, DownloadTicket, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
2
+ import { Asset, AssetKind, AssetSource, AssetStatus, AssetUrls, AssetView, AssetsQuery, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
3
3
  import "../types/index.js";
4
- export type { Asset, AssetKind, AssetStatus, AssetsQuery, DownloadTicket, Page, RequestUploadInput, UploadTicket };
4
+ export type { Asset, AssetKind, AssetSource, AssetStatus, AssetUrls, AssetView, AssetsQuery, Page, RequestUploadInput, UploadTicket };
@@ -1,28 +1,58 @@
1
1
  import { Page } from "../types/shared.js";
2
- import { Asset, AssetsQuery, DownloadTicket, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
2
+ import { Asset, AssetView, AssetsQuery, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
3
3
  import { OutboxAppender, UnitOfWork } from "../shared/ports.js";
4
4
  import "./model.js";
5
5
  //#region src/assets/ports.d.ts
6
- interface AssetsService {
7
- /** Register an asset and return a presigned URL to upload its bytes. */
6
+ interface MemberImageReader {
7
+ ownsImage(orgId: string, assetId: string, orgUserId: string): Promise<boolean>;
8
+ }
9
+ interface LibraryAssetReader {
10
+ libraryAssetsAmong(orgId: string, assetIds: string[]): Promise<string[]>;
11
+ }
12
+ interface ReadyFile {
13
+ filename: string;
14
+ contentType: string;
15
+ size: number;
16
+ }
17
+ interface AssetFiles {
18
+ /** Ready files of the org among these ids, with what a download shows of them. */
19
+ readyFiles(orgId: string, assetIds: readonly string[]): Promise<Record<string, ReadyFile>>;
20
+ /** A signed storage URL for a ready file of the org, after the caller has checked
21
+ * access. `saveAs` makes it a short-lived download under that name. */
22
+ signFile(orgId: string, assetId: string, opts?: {
23
+ saveAs?: string;
24
+ }): Promise<string | null>;
25
+ }
26
+ interface MemberUploadInput {
27
+ filename: string;
28
+ contentType: string;
29
+ }
30
+ interface AssetsService extends MemberImageReader, LibraryAssetReader, AssetFiles {
8
31
  requestUpload(orgId: string, input: RequestUploadInput): Promise<UploadTicket>;
9
- /** After upload, capture size/content-type from storage and mark ready. */
10
- confirm(orgId: string, id: string): Promise<Asset | null>;
11
- list(orgId: string, query: AssetsQuery): Promise<Page<Asset>>;
12
- get(orgId: string, id: string): Promise<Asset | null>;
13
- /** Short-lived presigned URL to download/serve the asset. `expiresInSeconds`
14
- * overrides the adapter default — entitled delivery passes its own. */
15
- requestDownload(orgId: string, id: string, filename?: string, expiresInSeconds?: number): Promise<DownloadTicket | null>;
16
- /** Remove the object from storage and the registry. */
32
+ requestMemberUpload(orgId: string, orgUserId: string, input: MemberUploadInput): Promise<UploadTicket>;
33
+ confirm(orgId: string, id: string): Promise<AssetView | null>;
34
+ confirmOwn(orgId: string, id: string, orgUserId: string): Promise<AssetView | null>;
35
+ list(orgId: string, query: AssetsQuery): Promise<Page<AssetView>>;
36
+ get(orgId: string, id: string): Promise<AssetView | null>;
37
+ libraryFile(orgId: string, assetId: string, opts: {
38
+ download: boolean;
39
+ }): Promise<string | null>;
40
+ ownUploadFile(orgId: string, assetId: string, orgUserId: string): Promise<string | null>;
17
41
  remove(orgId: string, id: string): Promise<boolean>;
42
+ removeOwn(orgId: string, id: string, orgUserId: string): Promise<boolean>;
43
+ hasUnattached(orgId: string, now: Date): Promise<boolean>;
44
+ removeUnattached(orgId: string, now: Date): Promise<number>;
18
45
  }
19
46
  interface AssetsRepository {
20
47
  insert(orgId: string, asset: Asset): Promise<Asset>;
21
48
  list(orgId: string, query: AssetsQuery): Promise<Page<Asset>>;
22
- /** Scoped to the org — returns null if the asset belongs to another org. */
23
49
  findById(orgId: string, id: string): Promise<Asset | null>;
24
- update(id: string, patch: Partial<Pick<Asset, 'size' | 'contentType' | 'status'>>): Promise<Asset | null>;
25
- delete(id: string): Promise<boolean>;
50
+ findByIds(orgId: string, ids: string[]): Promise<Asset[]>;
51
+ markReady(orgId: string, id: string, patch: Pick<Asset, 'key' | 'kind' | 'size' | 'contentType'>): Promise<Asset | null>;
52
+ delete(orgId: string, id: string): Promise<boolean>;
53
+ hasUnreferencedMemberUploads(orgId: string, before: Date): Promise<boolean>;
54
+ listUnreferencedMemberUploads(orgId: string, before: Date): Promise<Asset[]>;
55
+ heldKeys(orgId: string, keys: string[]): Promise<string[]>;
26
56
  }
27
57
  interface AssetsWriteScope {
28
58
  assets: AssetsRepository;
@@ -30,5 +60,5 @@ interface AssetsWriteScope {
30
60
  }
31
61
  type AssetsUnitOfWork = UnitOfWork<AssetsWriteScope>;
32
62
  //#endregion
33
- export { AssetsRepository, AssetsService, AssetsUnitOfWork, AssetsWriteScope };
63
+ export { AssetFiles, AssetsRepository, AssetsService, AssetsUnitOfWork, AssetsWriteScope, LibraryAssetReader, MemberImageReader, MemberUploadInput, ReadyFile };
34
64
  //# sourceMappingURL=ports.d.ts.map
@@ -1,29 +1,61 @@
1
1
  import { Page } from "../types/shared.js";
2
2
  import { Logger, ObjectStorage } from "../types/ports.js";
3
- import { Asset, AssetsQuery, DownloadTicket, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
3
+ import { AssetKind, AssetView, AssetsQuery, RequestUploadInput, UploadTicket } from "../types/schemas/assets.js";
4
4
  import "../shared/ports.js";
5
+ import { FileUrls } from "./file-urls.js";
5
6
  import "./model.js";
6
- import { AssetsRepository, AssetsService, AssetsUnitOfWork } from "./ports.js";
7
+ import { AssetsRepository, AssetsService, AssetsUnitOfWork, MemberUploadInput, ReadyFile } from "./ports.js";
7
8
  //#region src/assets/service.d.ts
9
+ declare const MEMBER_IMAGE_TYPE: RegExp;
10
+ declare function isMemberImageType(contentType: string): boolean;
11
+ declare function kindOf(contentType: string): AssetKind;
8
12
  type AssetsServiceParams = {
9
13
  storage: ObjectStorage;
10
14
  repo: AssetsRepository;
11
15
  uow: AssetsUnitOfWork;
16
+ memberImageMaxBytes: number;
17
+ downloadLinkExpirySeconds: number;
18
+ fileUrls: FileUrls;
12
19
  logger?: Logger;
13
20
  };
14
21
  declare class AssetsServiceImpl implements AssetsService {
15
22
  private readonly storage;
16
23
  private readonly repo;
17
24
  private readonly uow;
25
+ private readonly memberImageMaxBytes;
26
+ private readonly downloadLinkExpirySeconds;
27
+ private readonly fileUrls;
18
28
  private readonly logger;
19
29
  constructor(params: AssetsServiceParams);
20
30
  requestUpload(orgId: string, input: RequestUploadInput): Promise<UploadTicket>;
21
- confirm(orgId: string, id: string): Promise<Asset | null>;
22
- list(orgId: string, query: AssetsQuery): Promise<Page<Asset>>;
23
- get(orgId: string, id: string): Promise<Asset | null>;
24
- requestDownload(orgId: string, id: string, filename?: string, expiresInSeconds?: number): Promise<DownloadTicket | null>;
31
+ requestMemberUpload(orgId: string, orgUserId: string, input: MemberUploadInput): Promise<UploadTicket>;
32
+ confirm(orgId: string, id: string): Promise<AssetView | null>;
33
+ confirmOwn(orgId: string, id: string, orgUserId: string): Promise<AssetView | null>;
34
+ ownUploadFile(orgId: string, assetId: string, orgUserId: string): Promise<string | null>;
35
+ ownsImage(orgId: string, assetId: string, orgUserId: string): Promise<boolean>;
36
+ libraryAssetsAmong(orgId: string, assetIds: string[]): Promise<string[]>;
37
+ list(orgId: string, query: AssetsQuery): Promise<Page<AssetView>>;
38
+ get(orgId: string, id: string): Promise<AssetView | null>;
39
+ readyFiles(orgId: string, assetIds: readonly string[]): Promise<Record<string, ReadyFile>>;
40
+ signFile(orgId: string, assetId: string, opts?: {
41
+ saveAs?: string;
42
+ }): Promise<string | null>;
43
+ libraryFile(orgId: string, assetId: string, opts: {
44
+ download: boolean;
45
+ }): Promise<string | null>;
25
46
  remove(orgId: string, id: string): Promise<boolean>;
47
+ removeOwn(orgId: string, id: string, orgUserId: string): Promise<boolean>;
48
+ hasUnattached(orgId: string, now: Date): Promise<boolean>;
49
+ removeUnattached(orgId: string, now: Date): Promise<number>;
50
+ private strayUploads;
51
+ private finalize;
52
+ private finalizeMember;
53
+ private markReady;
54
+ private readyAmong;
55
+ private view;
56
+ private discard;
57
+ private removeObject;
26
58
  }
27
59
  //#endregion
28
- export { AssetsServiceImpl, AssetsServiceParams };
60
+ export { AssetsServiceImpl, AssetsServiceParams, MEMBER_IMAGE_TYPE, isMemberImageType, kindOf };
29
61
  //# sourceMappingURL=service.d.ts.map