@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,350 @@
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.BlogPostRepository = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const nestjs_cls_1 = require("nestjs-cls");
15
+ const ai_status_1 = require("../../../common/enums/ai.status");
16
+ const build_fulltext_term_1 = require("../../../core/neo4j/helpers/build-fulltext-term");
17
+ const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
18
+ const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
19
+ const security_service_1 = require("../../../core/security/services/security.service");
20
+ const user_meta_1 = require("../../user/entities/user.meta");
21
+ const blog_category_meta_1 = require("../entities/blog-category.meta");
22
+ const blog_category_translation_meta_1 = require("../entities/blog-category-translation.meta");
23
+ const blog_post_1 = require("../entities/blog-post");
24
+ const blog_post_meta_1 = require("../entities/blog-post.meta");
25
+ const blog_post_translation_1 = require("../entities/blog-post-translation");
26
+ const blog_post_translation_meta_1 = require("../entities/blog-post-translation.meta");
27
+ const post = blog_post_meta_1.blogPostMeta.nodeName;
28
+ const postLabel = blog_post_meta_1.blogPostMeta.labelName;
29
+ const translationLabel = blog_post_translation_meta_1.blogPostTranslationMeta.labelName;
30
+ const categoryLabel = blog_category_meta_1.blogCategoryMeta.labelName;
31
+ const categoryTranslationLabel = blog_category_translation_meta_1.blogCategoryTranslationMeta.labelName;
32
+ let BlogPostRepository = class BlogPostRepository extends abstract_repository_1.AbstractRepository {
33
+ constructor(neo4j, securityService, clsService) {
34
+ super(neo4j, securityService, clsService);
35
+ this.descriptor = blog_post_1.BlogPostDescriptor;
36
+ }
37
+ /**
38
+ * Admin list. A post has no text of its own (every string lives on its
39
+ * translations), so the inherited find would ignore `term`: a search matches
40
+ * any language version through the translation full-text index instead.
41
+ */
42
+ async find(params) {
43
+ if (!params.term)
44
+ return super.find(params);
45
+ const query = this.neo4j.initQuery({
46
+ cursor: params.cursor,
47
+ serialiser: blog_post_1.BlogPostDescriptor.model,
48
+ fetchAll: params.fetchAll,
49
+ });
50
+ query.queryParams = { ...query.queryParams, term: (0, build_fulltext_term_1.buildFulltextTerm)(params.term) };
51
+ query.query += `
52
+ CALL db.index.fulltext.queryNodes("${blog_post_translation_1.BlogPostTranslationDescriptor.fulltextIndexName}", $term) YIELD node, score
53
+ MATCH (${post}:${postLabel})-[:HAS_TRANSLATION]->(node)
54
+ WITH ${post}, max(score) AS score
55
+ CALL {
56
+ WITH ${post}
57
+ ${this.buildDefaultMatch()}
58
+ RETURN true AS ${post}_fulltextAccess
59
+ LIMIT 1
60
+ }
61
+ WITH ${post}, score
62
+ ORDER BY score DESC
63
+ {CURSOR}
64
+ ${this.buildReturnStatement()}
65
+ `;
66
+ return this.neo4j.readMany(query);
67
+ }
68
+ /**
69
+ * Resolves the translation a visitor reads into `t`: the translation in $language when its
70
+ * AI status is completed, otherwise the original. Pattern comprehensions, so the row count
71
+ * (and the ORDER BY applied later) never changes.
72
+ */
73
+ buildResolvedTranslation(carry = []) {
74
+ const carried = [post, ...carry].join(", ");
75
+ return `
76
+ WITH ${carried},
77
+ head([(${post})-[:HAS_TRANSLATION]->(localised:${translationLabel}) WHERE localised.language = $language AND localised.aiStatus = $completedStatus | localised]) AS localised
78
+ WITH ${carried},
79
+ coalesce(localised, head([(${post})-[:HAS_TRANSLATION]->(original:${translationLabel}) WHERE original.isOriginal = true | original])) AS t
80
+ `;
81
+ }
82
+ /**
83
+ * Public RETURN: the post node plus the resolved-language columns read by the descriptor's
84
+ * computed fields. Never returns the author User node (no email leak) nor translation nodes.
85
+ */
86
+ buildPublicReturn(params) {
87
+ return `
88
+ RETURN ${post},
89
+ t.language AS resolvedLanguage,
90
+ t.title AS resolvedTitle,
91
+ t.slug AS resolvedSlug,
92
+ t.summary AS resolvedSummary,
93
+ ${params.includeBody ? "t.body AS resolvedBody," : ""}
94
+ t.coverImageAlt AS resolvedCoverImageAlt,
95
+ t.readingMinutes AS resolvedReadingMinutes,
96
+ head([(${post})<-[:AUTHORED]-(writer:${user_meta_1.userMeta.labelName}) | writer.name]) AS authorName,
97
+ [(${post})-[:IN_BLOG_CATEGORY]->(postCategory:${categoryLabel}) | postCategory.id] AS categoryIds
98
+ `;
99
+ }
100
+ async createWithOriginal(params) {
101
+ await this.neo4j.executeInTransaction([
102
+ {
103
+ query: `
104
+ MATCH (author:${user_meta_1.userMeta.labelName} {id: $authorId})
105
+ CREATE (${post}:${postLabel} {
106
+ id: $id,
107
+ status: $status,
108
+ originalLanguage: $originalLanguage,
109
+ coverImage: $coverImage,
110
+ createdAt: datetime(),
111
+ updatedAt: datetime()
112
+ })
113
+ CREATE (author)-[:AUTHORED]->(${post})
114
+ `,
115
+ params: {
116
+ id: params.id,
117
+ authorId: params.authorId,
118
+ status: "draft",
119
+ originalLanguage: params.originalLanguage,
120
+ coverImage: params.coverImage ?? null,
121
+ },
122
+ },
123
+ {
124
+ query: `
125
+ MATCH (${post}:${postLabel} {id: $id})
126
+ CREATE (translation:${translationLabel} {
127
+ id: $translationId,
128
+ language: $originalLanguage,
129
+ isOriginal: true,
130
+ source: $source,
131
+ aiStatus: $aiStatus,
132
+ title: $title,
133
+ slug: $slug,
134
+ summary: $summary,
135
+ body: $body,
136
+ bodyText: $bodyText,
137
+ coverImageAlt: $coverImageAlt,
138
+ readingMinutes: $readingMinutes,
139
+ createdAt: datetime(),
140
+ updatedAt: datetime()
141
+ })
142
+ CREATE (${post})-[:HAS_TRANSLATION]->(translation)
143
+ `,
144
+ params: {
145
+ id: params.id,
146
+ translationId: params.translation.id,
147
+ originalLanguage: params.originalLanguage,
148
+ source: "original",
149
+ aiStatus: ai_status_1.AiStatus.Completed,
150
+ title: params.translation.title,
151
+ slug: params.translation.slug,
152
+ summary: params.translation.summary ?? null,
153
+ body: params.translation.body,
154
+ bodyText: params.translation.bodyText,
155
+ coverImageAlt: params.translation.coverImageAlt ?? null,
156
+ readingMinutes: params.translation.readingMinutes,
157
+ },
158
+ },
159
+ {
160
+ query: `
161
+ MATCH (${post}:${postLabel} {id: $id})
162
+ MATCH (category:${categoryLabel})
163
+ WHERE category.id IN $categoryIds
164
+ MERGE (${post})-[:IN_BLOG_CATEGORY]->(category)
165
+ `,
166
+ params: { id: params.id, categoryIds: params.categoryIds },
167
+ },
168
+ ]);
169
+ }
170
+ /**
171
+ * Full update of the language-independent fields: a missing coverImage clears it, and the
172
+ * category edges become exactly `categoryIds`.
173
+ */
174
+ async updateShared(params) {
175
+ await this.neo4j.executeInTransaction([
176
+ {
177
+ query: `
178
+ MATCH (${post}:${postLabel} {id: $id})
179
+ SET ${post}.coverImage = $coverImage, ${post}.updatedAt = datetime()
180
+ `,
181
+ params: { id: params.id, coverImage: params.coverImage ?? null },
182
+ },
183
+ {
184
+ query: `
185
+ MATCH (${post}:${postLabel} {id: $id})-[edge:IN_BLOG_CATEGORY]->(category:${categoryLabel})
186
+ WHERE NOT category.id IN $categoryIds
187
+ DELETE edge
188
+ `,
189
+ params: { id: params.id, categoryIds: params.categoryIds },
190
+ },
191
+ {
192
+ query: `
193
+ MATCH (${post}:${postLabel} {id: $id})
194
+ MATCH (category:${categoryLabel})
195
+ WHERE category.id IN $categoryIds
196
+ MERGE (${post})-[:IN_BLOG_CATEGORY]->(category)
197
+ `,
198
+ params: { id: params.id, categoryIds: params.categoryIds },
199
+ },
200
+ ]);
201
+ }
202
+ /**
203
+ * Sets the status. Publishing stamps publishedAt only the first time, so unpublish and
204
+ * republish keep the original date.
205
+ */
206
+ async setStatus(params) {
207
+ await this.neo4j.executeInTransaction([
208
+ {
209
+ query: `
210
+ MATCH (${post}:${postLabel} {id: $id})
211
+ SET ${post}.status = $status, ${post}.updatedAt = datetime()
212
+ ${params.status === "published" ? `SET ${post}.publishedAt = coalesce(${post}.publishedAt, datetime())` : ""}
213
+ `,
214
+ params: { id: params.id, status: params.status },
215
+ },
216
+ ]);
217
+ }
218
+ async deleteWithTranslations(params) {
219
+ await this.neo4j.executeInTransaction([
220
+ {
221
+ query: `
222
+ MATCH (${post}:${postLabel} {id: $id})
223
+ OPTIONAL MATCH (${post})-[:HAS_TRANSLATION]->(translation:${translationLabel})
224
+ WITH ${post}, collect(translation) AS translations
225
+ FOREACH (item IN translations | DETACH DELETE item)
226
+ DETACH DELETE ${post}
227
+ `,
228
+ params: { id: params.id },
229
+ },
230
+ ]);
231
+ }
232
+ /**
233
+ * Published posts in the visitor's language (original as fallback), newest first, optionally
234
+ * filtered by a category slug in any language and searched through the translation full-text
235
+ * index (only the resolved translation of each post can match).
236
+ */
237
+ async findPublished(params) {
238
+ const query = this.neo4j.initQuery({ serialiser: blog_post_1.BlogPostDescriptor.model, cursor: params.cursor });
239
+ query.queryParams = {
240
+ ...query.queryParams,
241
+ language: params.language,
242
+ completedStatus: ai_status_1.AiStatus.Completed,
243
+ ...(params.categorySlug ? { categorySlug: params.categorySlug } : {}),
244
+ ...(params.term ? { term: (0, build_fulltext_term_1.buildFulltextTerm)(params.term) } : {}),
245
+ };
246
+ const categoryFilter = params.categorySlug
247
+ ? `AND EXISTS {
248
+ MATCH (${post})-[:IN_BLOG_CATEGORY]->(:${categoryLabel})-[:HAS_TRANSLATION]->(:${categoryTranslationLabel} {slug: $categorySlug})
249
+ }`
250
+ : "";
251
+ if (params.term) {
252
+ query.query += `
253
+ CALL db.index.fulltext.queryNodes("${blog_post_translation_1.BlogPostTranslationDescriptor.fulltextIndexName}", $term)
254
+ YIELD node, score
255
+ MATCH (${post}:${postLabel})-[:HAS_TRANSLATION]->(node)
256
+ WITH ${post}, node, score
257
+ CALL {
258
+ WITH ${post}
259
+ ${this.buildDefaultMatch()}
260
+ RETURN true AS ${post}_fulltextAccess
261
+ LIMIT 1
262
+ }
263
+ WITH ${post}, node, score
264
+ WHERE ${post}.status = "published"
265
+ ${categoryFilter}
266
+ ${this.buildResolvedTranslation(["node", "score"])}
267
+ WITH ${post}, node, score, t
268
+ WHERE node = t
269
+ WITH ${post}, t, score
270
+ ORDER BY score DESC
271
+ `;
272
+ }
273
+ else {
274
+ query.query += `
275
+ ${this.buildDefaultMatch()}
276
+ WHERE ${post}.status = "published"
277
+ ${categoryFilter}
278
+ ${this.buildResolvedTranslation()}
279
+ WITH ${post}, t
280
+ ORDER BY ${post}.publishedAt DESC
281
+ `;
282
+ }
283
+ query.query += `
284
+ {CURSOR}
285
+ ${this.buildPublicReturn({ includeBody: false })}
286
+ `;
287
+ return this.neo4j.readMany(query);
288
+ }
289
+ /**
290
+ * One published post by a slug of ANY of its languages, with the text resolved in $language.
291
+ * When two posts share the slug in different languages, the one owning it in $language wins.
292
+ */
293
+ async findPublishedBySlug(params) {
294
+ const query = this.neo4j.initQuery({ serialiser: blog_post_1.BlogPostDescriptor.model });
295
+ query.queryParams = {
296
+ ...query.queryParams,
297
+ slug: params.slug,
298
+ language: params.language,
299
+ completedStatus: ai_status_1.AiStatus.Completed,
300
+ };
301
+ query.query += `
302
+ ${this.buildDefaultMatch()}
303
+ WHERE ${post}.status = "published"
304
+ AND EXISTS {
305
+ MATCH (${post})-[:HAS_TRANSLATION]->(:${translationLabel} {slug: $slug})
306
+ }
307
+ WITH ${post},
308
+ CASE WHEN EXISTS {
309
+ MATCH (${post})-[:HAS_TRANSLATION]->(:${translationLabel} {slug: $slug, language: $language})
310
+ } THEN 0 ELSE 1 END AS slugRank
311
+ ORDER BY slugRank ASC
312
+ LIMIT 1
313
+ ${this.buildResolvedTranslation()}
314
+ ${this.buildPublicReturn({ includeBody: true })}
315
+ `;
316
+ return this.neo4j.readOne(query);
317
+ }
318
+ /**
319
+ * Up to `limit` other published posts sharing a category with the given post, newest first.
320
+ */
321
+ async findPublishedRelated(params) {
322
+ const query = this.neo4j.initQuery({ serialiser: blog_post_1.BlogPostDescriptor.model, cursor: { take: params.limit } });
323
+ query.queryParams = {
324
+ ...query.queryParams,
325
+ postId: params.postId,
326
+ language: params.language,
327
+ completedStatus: ai_status_1.AiStatus.Completed,
328
+ };
329
+ query.query += `
330
+ ${this.buildDefaultMatch()}
331
+ WHERE ${post}.status = "published"
332
+ AND ${post}.id <> $postId
333
+ AND EXISTS {
334
+ MATCH (${post})-[:IN_BLOG_CATEGORY]->(:${categoryLabel})<-[:IN_BLOG_CATEGORY]-(:${postLabel} {id: $postId})
335
+ }
336
+ ${this.buildResolvedTranslation()}
337
+ WITH ${post}, t
338
+ ORDER BY ${post}.publishedAt DESC
339
+ {CURSOR}
340
+ ${this.buildPublicReturn({ includeBody: false })}
341
+ `;
342
+ return this.neo4j.readManyWithoutCount(query);
343
+ }
344
+ };
345
+ exports.BlogPostRepository = BlogPostRepository;
346
+ exports.BlogPostRepository = BlogPostRepository = __decorate([
347
+ (0, common_1.Injectable)(),
348
+ __metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
349
+ ], BlogPostRepository);
350
+ //# sourceMappingURL=blog-post.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-post.repository.js","sourceRoot":"","sources":["../../../../src/foundations/blog/repositories/blog-post.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { ClsService } from "nestjs-cls";
2
+ import { AbstractRepository } from "../../../core/neo4j/abstracts/abstract.repository";
3
+ import { Neo4jService } from "../../../core/neo4j/services/neo4j.service";
4
+ import { SecurityService } from "../../../core/security/services/security.service";
5
+ import { BlogListLayout } from "../blog.constants";
6
+ import { BlogSettings, BlogSettingsDescriptor } from "../entities/blog-settings";
7
+ export declare class BlogSettingsRepository extends AbstractRepository<BlogSettings, typeof BlogSettingsDescriptor.relationships> {
8
+ protected readonly descriptor: import("../../..").EntityDescriptor<BlogSettings, {}>;
9
+ constructor(neo4j: Neo4jService, securityService: SecurityService, clsService: ClsService);
10
+ /**
11
+ * The single settings node, or null when it was never saved.
12
+ */
13
+ findSettings(): Promise<BlogSettings | null>;
14
+ /**
15
+ * Creates or updates the single settings node, always on BLOG_SETTINGS_ID.
16
+ */
17
+ upsert(params: {
18
+ listLayout: BlogListLayout;
19
+ }): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=blog-settings.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-settings.repository.d.ts","sourceRoot":"","sources":["../../../../src/foundations/blog/repositories/blog-settings.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACnF,OAAO,EAAoB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKjF,qBACa,sBAAuB,SAAQ,kBAAkB,CAC5D,YAAY,EACZ,OAAO,sBAAsB,CAAC,aAAa,CAC5C;IACC,SAAS,CAAC,QAAQ,CAAC,UAAU,wDAA0B;gBAE3C,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU;IAIzF;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAalD;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAYpE"}
@@ -0,0 +1,60 @@
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.BlogSettingsRepository = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const nestjs_cls_1 = require("nestjs-cls");
15
+ const abstract_repository_1 = require("../../../core/neo4j/abstracts/abstract.repository");
16
+ const neo4j_service_1 = require("../../../core/neo4j/services/neo4j.service");
17
+ const security_service_1 = require("../../../core/security/services/security.service");
18
+ const blog_constants_1 = require("../blog.constants");
19
+ const blog_settings_1 = require("../entities/blog-settings");
20
+ const blog_settings_meta_1 = require("../entities/blog-settings.meta");
21
+ const settings = blog_settings_meta_1.blogSettingsMeta.nodeName;
22
+ let BlogSettingsRepository = class BlogSettingsRepository extends abstract_repository_1.AbstractRepository {
23
+ constructor(neo4j, securityService, clsService) {
24
+ super(neo4j, securityService, clsService);
25
+ this.descriptor = blog_settings_1.BlogSettingsDescriptor;
26
+ }
27
+ /**
28
+ * The single settings node, or null when it was never saved.
29
+ */
30
+ async findSettings() {
31
+ const query = this.neo4j.initQuery({ serialiser: blog_settings_1.BlogSettingsDescriptor.model });
32
+ query.queryParams = { ...query.queryParams, searchValue: blog_constants_1.BLOG_SETTINGS_ID };
33
+ query.query += `
34
+ ${this.buildDefaultMatch({ searchField: "id" })}
35
+ ${this.buildReturnStatement()}
36
+ `;
37
+ return this.neo4j.readOne(query);
38
+ }
39
+ /**
40
+ * Creates or updates the single settings node, always on BLOG_SETTINGS_ID.
41
+ */
42
+ async upsert(params) {
43
+ await this.neo4j.executeInTransaction([
44
+ {
45
+ query: `
46
+ MERGE (${settings}:${blog_settings_meta_1.blogSettingsMeta.labelName} {id: $id})
47
+ ON CREATE SET ${settings}.createdAt = datetime()
48
+ SET ${settings}.listLayout = $listLayout, ${settings}.updatedAt = datetime()
49
+ `,
50
+ params: { id: blog_constants_1.BLOG_SETTINGS_ID, listLayout: params.listLayout },
51
+ },
52
+ ]);
53
+ }
54
+ };
55
+ exports.BlogSettingsRepository = BlogSettingsRepository;
56
+ exports.BlogSettingsRepository = BlogSettingsRepository = __decorate([
57
+ (0, common_1.Injectable)(),
58
+ __metadata("design:paramtypes", [neo4j_service_1.Neo4jService, security_service_1.SecurityService, nestjs_cls_1.ClsService])
59
+ ], BlogSettingsRepository);
60
+ //# sourceMappingURL=blog-settings.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-settings.repository.js","sourceRoot":"","sources":["../../../../src/foundations/blog/repositories/blog-settings.repository.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,2CAAwC;AACxC,2FAAuF;AACvF,8EAA0E;AAC1E,uFAAmF;AACnF,sDAAqE;AACrE,6DAAiF;AACjF,uEAAkE;AAElE,MAAM,QAAQ,GAAG,qCAAgB,CAAC,QAAQ,CAAC;AAGpC,IAAM,sBAAsB,GAA5B,MAAM,sBAAuB,SAAQ,wCAG3C;IAGC,YAAY,KAAmB,EAAE,eAAgC,EAAE,UAAsB;QACvF,KAAK,CAAC,KAAK,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;QAHzB,eAAU,GAAG,sCAAsB,CAAC;IAIvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,sCAAsB,CAAC,KAAK,EAAE,CAAC,CAAC;QAEjF,KAAK,CAAC,WAAW,GAAG,EAAE,GAAG,KAAK,CAAC,WAAW,EAAE,WAAW,EAAE,iCAAgB,EAAE,CAAC;QAE5E,KAAK,CAAC,KAAK,IAAI;QACX,IAAI,CAAC,iBAAiB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,oBAAoB,EAAE;KAC9B,CAAC;QAEF,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,MAAsC;QACjD,MAAM,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC;YACpC;gBACE,KAAK,EAAE;mBACI,QAAQ,IAAI,qCAAgB,CAAC,SAAS;0BAC/B,QAAQ;gBAClB,QAAQ,8BAA8B,QAAQ;SACrD;gBACD,MAAM,EAAE,EAAE,EAAE,EAAE,iCAAgB,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE;aAChE;SACF,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAzCY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAOQ,4BAAY,EAAmB,kCAAe,EAAc,uBAAU;GAN9E,sBAAsB,CAyClC"}
@@ -0,0 +1,37 @@
1
+ import { ClsService } from "nestjs-cls";
2
+ import { JsonApiSingleDocument } from "../../../core/jsonapi/interfaces/jsonapi.document.interface";
3
+ import { JsonApiService } from "../../../core/jsonapi/services/jsonapi.service";
4
+ import { AbstractService } from "../../../core/neo4j/abstracts/abstract.service";
5
+ import { BlogCategoryTranslationPutDTO } from "../dtos/blog-category-translation.put.dto";
6
+ import { BlogCategoryTranslation, BlogCategoryTranslationDescriptor } from "../entities/blog-category-translation";
7
+ import { BlogCategoryTranslationRepository } from "../repositories/blog-category-translation.repository";
8
+ import { BlogQueueService } from "./blog-queue.service";
9
+ /**
10
+ * Hand edits to a non-original category translation, and "Translate again"
11
+ * for one language. The original is edited through BlogCategoryService only.
12
+ */
13
+ export declare class BlogCategoryTranslationService extends AbstractService<BlogCategoryTranslation, typeof BlogCategoryTranslationDescriptor.relationships> {
14
+ private readonly blogCategoryTranslationRepository;
15
+ private readonly blogQueueService;
16
+ protected readonly descriptor: import("../../..").EntityDescriptor<BlogCategoryTranslation, {
17
+ category: {
18
+ model: import("../../..").DataMeta;
19
+ direction: "in";
20
+ relationship: string;
21
+ cardinality: "one";
22
+ description: string;
23
+ };
24
+ }>;
25
+ constructor(jsonApiService: JsonApiService, blogCategoryTranslationRepository: BlogCategoryTranslationRepository, clsService: ClsService, blogQueueService: BlogQueueService);
26
+ /** Saves this one translation and marks it `manual`. Nothing is re-run. */
27
+ updateTranslation(params: {
28
+ data: BlogCategoryTranslationPutDTO["data"];
29
+ }): Promise<JsonApiSingleDocument>;
30
+ /** Re-queues translation of this one language from the current original. */
31
+ retranslate(params: {
32
+ id: string;
33
+ }): Promise<void>;
34
+ private _findEditable;
35
+ private _uniqueSlug;
36
+ }
37
+ //# sourceMappingURL=blog-category-translation.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-category-translation.service.d.ts","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-category-translation.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,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,6BAA6B,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AACnH,OAAO,EAAE,iCAAiC,EAAE,MAAM,sDAAsD,CAAC;AAEzG,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;GAGG;AACH,qBACa,8BAA+B,SAAQ,eAAe,CACjE,uBAAuB,EACvB,OAAO,iCAAiC,CAAC,aAAa,CACvD;IAKG,OAAO,CAAC,QAAQ,CAAC,iCAAiC;IAElD,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IANnC,SAAS,CAAC,QAAQ,CAAC,UAAU;;;;;;;;OAAqC;gBAGhE,cAAc,EAAE,cAAc,EACb,iCAAiC,EAAE,iCAAiC,EACrF,UAAU,EAAE,UAAU,EACL,gBAAgB,EAAE,gBAAgB;IAKrD,2EAA2E;IACrE,iBAAiB,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,6BAA6B,CAAC,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAgChH,4EAA4E;IACtE,WAAW,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAU1C,aAAa;YAQb,WAAW;CAa1B"}
@@ -0,0 +1,97 @@
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.BlogCategoryTranslationService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const nestjs_cls_1 = require("nestjs-cls");
15
+ const jsonapi_service_1 = require("../../../core/jsonapi/services/jsonapi.service");
16
+ const abstract_service_1 = require("../../../core/neo4j/abstracts/abstract.service");
17
+ const blog_category_translation_1 = require("../entities/blog-category-translation");
18
+ const blog_category_translation_repository_1 = require("../repositories/blog-category-translation.repository");
19
+ const slug_1 = require("../utils/slug");
20
+ const blog_queue_service_1 = require("./blog-queue.service");
21
+ /**
22
+ * Hand edits to a non-original category translation, and "Translate again"
23
+ * for one language. The original is edited through BlogCategoryService only.
24
+ */
25
+ let BlogCategoryTranslationService = class BlogCategoryTranslationService extends abstract_service_1.AbstractService {
26
+ constructor(jsonApiService, blogCategoryTranslationRepository, clsService, blogQueueService) {
27
+ super(jsonApiService, blogCategoryTranslationRepository, clsService, blog_category_translation_1.BlogCategoryTranslationDescriptor.model);
28
+ this.blogCategoryTranslationRepository = blogCategoryTranslationRepository;
29
+ this.blogQueueService = blogQueueService;
30
+ this.descriptor = blog_category_translation_1.BlogCategoryTranslationDescriptor;
31
+ }
32
+ /** Saves this one translation and marks it `manual`. Nothing is re-run. */
33
+ async updateTranslation(params) {
34
+ const id = params.data.id;
35
+ const attributes = params.data.attributes;
36
+ const translation = await this._findEditable({ id });
37
+ let slug = translation.slug;
38
+ if (attributes.slug?.trim()) {
39
+ slug = await this._uniqueSlug({
40
+ language: translation.language,
41
+ text: attributes.slug,
42
+ excludeTranslationId: id,
43
+ });
44
+ }
45
+ else if (!slug || attributes.name !== translation.name) {
46
+ slug = await this._uniqueSlug({
47
+ language: translation.language,
48
+ text: attributes.name,
49
+ excludeTranslationId: id,
50
+ });
51
+ }
52
+ await this.blogCategoryTranslationRepository.updateText({
53
+ id,
54
+ name: attributes.name,
55
+ slug,
56
+ description: attributes.description,
57
+ source: "manual",
58
+ });
59
+ return this.findById({ id });
60
+ }
61
+ /** Re-queues translation of this one language from the current original. */
62
+ async retranslate(params) {
63
+ const translation = await this._findEditable({ id: params.id });
64
+ if (!translation.category?.id)
65
+ throw new common_1.NotFoundException(`Blog category translation ${params.id} has no category`);
66
+ await this.blogQueueService.enqueueCategoryLanguage({
67
+ categoryId: translation.category.id,
68
+ language: translation.language,
69
+ });
70
+ }
71
+ async _findEditable(params) {
72
+ const translation = await this.blogCategoryTranslationRepository.findById({ id: params.id });
73
+ if (!translation)
74
+ throw new common_1.NotFoundException(`Blog category translation ${params.id} not found`);
75
+ if (translation.isOriginal)
76
+ throw new common_1.BadRequestException("The original is edited from the category, not as a translation");
77
+ return translation;
78
+ }
79
+ async _uniqueSlug(params) {
80
+ const base = (0, slug_1.slugify)(params.text);
81
+ const taken = await this.blogCategoryTranslationRepository.findSlugsWithPrefix({
82
+ language: params.language,
83
+ prefix: base,
84
+ excludeTranslationId: params.excludeTranslationId,
85
+ });
86
+ return (0, slug_1.uniqueSlug)(base, taken);
87
+ }
88
+ };
89
+ exports.BlogCategoryTranslationService = BlogCategoryTranslationService;
90
+ exports.BlogCategoryTranslationService = BlogCategoryTranslationService = __decorate([
91
+ (0, common_1.Injectable)(),
92
+ __metadata("design:paramtypes", [jsonapi_service_1.JsonApiService,
93
+ blog_category_translation_repository_1.BlogCategoryTranslationRepository,
94
+ nestjs_cls_1.ClsService,
95
+ blog_queue_service_1.BlogQueueService])
96
+ ], BlogCategoryTranslationService);
97
+ //# sourceMappingURL=blog-category-translation.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blog-category-translation.service.js","sourceRoot":"","sources":["../../../../src/foundations/blog/services/blog-category-translation.service.ts"],"names":[],"mappings":"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"}