@carlonicora/nestjs-neo4jsonapi 6.7.0 → 6.9.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 (218) hide show
  1. package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
  2. package/dist/bootstrap/app.module.factory.js +1 -0
  3. package/dist/bootstrap/app.module.factory.js.map +1 -1
  4. package/dist/bootstrap/bootstrap.options.d.ts +15 -0
  5. package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
  6. package/dist/common/constants/core-module.ids.d.ts +1 -0
  7. package/dist/common/constants/core-module.ids.d.ts.map +1 -1
  8. package/dist/common/constants/core-module.ids.js +1 -0
  9. package/dist/common/constants/core-module.ids.js.map +1 -1
  10. package/dist/config/enums/queue.id.d.ts +1 -0
  11. package/dist/config/enums/queue.id.d.ts.map +1 -1
  12. package/dist/config/enums/queue.id.js +1 -0
  13. package/dist/config/enums/queue.id.js.map +1 -1
  14. package/dist/core/blocknote/services/blocknote.service.d.ts +25 -0
  15. package/dist/core/blocknote/services/blocknote.service.d.ts.map +1 -1
  16. package/dist/core/blocknote/services/blocknote.service.js +84 -0
  17. package/dist/core/blocknote/services/blocknote.service.js.map +1 -1
  18. package/dist/foundations/blog/blog.constants.d.ts +17 -0
  19. package/dist/foundations/blog/blog.constants.d.ts.map +1 -0
  20. package/dist/foundations/blog/blog.constants.js +17 -0
  21. package/dist/foundations/blog/blog.constants.js.map +1 -0
  22. package/dist/foundations/blog/blog.module.d.ts +28 -0
  23. package/dist/foundations/blog/blog.module.d.ts.map +1 -0
  24. package/dist/foundations/blog/blog.module.js +143 -0
  25. package/dist/foundations/blog/blog.module.js.map +1 -0
  26. package/dist/foundations/blog/controllers/blog-category-translation.controller.d.ts +17 -0
  27. package/dist/foundations/blog/controllers/blog-category-translation.controller.d.ts.map +1 -0
  28. package/dist/foundations/blog/controllers/blog-category-translation.controller.js +81 -0
  29. package/dist/foundations/blog/controllers/blog-category-translation.controller.js.map +1 -0
  30. package/dist/foundations/blog/controllers/blog-category.controller.d.ts +24 -0
  31. package/dist/foundations/blog/controllers/blog-category.controller.d.ts.map +1 -0
  32. package/dist/foundations/blog/controllers/blog-category.controller.js +125 -0
  33. package/dist/foundations/blog/controllers/blog-category.controller.js.map +1 -0
  34. package/dist/foundations/blog/controllers/blog-post-translation.controller.d.ts +17 -0
  35. package/dist/foundations/blog/controllers/blog-post-translation.controller.d.ts.map +1 -0
  36. package/dist/foundations/blog/controllers/blog-post-translation.controller.js +81 -0
  37. package/dist/foundations/blog/controllers/blog-post-translation.controller.js.map +1 -0
  38. package/dist/foundations/blog/controllers/blog-post.controller.d.ts +28 -0
  39. package/dist/foundations/blog/controllers/blog-post.controller.d.ts.map +1 -0
  40. package/dist/foundations/blog/controllers/blog-post.controller.js +157 -0
  41. package/dist/foundations/blog/controllers/blog-post.controller.js.map +1 -0
  42. package/dist/foundations/blog/controllers/blog-settings.controller.d.ts +16 -0
  43. package/dist/foundations/blog/controllers/blog-settings.controller.d.ts.map +1 -0
  44. package/dist/foundations/blog/controllers/blog-settings.controller.js +73 -0
  45. package/dist/foundations/blog/controllers/blog-settings.controller.js.map +1 -0
  46. package/dist/foundations/blog/controllers/blog.public.controller.d.ts +26 -0
  47. package/dist/foundations/blog/controllers/blog.public.controller.d.ts.map +1 -0
  48. package/dist/foundations/blog/controllers/blog.public.controller.js +117 -0
  49. package/dist/foundations/blog/controllers/blog.public.controller.js.map +1 -0
  50. package/dist/foundations/blog/dtos/blog-category-translation.put.dto.d.ts +16 -0
  51. package/dist/foundations/blog/dtos/blog-category-translation.put.dto.d.ts.map +1 -0
  52. package/dist/foundations/blog/dtos/blog-category-translation.put.dto.js +62 -0
  53. package/dist/foundations/blog/dtos/blog-category-translation.put.dto.js.map +1 -0
  54. package/dist/foundations/blog/dtos/blog-category.dto.d.ts +11 -0
  55. package/dist/foundations/blog/dtos/blog-category.dto.d.ts.map +1 -0
  56. package/dist/foundations/blog/dtos/blog-category.dto.js +45 -0
  57. package/dist/foundations/blog/dtos/blog-category.dto.js.map +1 -0
  58. package/dist/foundations/blog/dtos/blog-category.post.dto.d.ts +16 -0
  59. package/dist/foundations/blog/dtos/blog-category.post.dto.d.ts.map +1 -0
  60. package/dist/foundations/blog/dtos/blog-category.post.dto.js +68 -0
  61. package/dist/foundations/blog/dtos/blog-category.post.dto.js.map +1 -0
  62. package/dist/foundations/blog/dtos/blog-category.put.dto.d.ts +21 -0
  63. package/dist/foundations/blog/dtos/blog-category.put.dto.d.ts.map +1 -0
  64. package/dist/foundations/blog/dtos/blog-category.put.dto.js +76 -0
  65. package/dist/foundations/blog/dtos/blog-category.put.dto.js.map +1 -0
  66. package/dist/foundations/blog/dtos/blog-post-translation.put.dto.d.ts +19 -0
  67. package/dist/foundations/blog/dtos/blog-post-translation.put.dto.d.ts.map +1 -0
  68. package/dist/foundations/blog/dtos/blog-post-translation.put.dto.js +73 -0
  69. package/dist/foundations/blog/dtos/blog-post-translation.put.dto.js.map +1 -0
  70. package/dist/foundations/blog/dtos/blog-post.dto.d.ts +11 -0
  71. package/dist/foundations/blog/dtos/blog-post.dto.d.ts.map +1 -0
  72. package/dist/foundations/blog/dtos/blog-post.dto.js +45 -0
  73. package/dist/foundations/blog/dtos/blog-post.dto.js.map +1 -0
  74. package/dist/foundations/blog/dtos/blog-post.post.dto.d.ts +27 -0
  75. package/dist/foundations/blog/dtos/blog-post.post.dto.d.ts.map +1 -0
  76. package/dist/foundations/blog/dtos/blog-post.post.dto.js +98 -0
  77. package/dist/foundations/blog/dtos/blog-post.post.dto.js.map +1 -0
  78. package/dist/foundations/blog/dtos/blog-post.put.dto.d.ts +30 -0
  79. package/dist/foundations/blog/dtos/blog-post.put.dto.d.ts.map +1 -0
  80. package/dist/foundations/blog/dtos/blog-post.put.dto.js +104 -0
  81. package/dist/foundations/blog/dtos/blog-post.put.dto.js.map +1 -0
  82. package/dist/foundations/blog/dtos/blog-settings.put.dto.d.ts +14 -0
  83. package/dist/foundations/blog/dtos/blog-settings.put.dto.d.ts.map +1 -0
  84. package/dist/foundations/blog/dtos/blog-settings.put.dto.js +52 -0
  85. package/dist/foundations/blog/dtos/blog-settings.put.dto.js.map +1 -0
  86. package/dist/foundations/blog/entities/blog-category-translation.d.ts +36 -0
  87. package/dist/foundations/blog/entities/blog-category-translation.d.ts.map +1 -0
  88. package/dist/foundations/blog/entities/blog-category-translation.js +70 -0
  89. package/dist/foundations/blog/entities/blog-category-translation.js.map +1 -0
  90. package/dist/foundations/blog/entities/blog-category-translation.meta.d.ts +3 -0
  91. package/dist/foundations/blog/entities/blog-category-translation.meta.d.ts.map +1 -0
  92. package/dist/foundations/blog/entities/blog-category-translation.meta.js +10 -0
  93. package/dist/foundations/blog/entities/blog-category-translation.meta.js.map +1 -0
  94. package/dist/foundations/blog/entities/blog-category.d.ts +35 -0
  95. package/dist/foundations/blog/entities/blog-category.d.ts.map +1 -0
  96. package/dist/foundations/blog/entities/blog-category.js +78 -0
  97. package/dist/foundations/blog/entities/blog-category.js.map +1 -0
  98. package/dist/foundations/blog/entities/blog-category.meta.d.ts +3 -0
  99. package/dist/foundations/blog/entities/blog-category.meta.d.ts.map +1 -0
  100. package/dist/foundations/blog/entities/blog-category.meta.js +10 -0
  101. package/dist/foundations/blog/entities/blog-category.meta.js.map +1 -0
  102. package/dist/foundations/blog/entities/blog-post-translation.d.ts +43 -0
  103. package/dist/foundations/blog/entities/blog-post-translation.d.ts.map +1 -0
  104. package/dist/foundations/blog/entities/blog-post-translation.js +91 -0
  105. package/dist/foundations/blog/entities/blog-post-translation.js.map +1 -0
  106. package/dist/foundations/blog/entities/blog-post-translation.meta.d.ts +3 -0
  107. package/dist/foundations/blog/entities/blog-post-translation.meta.d.ts.map +1 -0
  108. package/dist/foundations/blog/entities/blog-post-translation.meta.js +10 -0
  109. package/dist/foundations/blog/entities/blog-post-translation.meta.js.map +1 -0
  110. package/dist/foundations/blog/entities/blog-post.d.ts +63 -0
  111. package/dist/foundations/blog/entities/blog-post.d.ts.map +1 -0
  112. package/dist/foundations/blog/entities/blog-post.js +149 -0
  113. package/dist/foundations/blog/entities/blog-post.js.map +1 -0
  114. package/dist/foundations/blog/entities/blog-post.meta.d.ts +3 -0
  115. package/dist/foundations/blog/entities/blog-post.meta.d.ts.map +1 -0
  116. package/dist/foundations/blog/entities/blog-post.meta.js +10 -0
  117. package/dist/foundations/blog/entities/blog-post.meta.js.map +1 -0
  118. package/dist/foundations/blog/entities/blog-settings.d.ts +18 -0
  119. package/dist/foundations/blog/entities/blog-settings.d.ts.map +1 -0
  120. package/dist/foundations/blog/entities/blog-settings.js +26 -0
  121. package/dist/foundations/blog/entities/blog-settings.js.map +1 -0
  122. package/dist/foundations/blog/entities/blog-settings.meta.d.ts +3 -0
  123. package/dist/foundations/blog/entities/blog-settings.meta.d.ts.map +1 -0
  124. package/dist/foundations/blog/entities/blog-settings.meta.js +10 -0
  125. package/dist/foundations/blog/entities/blog-settings.meta.js.map +1 -0
  126. package/dist/foundations/blog/index.d.ts +34 -0
  127. package/dist/foundations/blog/index.d.ts.map +1 -0
  128. package/dist/foundations/blog/index.js +50 -0
  129. package/dist/foundations/blog/index.js.map +1 -0
  130. package/dist/foundations/blog/interfaces/blog.config.interface.d.ts +22 -0
  131. package/dist/foundations/blog/interfaces/blog.config.interface.d.ts.map +1 -0
  132. package/dist/foundations/blog/interfaces/blog.config.interface.js +10 -0
  133. package/dist/foundations/blog/interfaces/blog.config.interface.js.map +1 -0
  134. package/dist/foundations/blog/processors/blog.processor.d.ts +77 -0
  135. package/dist/foundations/blog/processors/blog.processor.d.ts.map +1 -0
  136. package/dist/foundations/blog/processors/blog.processor.js +404 -0
  137. package/dist/foundations/blog/processors/blog.processor.js.map +1 -0
  138. package/dist/foundations/blog/prompts/blog-summary.prompt.d.ts +6 -0
  139. package/dist/foundations/blog/prompts/blog-summary.prompt.d.ts.map +1 -0
  140. package/dist/foundations/blog/prompts/blog-summary.prompt.js +19 -0
  141. package/dist/foundations/blog/prompts/blog-summary.prompt.js.map +1 -0
  142. package/dist/foundations/blog/prompts/blog-translate.prompt.d.ts +7 -0
  143. package/dist/foundations/blog/prompts/blog-translate.prompt.d.ts.map +1 -0
  144. package/dist/foundations/blog/prompts/blog-translate.prompt.js +24 -0
  145. package/dist/foundations/blog/prompts/blog-translate.prompt.js.map +1 -0
  146. package/dist/foundations/blog/repositories/blog-category-translation.repository.d.ts +78 -0
  147. package/dist/foundations/blog/repositories/blog-category-translation.repository.d.ts.map +1 -0
  148. package/dist/foundations/blog/repositories/blog-category-translation.repository.js +199 -0
  149. package/dist/foundations/blog/repositories/blog-category-translation.repository.js.map +1 -0
  150. package/dist/foundations/blog/repositories/blog-category.repository.d.ts +56 -0
  151. package/dist/foundations/blog/repositories/blog-category.repository.d.ts.map +1 -0
  152. package/dist/foundations/blog/repositories/blog-category.repository.js +166 -0
  153. package/dist/foundations/blog/repositories/blog-category.repository.js.map +1 -0
  154. package/dist/foundations/blog/repositories/blog-post-translation.repository.d.ts +88 -0
  155. package/dist/foundations/blog/repositories/blog-post-translation.repository.d.ts.map +1 -0
  156. package/dist/foundations/blog/repositories/blog-post-translation.repository.js +220 -0
  157. package/dist/foundations/blog/repositories/blog-post-translation.repository.js.map +1 -0
  158. package/dist/foundations/blog/repositories/blog-post.repository.d.ts +118 -0
  159. package/dist/foundations/blog/repositories/blog-post.repository.d.ts.map +1 -0
  160. package/dist/foundations/blog/repositories/blog-post.repository.js +350 -0
  161. package/dist/foundations/blog/repositories/blog-post.repository.js.map +1 -0
  162. package/dist/foundations/blog/repositories/blog-settings.repository.d.ts +21 -0
  163. package/dist/foundations/blog/repositories/blog-settings.repository.d.ts.map +1 -0
  164. package/dist/foundations/blog/repositories/blog-settings.repository.js +60 -0
  165. package/dist/foundations/blog/repositories/blog-settings.repository.js.map +1 -0
  166. package/dist/foundations/blog/services/blog-category-translation.service.d.ts +37 -0
  167. package/dist/foundations/blog/services/blog-category-translation.service.d.ts.map +1 -0
  168. package/dist/foundations/blog/services/blog-category-translation.service.js +97 -0
  169. package/dist/foundations/blog/services/blog-category-translation.service.js.map +1 -0
  170. package/dist/foundations/blog/services/blog-category.service.d.ts +56 -0
  171. package/dist/foundations/blog/services/blog-category.service.d.ts.map +1 -0
  172. package/dist/foundations/blog/services/blog-category.service.js +164 -0
  173. package/dist/foundations/blog/services/blog-category.service.js.map +1 -0
  174. package/dist/foundations/blog/services/blog-post-translation.service.d.ts +44 -0
  175. package/dist/foundations/blog/services/blog-post-translation.service.d.ts.map +1 -0
  176. package/dist/foundations/blog/services/blog-post-translation.service.js +115 -0
  177. package/dist/foundations/blog/services/blog-post-translation.service.js.map +1 -0
  178. package/dist/foundations/blog/services/blog-post.service.d.ts +109 -0
  179. package/dist/foundations/blog/services/blog-post.service.d.ts.map +1 -0
  180. package/dist/foundations/blog/services/blog-post.service.js +276 -0
  181. package/dist/foundations/blog/services/blog-post.service.js.map +1 -0
  182. package/dist/foundations/blog/services/blog-queue.service.d.ts +36 -0
  183. package/dist/foundations/blog/services/blog-queue.service.d.ts.map +1 -0
  184. package/dist/foundations/blog/services/blog-queue.service.js +79 -0
  185. package/dist/foundations/blog/services/blog-queue.service.js.map +1 -0
  186. package/dist/foundations/blog/services/blog-settings.service.d.ts +21 -0
  187. package/dist/foundations/blog/services/blog-settings.service.d.ts.map +1 -0
  188. package/dist/foundations/blog/services/blog-settings.service.js +49 -0
  189. package/dist/foundations/blog/services/blog-settings.service.js.map +1 -0
  190. package/dist/foundations/blog/utils/reading-time.d.ts +5 -0
  191. package/dist/foundations/blog/utils/reading-time.d.ts.map +1 -0
  192. package/dist/foundations/blog/utils/reading-time.js +12 -0
  193. package/dist/foundations/blog/utils/reading-time.js.map +1 -0
  194. package/dist/foundations/blog/utils/slug.d.ts +12 -0
  195. package/dist/foundations/blog/utils/slug.d.ts.map +1 -0
  196. package/dist/foundations/blog/utils/slug.js +36 -0
  197. package/dist/foundations/blog/utils/slug.js.map +1 -0
  198. package/dist/foundations/foundations.modules.d.ts +8 -0
  199. package/dist/foundations/foundations.modules.d.ts.map +1 -1
  200. package/dist/foundations/foundations.modules.js +4 -1
  201. package/dist/foundations/foundations.modules.js.map +1 -1
  202. package/dist/foundations/index.d.ts +1 -0
  203. package/dist/foundations/index.d.ts.map +1 -1
  204. package/dist/foundations/index.js +1 -0
  205. package/dist/foundations/index.js.map +1 -1
  206. package/dist/foundations/stripe/services/stripe.payment.service.d.ts +33 -0
  207. package/dist/foundations/stripe/services/stripe.payment.service.d.ts.map +1 -1
  208. package/dist/foundations/stripe/services/stripe.payment.service.js +68 -0
  209. package/dist/foundations/stripe/services/stripe.payment.service.js.map +1 -1
  210. package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.d.ts +2 -2
  211. package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.d.ts.map +1 -1
  212. package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.js +9 -9
  213. package/dist/foundations/stripe-subscription/services/stripe-subscription-admin.service.js.map +1 -1
  214. package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts +3 -1
  215. package/dist/foundations/tokenusage/enums/tokenusage.type.d.ts.map +1 -1
  216. package/dist/foundations/tokenusage/enums/tokenusage.type.js +2 -0
  217. package/dist/foundations/tokenusage/enums/tokenusage.type.js.map +1 -1
  218. package/package.json +1 -1
@@ -0,0 +1,56 @@
1
+ import { ConfigService } from "@nestjs/config";
2
+ import { ClsService } from "nestjs-cls";
3
+ import { JsonApiListDocument, JsonApiSingleDocument } from "../../../core/jsonapi/interfaces/jsonapi.document.interface";
4
+ import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
5
+ import { AbstractService, JsonApiDTOData } from "../../../core/neo4j/abstracts/abstract.service";
6
+ import { BlogCategory, BlogCategoryDescriptor } from "../entities/blog-category";
7
+ import { BlogCategoryTranslationRepository } from "../repositories/blog-category-translation.repository";
8
+ import { BlogCategoryRepository } from "../repositories/blog-category.repository";
9
+ import { BlogQueueService } from "./blog-queue.service";
10
+ import { S3ClientKeyService } from "../../s3/services/s3-client-key.service";
11
+ /**
12
+ * Blog categories: admin writes in the original language, translation through
13
+ * the blog queue, and the public list resolved to one language.
14
+ */
15
+ export declare class BlogCategoryService extends AbstractService<BlogCategory, typeof BlogCategoryDescriptor.relationships> {
16
+ private readonly blogCategoryRepository;
17
+ private readonly blogCategoryTranslationRepository;
18
+ private readonly blogQueueService;
19
+ private readonly configService;
20
+ private readonly s3ClientKeys?;
21
+ protected readonly descriptor: import("../../..").EntityDescriptor<BlogCategory, {
22
+ translations: {
23
+ model: import("../../..").DataMeta;
24
+ direction: "out";
25
+ relationship: string;
26
+ cardinality: "many";
27
+ required: false;
28
+ description: string;
29
+ };
30
+ }>;
31
+ constructor(jsonApiService: JsonApiService, blogCategoryRepository: BlogCategoryRepository, clsService: ClsService, blogCategoryTranslationRepository: BlogCategoryTranslationRepository, blogQueueService: BlogQueueService, configService: ConfigService, s3ClientKeys?: S3ClientKeyService);
32
+ createFromDTO(params: {
33
+ data: JsonApiDTOData;
34
+ included?: unknown[];
35
+ }): Promise<JsonApiSingleDocument>;
36
+ /**
37
+ * Updates the image and the original-language text. Translation re-runs only
38
+ * when the original's text changed. The slug follows the name unless the
39
+ * admin sets one explicitly.
40
+ */
41
+ putFromDTO(params: {
42
+ data: JsonApiDTOData;
43
+ included?: unknown[];
44
+ }): Promise<JsonApiSingleDocument>;
45
+ /** Deletes the category with every translation. */
46
+ delete(params: {
47
+ id: string;
48
+ }): Promise<void>;
49
+ findPublicList(params: {
50
+ language: string;
51
+ }): Promise<JsonApiListDocument>;
52
+ private _queue;
53
+ private _supportedLanguages;
54
+ private _uniqueSlug;
55
+ }
56
+ //# sourceMappingURL=blog-category.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-category.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-category.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,6DAA6D,CAAC;AAErE,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAGjG,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAE,iCAAiC,EAAE,MAAM,sDAAsD,CAAC;AACzG,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAElF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAE7E;;;GAGG;AACH,qBACa,mBAAoB,SAAQ,eAAe,CAAC,YAAY,EAAE,OAAO,sBAAsB,CAAC,aAAa,CAAC;IAK/G,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IAEvC,OAAO,CAAC,QAAQ,CAAC,iCAAiC;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAClB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IAT5C,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;;OAA0B;gBAGrD,cAAc,EAAE,cAAc,EACb,sBAAsB,EAAE,sBAAsB,EAC/D,UAAU,EAAE,UAAU,EACL,iCAAiC,EAAE,iCAAiC,EACpE,gBAAgB,EAAE,gBAAgB,EAClC,aAAa,EAAE,aAAa,EAChB,YAAY,CAAC,EAAE,kBAAkB;IAK1D,aAAa,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAkC3G;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,cAAc,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAoDxG,mDAAmD;IAC7C,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C,cAAc,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAOlE,MAAM;IAKpB,OAAO,CAAC,mBAAmB;YAIb,WAAW;CAa1B"}
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.BlogCategoryService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const config_1 = require("@nestjs/config");
18
+ const crypto_1 = require("crypto");
19
+ const nestjs_cls_1 = require("nestjs-cls");
20
+ const jsonapi_paginator_1 = require("../../../core/jsonapi/serialisers/jsonapi.paginator");
21
+ const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
22
+ const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
23
+ const blog_category_1 = require("../entities/blog-category");
24
+ const blog_category_translation_repository_1 = require("../repositories/blog-category-translation.repository");
25
+ const blog_category_repository_1 = require("../repositories/blog-category.repository");
26
+ const slug_1 = require("../utils/slug");
27
+ const blog_queue_service_1 = require("./blog-queue.service");
28
+ const s3_client_key_service_1 = require("../../s3/services/s3-client-key.service");
29
+ /**
30
+ * Blog categories: admin writes in the original language, translation through
31
+ * the blog queue, and the public list resolved to one language.
32
+ */
33
+ let BlogCategoryService = class BlogCategoryService extends abstract_service_1.AbstractService {
34
+ constructor(jsonApiService, blogCategoryRepository, clsService, blogCategoryTranslationRepository, blogQueueService, configService, s3ClientKeys) {
35
+ super(jsonApiService, blogCategoryRepository, clsService, blog_category_1.BlogCategoryDescriptor.model);
36
+ this.blogCategoryRepository = blogCategoryRepository;
37
+ this.blogCategoryTranslationRepository = blogCategoryTranslationRepository;
38
+ this.blogQueueService = blogQueueService;
39
+ this.configService = configService;
40
+ this.s3ClientKeys = s3ClientKeys;
41
+ this.descriptor = blog_category_1.BlogCategoryDescriptor;
42
+ }
43
+ async createFromDTO(params) {
44
+ // The controller validated the body against BlogCategoryPostDTO; the crud handler widens it to JsonApiDTOData.
45
+ const data = params.data;
46
+ const attributes = data.attributes;
47
+ // A client-sent image key is checked against the app's S3 key policy before it is stored and signed.
48
+ await this.s3ClientKeys?.assertClientKey({ key: attributes.image });
49
+ const originalLanguage = attributes.originalLanguage;
50
+ const supportedLanguages = this._supportedLanguages();
51
+ if (!supportedLanguages.includes(originalLanguage))
52
+ throw new common_1.BadRequestException(`Unsupported language: ${originalLanguage}`);
53
+ const slug = await this._uniqueSlug({ language: originalLanguage, text: attributes.name });
54
+ await this.blogCategoryRepository.createWithOriginal({
55
+ id: data.id,
56
+ originalLanguage,
57
+ image: attributes.image,
58
+ translation: {
59
+ id: (0, crypto_1.randomUUID)(),
60
+ name: attributes.name,
61
+ slug,
62
+ description: attributes.description,
63
+ },
64
+ });
65
+ await this._queue({
66
+ categoryId: data.id,
67
+ languages: supportedLanguages.filter((language) => language !== originalLanguage),
68
+ });
69
+ return this.findById({ id: data.id });
70
+ }
71
+ /**
72
+ * Updates the image and the original-language text. Translation re-runs only
73
+ * when the original's text changed. The slug follows the name unless the
74
+ * admin sets one explicitly.
75
+ */
76
+ async putFromDTO(params) {
77
+ // The controller validated the body against BlogCategoryPutDTO; the crud handler widens it to JsonApiDTOData.
78
+ const data = params.data;
79
+ const id = data.id;
80
+ const attributes = data.attributes;
81
+ // A client-sent image key is checked against the app's S3 key policy before it is stored and signed.
82
+ await this.s3ClientKeys?.assertClientKey({ key: attributes.image });
83
+ const category = await this.blogCategoryRepository.findById({ id });
84
+ if (!category)
85
+ throw new common_1.NotFoundException(`Blog category ${id} not found`);
86
+ const original = await this.blogCategoryTranslationRepository.findOriginal({ categoryId: id });
87
+ if (!original)
88
+ throw new common_1.NotFoundException(`Blog category ${id} has no original text`);
89
+ const textChanged = attributes.name !== original.name || (attributes.description ?? "") !== (original.description ?? "");
90
+ let slug = original.slug;
91
+ if (attributes.slug?.trim()) {
92
+ slug = await this._uniqueSlug({
93
+ language: category.originalLanguage,
94
+ text: attributes.slug,
95
+ excludeTranslationId: original.id,
96
+ });
97
+ }
98
+ else if (!slug || attributes.name !== original.name) {
99
+ slug = await this._uniqueSlug({
100
+ language: category.originalLanguage,
101
+ text: attributes.name,
102
+ excludeTranslationId: original.id,
103
+ });
104
+ }
105
+ // Omitted image = unchanged: the client only sends a key after a new upload.
106
+ await this.blogCategoryRepository.updateShared({ id, image: attributes.image ?? category.image });
107
+ await this.blogCategoryTranslationRepository.updateText({
108
+ id: original.id,
109
+ name: attributes.name,
110
+ slug,
111
+ description: attributes.description,
112
+ });
113
+ if (textChanged) {
114
+ await this._queue({
115
+ categoryId: id,
116
+ languages: this._supportedLanguages().filter((language) => language !== category.originalLanguage),
117
+ });
118
+ }
119
+ return this.findById({ id });
120
+ }
121
+ /** Deletes the category with every translation. */
122
+ async delete(params) {
123
+ const category = await this.blogCategoryRepository.findById({ id: params.id });
124
+ if (!category)
125
+ throw new common_1.NotFoundException(`Blog category ${params.id} not found`);
126
+ await this.blogCategoryRepository.deleteWithTranslations({ id: params.id });
127
+ }
128
+ async findPublicList(params) {
129
+ const data = await this.blogCategoryRepository.findPublicList({ language: params.language });
130
+ // The public list is every category, never a page: fetchAll keeps a spurious "next" link out of it.
131
+ const paginator = new jsonapi_paginator_1.JsonApiPaginator({ fetchAll: "true" });
132
+ return this.jsonApiService.buildList(blog_category_1.BlogCategoryDescriptor.model, data, paginator);
133
+ }
134
+ async _queue(params) {
135
+ if (params.languages.length === 0)
136
+ return;
137
+ await this.blogQueueService.enqueueCategory(params);
138
+ }
139
+ _supportedLanguages() {
140
+ return this.configService.get("i18n")?.supportedLanguages ?? ["en"];
141
+ }
142
+ async _uniqueSlug(params) {
143
+ const base = (0, slug_1.slugify)(params.text);
144
+ const taken = await this.blogCategoryTranslationRepository.findSlugsWithPrefix({
145
+ language: params.language,
146
+ prefix: base,
147
+ excludeTranslationId: params.excludeTranslationId,
148
+ });
149
+ return (0, slug_1.uniqueSlug)(base, taken);
150
+ }
151
+ };
152
+ exports.BlogCategoryService = BlogCategoryService;
153
+ exports.BlogCategoryService = BlogCategoryService = __decorate([
154
+ (0, common_1.Injectable)(),
155
+ __param(6, (0, common_1.Optional)()),
156
+ __metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
157
+ blog_category_repository_1.BlogCategoryRepository,
158
+ nestjs_cls_1.ClsService,
159
+ blog_category_translation_repository_1.BlogCategoryTranslationRepository,
160
+ blog_queue_service_1.BlogQueueService,
161
+ config_1.ConfigService,
162
+ s3_client_key_service_1.S3ClientKeyService])
163
+ ], BlogCategoryService);
164
+ //# sourceMappingURL=blog-category.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-category.service.js","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-category.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { ClsService } from "nestjs-cls";
2
+ import { BlockNoteService } from "../../../core/blocknote/services/blocknote.service";
3
+ import { JsonApiSingleDocument } from "../../../core/jsonapi/interfaces/jsonapi.document.interface";
4
+ import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
5
+ import { AbstractService } from "../../../core/neo4j/abstracts/abstract.service";
6
+ import { BlogPostTranslationPutDTO } from "../dtos/blog-post-translation.put.dto";
7
+ import { BlogPostTranslation, BlogPostTranslationDescriptor } from "../entities/blog-post-translation";
8
+ import { BlogPostTranslationRepository } from "../repositories/blog-post-translation.repository";
9
+ import { BlogQueueService } from "./blog-queue.service";
10
+ /**
11
+ * Hand edits to a non-original post translation, and "Translate again" for
12
+ * one language. The original is edited through BlogPostService only.
13
+ */
14
+ export declare class BlogPostTranslationService extends AbstractService<BlogPostTranslation, typeof BlogPostTranslationDescriptor.relationships> {
15
+ private readonly blogPostTranslationRepository;
16
+ private readonly blogQueueService;
17
+ private readonly blockNoteService;
18
+ protected readonly descriptor: import("../../..").EntityDescriptor<BlogPostTranslation, {
19
+ post: {
20
+ model: import("../../..").DataMeta;
21
+ direction: "in";
22
+ relationship: string;
23
+ cardinality: "one";
24
+ description: string;
25
+ };
26
+ }>;
27
+ constructor(jsonApiService: JsonApiService, blogPostTranslationRepository: BlogPostTranslationRepository, clsService: ClsService, blogQueueService: BlogQueueService, blockNoteService: BlockNoteService);
28
+ /**
29
+ * Saves this one translation and marks it `manual`. Nothing is re-run.
30
+ * The slug follows the post rule: kept once the post is published, unless the
31
+ * admin sets one explicitly.
32
+ */
33
+ updateTranslation(params: {
34
+ data: BlogPostTranslationPutDTO["data"];
35
+ }): Promise<JsonApiSingleDocument>;
36
+ /** Re-queues translation of this one language from the current original. */
37
+ retranslate(params: {
38
+ id: string;
39
+ }): Promise<void>;
40
+ private _findEditable;
41
+ private _plainText;
42
+ private _uniqueSlug;
43
+ }
44
+ //# sourceMappingURL=blog-post-translation.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-post-translation.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-post-translation.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6DAA6D,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AACvG,OAAO,EAAE,6BAA6B,EAAE,MAAM,kDAAkD,CAAC;AAGjG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;GAGG;AACH,qBACa,0BAA2B,SAAQ,eAAe,CAC7D,mBAAmB,EACnB,OAAO,6BAA6B,CAAC,aAAa,CACnD;IAKG,OAAO,CAAC,QAAQ,CAAC,6BAA6B;IAE9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAPnC,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;OAAiC;gBAG5D,cAAc,EAAE,cAAc,EACb,6BAA6B,EAAE,6BAA6B,EAC7E,UAAU,EAAE,UAAU,EACL,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,gBAAgB;IAKrD;;;;OAIG;IACG,iBAAiB,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAsC5G,4EAA4E;IACtE,WAAW,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAM1C,aAAa;IAQ3B,OAAO,CAAC,UAAU;YAQJ,WAAW;CAa1B"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.BlogPostTranslationService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const nestjs_cls_1 = require("nestjs-cls");
15
+ const blocknote_service_1 = require("../../../core/blocknote/services/blocknote.service");
16
+ const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
17
+ const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
18
+ const blog_post_translation_1 = require("../entities/blog-post-translation");
19
+ const blog_post_translation_repository_1 = require("../repositories/blog-post-translation.repository");
20
+ const reading_time_1 = require("../utils/reading-time");
21
+ const slug_1 = require("../utils/slug");
22
+ const blog_queue_service_1 = require("./blog-queue.service");
23
+ /**
24
+ * Hand edits to a non-original post translation, and "Translate again" for
25
+ * one language. The original is edited through BlogPostService only.
26
+ */
27
+ let BlogPostTranslationService = class BlogPostTranslationService extends abstract_service_1.AbstractService {
28
+ constructor(jsonApiService, blogPostTranslationRepository, clsService, blogQueueService, blockNoteService) {
29
+ super(jsonApiService, blogPostTranslationRepository, clsService, blog_post_translation_1.BlogPostTranslationDescriptor.model);
30
+ this.blogPostTranslationRepository = blogPostTranslationRepository;
31
+ this.blogQueueService = blogQueueService;
32
+ this.blockNoteService = blockNoteService;
33
+ this.descriptor = blog_post_translation_1.BlogPostTranslationDescriptor;
34
+ }
35
+ /**
36
+ * Saves this one translation and marks it `manual`. Nothing is re-run.
37
+ * The slug follows the post rule: kept once the post is published, unless the
38
+ * admin sets one explicitly.
39
+ */
40
+ async updateTranslation(params) {
41
+ const id = params.data.id;
42
+ const attributes = params.data.attributes;
43
+ const translation = await this._findEditable({ id });
44
+ let slug = translation.slug;
45
+ if (attributes.slug?.trim()) {
46
+ slug = await this._uniqueSlug({
47
+ language: translation.language,
48
+ text: attributes.slug,
49
+ excludeTranslationId: id,
50
+ });
51
+ }
52
+ else if (!slug || (translation.post?.status !== "published" && attributes.title !== translation.title)) {
53
+ slug = await this._uniqueSlug({
54
+ language: translation.language,
55
+ text: attributes.title,
56
+ excludeTranslationId: id,
57
+ });
58
+ }
59
+ const bodyText = this._plainText(attributes.body);
60
+ await this.blogPostTranslationRepository.updateText({
61
+ id,
62
+ title: attributes.title,
63
+ slug,
64
+ summary: attributes.summary?.trim() ? attributes.summary : undefined,
65
+ body: attributes.body,
66
+ bodyText,
67
+ coverImageAlt: attributes.coverImageAlt,
68
+ readingMinutes: (0, reading_time_1.readingMinutes)(bodyText),
69
+ source: "manual",
70
+ });
71
+ return this.findById({ id });
72
+ }
73
+ /** Re-queues translation of this one language from the current original. */
74
+ async retranslate(params) {
75
+ const translation = await this._findEditable({ id: params.id });
76
+ if (!translation.post?.id)
77
+ throw new common_1.NotFoundException(`Blog post translation ${params.id} has no post`);
78
+ await this.blogQueueService.enqueuePostLanguage({ postId: translation.post.id, language: translation.language });
79
+ }
80
+ async _findEditable(params) {
81
+ const translation = await this.blogPostTranslationRepository.findById({ id: params.id });
82
+ if (!translation)
83
+ throw new common_1.NotFoundException(`Blog post translation ${params.id} not found`);
84
+ if (translation.isOriginal)
85
+ throw new common_1.BadRequestException("The original is edited from the post, not as a translation");
86
+ return translation;
87
+ }
88
+ _plainText(body) {
89
+ try {
90
+ return this.blockNoteService.convertToPlainText({ nodes: JSON.parse(body) });
91
+ }
92
+ catch {
93
+ throw new common_1.BadRequestException("The body is not valid BlockNote JSON");
94
+ }
95
+ }
96
+ async _uniqueSlug(params) {
97
+ const base = (0, slug_1.slugify)(params.text);
98
+ const taken = await this.blogPostTranslationRepository.findSlugsWithPrefix({
99
+ language: params.language,
100
+ prefix: base,
101
+ excludeTranslationId: params.excludeTranslationId,
102
+ });
103
+ return (0, slug_1.uniqueSlug)(base, taken);
104
+ }
105
+ };
106
+ exports.BlogPostTranslationService = BlogPostTranslationService;
107
+ exports.BlogPostTranslationService = BlogPostTranslationService = __decorate([
108
+ (0, common_1.Injectable)(),
109
+ __metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
110
+ blog_post_translation_repository_1.BlogPostTranslationRepository,
111
+ nestjs_cls_1.ClsService,
112
+ blog_queue_service_1.BlogQueueService,
113
+ blocknote_service_1.BlockNoteService])
114
+ ], BlogPostTranslationService);
115
+ //# sourceMappingURL=blog-post-translation.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-post-translation.service.js","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-post-translation.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import { ConfigService } from "@nestjs/config";
2
+ import { ClsService } from "nestjs-cls";
3
+ import { BlockNoteService } from "../../../core/blocknote/services/blocknote.service";
4
+ import { JsonApiListDocument, JsonApiSingleDocument } from "../../../core/jsonapi/interfaces/jsonapi.document.interface";
5
+ import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
6
+ import { AbstractService, JsonApiDTOData } from "../../../core/neo4j/abstracts/abstract.service";
7
+ import { BlogPost, BlogPostDescriptor } from "../entities/blog-post";
8
+ import { BlogPostTranslationRepository } from "../repositories/blog-post-translation.repository";
9
+ import { BlogPostRepository } from "../repositories/blog-post.repository";
10
+ import { BlogQueueService } from "./blog-queue.service";
11
+ import { S3ClientKeyService } from "../../s3/services/s3-client-key.service";
12
+ /**
13
+ * Blog posts: admin writes (original language only), publishing, and the
14
+ * public reads that resolve one language per post.
15
+ */
16
+ export declare class BlogPostService extends AbstractService<BlogPost, typeof BlogPostDescriptor.relationships> {
17
+ private readonly blogPostRepository;
18
+ private readonly blogPostTranslationRepository;
19
+ private readonly blogQueueService;
20
+ private readonly blockNoteService;
21
+ private readonly configService;
22
+ private readonly s3ClientKeys?;
23
+ protected readonly descriptor: import("../../..").EntityDescriptor<BlogPost, {
24
+ author: {
25
+ model: import("../../..").DataMeta;
26
+ direction: "in";
27
+ relationship: string;
28
+ cardinality: "one";
29
+ description: string;
30
+ };
31
+ categories: {
32
+ model: import("../../..").DataMeta;
33
+ direction: "out";
34
+ relationship: string;
35
+ cardinality: "many";
36
+ required: false;
37
+ dtoKey: string;
38
+ description: string;
39
+ };
40
+ translations: {
41
+ model: import("../../..").DataMeta;
42
+ direction: "out";
43
+ relationship: string;
44
+ cardinality: "many";
45
+ required: false;
46
+ description: string;
47
+ };
48
+ }>;
49
+ constructor(jsonApiService: JsonApiService, blogPostRepository: BlogPostRepository, clsService: ClsService, blogPostTranslationRepository: BlogPostTranslationRepository, blogQueueService: BlogQueueService, blockNoteService: BlockNoteService, configService: ConfigService, s3ClientKeys?: S3ClientKeyService);
50
+ /**
51
+ * Creates a draft with its original-language text, then queues the summary
52
+ * (unless the admin wrote one) and the translation into every other language.
53
+ */
54
+ createFromDTO(params: {
55
+ data: JsonApiDTOData;
56
+ included?: unknown[];
57
+ }): Promise<JsonApiSingleDocument>;
58
+ /**
59
+ * Updates the shared fields and the original-language text.
60
+ *
61
+ * - A published post keeps its slugs when the title changes (old links keep
62
+ * working); an explicit `slug` is always applied.
63
+ * - Translation re-runs only when the original's text changed, and it
64
+ * overwrites hand-edited translations.
65
+ * - The summary is regenerated when the body changed and the admin did not
66
+ * edit the summary on this save, or when it was cleared.
67
+ */
68
+ putFromDTO(params: {
69
+ data: JsonApiDTOData;
70
+ included?: unknown[];
71
+ }): Promise<JsonApiSingleDocument>;
72
+ /** Deletes the post with every translation. */
73
+ delete(params: {
74
+ id: string;
75
+ }): Promise<void>;
76
+ /** Publishes (or republishes) a post. The first publish date is kept. */
77
+ publish(params: {
78
+ id: string;
79
+ }): Promise<JsonApiSingleDocument>;
80
+ unpublish(params: {
81
+ id: string;
82
+ }): Promise<JsonApiSingleDocument>;
83
+ findPublishedList(params: {
84
+ query: any;
85
+ language: string;
86
+ categorySlug?: string;
87
+ search?: string;
88
+ }): Promise<JsonApiListDocument>;
89
+ /** 404 for an unknown slug and for a draft or unpublished post. */
90
+ findPublishedBySlug(params: {
91
+ slug: string;
92
+ language: string;
93
+ }): Promise<JsonApiSingleDocument>;
94
+ findPublishedRelated(params: {
95
+ slug: string;
96
+ language: string;
97
+ }): Promise<JsonApiListDocument>;
98
+ private _queue;
99
+ private _supportedLanguages;
100
+ private _plainText;
101
+ private _categoryIds;
102
+ private _uniqueSlug;
103
+ /**
104
+ * Anonymous visitors set page[size] through the URL ("Load more" grows it), so the
105
+ * public list caps it: an unbounded size would let anyone force a full-table read.
106
+ */
107
+ private _clampPublicPageSize;
108
+ }
109
+ //# sourceMappingURL=blog-post.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-post.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-post.service.ts"],"names":[],"mappings":"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"}