@s-hirano-ist/s-core 1.2.0 → 1.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 (166) hide show
  1. package/dist/articles/entities/article-entity.d.ts +342 -11
  2. package/dist/articles/entities/article-entity.d.ts.map +1 -1
  3. package/dist/articles/entities/article-entity.js +295 -9
  4. package/dist/articles/entities/article-entity.js.map +1 -1
  5. package/dist/articles/events/article-created-event.d.ts +36 -0
  6. package/dist/articles/events/article-created-event.d.ts.map +1 -1
  7. package/dist/articles/events/article-created-event.js +36 -0
  8. package/dist/articles/events/article-created-event.js.map +1 -1
  9. package/dist/articles/events/article-deleted-event.d.ts +30 -0
  10. package/dist/articles/events/article-deleted-event.d.ts.map +1 -1
  11. package/dist/articles/events/article-deleted-event.js +30 -0
  12. package/dist/articles/events/article-deleted-event.js.map +1 -1
  13. package/dist/articles/index.d.ts +33 -0
  14. package/dist/articles/index.d.ts.map +1 -1
  15. package/dist/articles/index.js +33 -0
  16. package/dist/articles/index.js.map +1 -1
  17. package/dist/articles/repositories/articles-command-repository.interface.d.ts +37 -0
  18. package/dist/articles/repositories/articles-command-repository.interface.d.ts.map +1 -1
  19. package/dist/articles/repositories/articles-query-repository.interface.d.ts +53 -0
  20. package/dist/articles/repositories/articles-query-repository.interface.d.ts.map +1 -1
  21. package/dist/articles/repositories/category-query-repository.interface.d.ts +29 -0
  22. package/dist/articles/repositories/category-query-repository.interface.d.ts.map +1 -1
  23. package/dist/articles/services/articles-domain-service.d.ts +40 -0
  24. package/dist/articles/services/articles-domain-service.d.ts.map +1 -1
  25. package/dist/articles/services/articles-domain-service.js +50 -0
  26. package/dist/articles/services/articles-domain-service.js.map +1 -1
  27. package/dist/articles/types/cache-strategy.d.ts +19 -0
  28. package/dist/articles/types/cache-strategy.d.ts.map +1 -1
  29. package/dist/articles/types/query-params.d.ts +83 -5
  30. package/dist/articles/types/query-params.d.ts.map +1 -1
  31. package/dist/articles/types/sort-order.d.ts +12 -0
  32. package/dist/articles/types/sort-order.d.ts.map +1 -1
  33. package/dist/books/entities/books-entity.d.ts +348 -13
  34. package/dist/books/entities/books-entity.d.ts.map +1 -1
  35. package/dist/books/entities/books-entity.js +296 -11
  36. package/dist/books/entities/books-entity.js.map +1 -1
  37. package/dist/books/events/book-created-event.d.ts +32 -0
  38. package/dist/books/events/book-created-event.d.ts.map +1 -1
  39. package/dist/books/events/book-created-event.js +32 -0
  40. package/dist/books/events/book-created-event.js.map +1 -1
  41. package/dist/books/events/book-deleted-event.d.ts +30 -0
  42. package/dist/books/events/book-deleted-event.d.ts.map +1 -1
  43. package/dist/books/events/book-deleted-event.js +30 -0
  44. package/dist/books/events/book-deleted-event.js.map +1 -1
  45. package/dist/books/index.d.ts +33 -0
  46. package/dist/books/index.d.ts.map +1 -1
  47. package/dist/books/index.js +33 -0
  48. package/dist/books/index.js.map +1 -1
  49. package/dist/books/repositories/books-command-repository.interface.d.ts +45 -0
  50. package/dist/books/repositories/books-command-repository.interface.d.ts.map +1 -1
  51. package/dist/books/repositories/books-query-repository.interface.d.ts +53 -0
  52. package/dist/books/repositories/books-query-repository.interface.d.ts.map +1 -1
  53. package/dist/books/services/books-domain-service.d.ts +40 -0
  54. package/dist/books/services/books-domain-service.d.ts.map +1 -1
  55. package/dist/books/services/books-domain-service.js +50 -0
  56. package/dist/books/services/books-domain-service.js.map +1 -1
  57. package/dist/books/types/cache-strategy.d.ts +19 -0
  58. package/dist/books/types/cache-strategy.d.ts.map +1 -1
  59. package/dist/books/types/query-params.d.ts +44 -3
  60. package/dist/books/types/query-params.d.ts.map +1 -1
  61. package/dist/books/types/sort-order.d.ts +12 -0
  62. package/dist/books/types/sort-order.d.ts.map +1 -1
  63. package/dist/common/entities/common-entity.d.ts +282 -2
  64. package/dist/common/entities/common-entity.d.ts.map +1 -1
  65. package/dist/common/entities/common-entity.js +235 -2
  66. package/dist/common/entities/common-entity.js.map +1 -1
  67. package/dist/common/events/base-domain-event.d.ts +32 -0
  68. package/dist/common/events/base-domain-event.d.ts.map +1 -1
  69. package/dist/common/events/base-domain-event.js +32 -0
  70. package/dist/common/events/base-domain-event.js.map +1 -1
  71. package/dist/common/events/domain-event.interface.d.ts +54 -0
  72. package/dist/common/events/domain-event.interface.d.ts.map +1 -1
  73. package/dist/common/events/system-error-event.d.ts +36 -0
  74. package/dist/common/events/system-error-event.d.ts.map +1 -1
  75. package/dist/common/events/system-error-event.js +36 -0
  76. package/dist/common/events/system-error-event.js.map +1 -1
  77. package/dist/common/events/system-warning-event.d.ts +35 -0
  78. package/dist/common/events/system-warning-event.d.ts.map +1 -1
  79. package/dist/common/events/system-warning-event.js +35 -0
  80. package/dist/common/events/system-warning-event.js.map +1 -1
  81. package/dist/common/index.d.ts +23 -0
  82. package/dist/common/index.d.ts.map +1 -1
  83. package/dist/common/index.js +23 -0
  84. package/dist/common/index.js.map +1 -1
  85. package/dist/common/services/entity-factory.d.ts +27 -0
  86. package/dist/common/services/entity-factory.d.ts.map +1 -1
  87. package/dist/common/services/entity-factory.js +27 -0
  88. package/dist/common/services/entity-factory.js.map +1 -1
  89. package/dist/common/services/id-generator.d.ts +32 -0
  90. package/dist/common/services/id-generator.d.ts.map +1 -1
  91. package/dist/common/services/id-generator.js +32 -0
  92. package/dist/common/services/id-generator.js.map +1 -1
  93. package/dist/errors/error-classes.d.ts +83 -0
  94. package/dist/errors/error-classes.d.ts.map +1 -1
  95. package/dist/errors/error-classes.js +83 -0
  96. package/dist/errors/error-classes.js.map +1 -1
  97. package/dist/errors/index.d.ts +29 -0
  98. package/dist/errors/index.d.ts.map +1 -1
  99. package/dist/errors/index.js +29 -0
  100. package/dist/errors/index.js.map +1 -1
  101. package/dist/images/entities/image-entity.d.ts +373 -4
  102. package/dist/images/entities/image-entity.d.ts.map +1 -1
  103. package/dist/images/entities/image-entity.js +320 -3
  104. package/dist/images/entities/image-entity.js.map +1 -1
  105. package/dist/images/events/image-created-event.d.ts +30 -0
  106. package/dist/images/events/image-created-event.d.ts.map +1 -1
  107. package/dist/images/events/image-created-event.js +30 -0
  108. package/dist/images/events/image-created-event.js.map +1 -1
  109. package/dist/images/events/image-deleted-event.d.ts +30 -0
  110. package/dist/images/events/image-deleted-event.d.ts.map +1 -1
  111. package/dist/images/events/image-deleted-event.js +30 -0
  112. package/dist/images/events/image-deleted-event.js.map +1 -1
  113. package/dist/images/index.d.ts +35 -0
  114. package/dist/images/index.d.ts.map +1 -1
  115. package/dist/images/index.js +35 -0
  116. package/dist/images/index.js.map +1 -1
  117. package/dist/images/repositories/images-command-repository.interface.d.ts +43 -0
  118. package/dist/images/repositories/images-command-repository.interface.d.ts.map +1 -1
  119. package/dist/images/repositories/images-query-repository.interface.d.ts +59 -0
  120. package/dist/images/repositories/images-query-repository.interface.d.ts.map +1 -1
  121. package/dist/images/services/images-domain-service.d.ts +40 -0
  122. package/dist/images/services/images-domain-service.d.ts.map +1 -1
  123. package/dist/images/services/images-domain-service.js +50 -0
  124. package/dist/images/services/images-domain-service.js.map +1 -1
  125. package/dist/images/types/cache-strategy.d.ts +19 -0
  126. package/dist/images/types/cache-strategy.d.ts.map +1 -1
  127. package/dist/images/types/query-params.d.ts +44 -3
  128. package/dist/images/types/query-params.d.ts.map +1 -1
  129. package/dist/images/types/sort-order.d.ts +12 -0
  130. package/dist/images/types/sort-order.d.ts.map +1 -1
  131. package/dist/index.d.ts +30 -0
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +30 -0
  134. package/dist/index.js.map +1 -1
  135. package/dist/notes/entities/note-entity.d.ts +212 -6
  136. package/dist/notes/entities/note-entity.d.ts.map +1 -1
  137. package/dist/notes/entities/note-entity.js +182 -4
  138. package/dist/notes/entities/note-entity.js.map +1 -1
  139. package/dist/notes/events/note-created-event.d.ts +32 -0
  140. package/dist/notes/events/note-created-event.d.ts.map +1 -1
  141. package/dist/notes/events/note-created-event.js +32 -0
  142. package/dist/notes/events/note-created-event.js.map +1 -1
  143. package/dist/notes/events/note-deleted-event.d.ts +30 -0
  144. package/dist/notes/events/note-deleted-event.d.ts.map +1 -1
  145. package/dist/notes/events/note-deleted-event.js +30 -0
  146. package/dist/notes/events/note-deleted-event.js.map +1 -1
  147. package/dist/notes/index.d.ts +32 -0
  148. package/dist/notes/index.d.ts.map +1 -1
  149. package/dist/notes/index.js +32 -0
  150. package/dist/notes/index.js.map +1 -1
  151. package/dist/notes/repositories/notes-command-repository.interface.d.ts +37 -0
  152. package/dist/notes/repositories/notes-command-repository.interface.d.ts.map +1 -1
  153. package/dist/notes/repositories/notes-query-repository.interface.d.ts +53 -0
  154. package/dist/notes/repositories/notes-query-repository.interface.d.ts.map +1 -1
  155. package/dist/notes/services/notes-domain-service.d.ts +40 -0
  156. package/dist/notes/services/notes-domain-service.d.ts.map +1 -1
  157. package/dist/notes/services/notes-domain-service.js +50 -0
  158. package/dist/notes/services/notes-domain-service.js.map +1 -1
  159. package/dist/notes/types/cache-strategy.d.ts +19 -0
  160. package/dist/notes/types/cache-strategy.d.ts.map +1 -1
  161. package/dist/notes/types/query-params.d.ts +44 -3
  162. package/dist/notes/types/query-params.d.ts.map +1 -1
  163. package/dist/notes/types/sort-order.d.ts +12 -0
  164. package/dist/notes/types/sort-order.d.ts.map +1 -1
  165. package/dist/tsconfig.tsbuildinfo +1 -1
  166. package/package.json +1 -1
@@ -1,7 +1,44 @@
1
1
  import type { Id, Status, UserId } from "../../common/entities/common-entity";
2
2
  import type { UnexportedArticle } from "../entities/article-entity";
3
+ /**
4
+ * Command repository interface for the Article domain.
5
+ *
6
+ * @remarks
7
+ * Follows the CQRS pattern - this interface handles write operations only.
8
+ * Implementations should be provided by the infrastructure layer (e.g., Prisma).
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Infrastructure implementation
13
+ * class PrismaArticlesCommandRepository implements IArticlesCommandRepository {
14
+ * async create(data: UnexportedArticle) {
15
+ * await prisma.article.create({ data });
16
+ * }
17
+ *
18
+ * async deleteById(id: Id, userId: UserId, status: Status) {
19
+ * await prisma.article.delete({
20
+ * where: { id, userId, status }
21
+ * });
22
+ * }
23
+ * }
24
+ * ```
25
+ *
26
+ * @see {@link IArticlesQueryRepository} for read operations
27
+ */
3
28
  export type IArticlesCommandRepository = {
29
+ /**
30
+ * Creates a new article in the repository.
31
+ *
32
+ * @param data - The unexported article entity to persist
33
+ */
4
34
  create(data: UnexportedArticle): Promise<void>;
35
+ /**
36
+ * Deletes an article by its ID.
37
+ *
38
+ * @param id - The article ID to delete
39
+ * @param userId - The user ID for tenant isolation
40
+ * @param status - The expected status of the article
41
+ */
5
42
  deleteById(id: Id, userId: UserId, status: Status): Promise<void>;
6
43
  };
7
44
  //# sourceMappingURL=articles-command-repository.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"articles-command-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/articles-command-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACxC,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE,CAAC"}
1
+ {"version":3,"file":"articles-command-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/articles-command-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACxC;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE,CAAC"}
@@ -1,7 +1,35 @@
1
1
  import type { Status, UserId } from "../../common/entities/common-entity";
2
2
  import type { Url } from "../entities/article-entity";
3
3
  import type { ArticlesFindManyParams } from "../types/query-params";
4
+ /**
5
+ * Query repository interface for the Article domain.
6
+ *
7
+ * @remarks
8
+ * Follows the CQRS pattern - this interface handles read operations only.
9
+ * Implementations should be provided by the infrastructure layer (e.g., Prisma).
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Infrastructure implementation
14
+ * class PrismaArticlesQueryRepository implements IArticlesQueryRepository {
15
+ * async findByUrl(url: Url, userId: UserId) {
16
+ * return await prisma.article.findUnique({
17
+ * where: { url, userId }
18
+ * });
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * @see {@link IArticlesCommandRepository} for write operations
24
+ */
4
25
  export type IArticlesQueryRepository = {
26
+ /**
27
+ * Finds an article by its URL for a specific user.
28
+ *
29
+ * @param url - The validated URL to search for
30
+ * @param userId - The user ID for tenant isolation
31
+ * @returns The article data if found, null otherwise
32
+ */
5
33
  findByUrl(url: Url, userId: UserId): Promise<{
6
34
  title: string;
7
35
  url: string;
@@ -15,6 +43,16 @@ export type IArticlesQueryRepository = {
15
43
  name: string;
16
44
  };
17
45
  } | null>;
46
+ /**
47
+ * Retrieves multiple articles with pagination and filtering.
48
+ *
49
+ * @param userId - The user ID for tenant isolation
50
+ * @param status - Filter by UNEXPORTED or EXPORTED status
51
+ * @param params - Pagination, sorting, and caching parameters
52
+ * @returns Array of article data objects
53
+ *
54
+ * @see {@link ArticlesFindManyParams} for parameter options
55
+ */
18
56
  findMany(userId: UserId, status: Status, params: ArticlesFindManyParams): Promise<{
19
57
  id: string;
20
58
  title: string;
@@ -27,7 +65,22 @@ export type IArticlesQueryRepository = {
27
65
  name: string;
28
66
  };
29
67
  }[]>;
68
+ /**
69
+ * Counts articles matching the given criteria.
70
+ *
71
+ * @param userId - The user ID for tenant isolation
72
+ * @param status - Filter by status
73
+ * @returns The count of matching articles
74
+ */
30
75
  count(userId: UserId, status: Status): Promise<number>;
76
+ /**
77
+ * Searches articles by text query.
78
+ *
79
+ * @param query - The search query string
80
+ * @param userId - The user ID for tenant isolation
81
+ * @param limit - Optional maximum number of results (default varies by implementation)
82
+ * @returns Array of matching article data objects
83
+ */
31
84
  search(query: string, userId: UserId, limit?: number): Promise<{
32
85
  id: string;
33
86
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"articles-query-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/articles-query-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,MAAM,wBAAwB,GAAG;IACtC,SAAS,CACR,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE;YACT,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;SACb,CAAC;KACF,GAAG,IAAI,CAAC,CAAC;IACV,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,sBAAsB,GAC5B,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,EAAE;YACT,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;SACb,CAAC;KACF,EAAE,CACH,CAAC;IACF,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvC,EAAE,CACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"articles-query-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/articles-query-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACtC;;;;;;OAMG;IACH,SAAS,CACR,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QACV,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE;YACT,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;SACb,CAAC;KACF,GAAG,IAAI,CAAC,CAAC;IAEV;;;;;;;;;OASG;IACH,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,sBAAsB,GAC5B,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,EAAE;YACT,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;SACb,CAAC;KACF,EAAE,CACH,CAAC;IAEF;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvD;;;;;;;OAOG;IACH,MAAM,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACZ,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,QAAQ,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;KACvC,EAAE,CACH,CAAC;CACF,CAAC"}
@@ -1,6 +1,35 @@
1
1
  import type { UserId } from "../../common/entities/common-entity";
2
2
  import type { CategoryFindManyParams } from "../types/query-params";
3
+ /**
4
+ * Query repository interface for the Category domain.
5
+ *
6
+ * @remarks
7
+ * Provides read-only access to categories.
8
+ * Categories are used to organize articles into logical groups.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Infrastructure implementation
13
+ * class PrismaCategoryQueryRepository implements ICategoryQueryRepository {
14
+ * async findMany(userId: UserId, params?: CategoryFindManyParams) {
15
+ * return await prisma.category.findMany({
16
+ * where: { userId },
17
+ * ...params
18
+ * });
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * @see {@link CategoryFindManyParams} for query parameters
24
+ */
3
25
  export type ICategoryQueryRepository = {
26
+ /**
27
+ * Retrieves multiple categories with optional pagination and sorting.
28
+ *
29
+ * @param userId - The user ID for tenant isolation
30
+ * @param params - Optional pagination and sorting parameters
31
+ * @returns Array of category data objects
32
+ */
4
33
  findMany(userId: UserId, params?: CategoryFindManyParams): Promise<{
5
34
  id: string;
6
35
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"category-query-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/category-query-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE,MAAM,MAAM,wBAAwB,GAAG;IACtC,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,sBAAsB,GAC7B,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACb,EAAE,CACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"category-query-repository.interface.d.ts","sourceRoot":"","sources":["../../../articles/repositories/category-query-repository.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACtC;;;;;;OAMG;IACH,QAAQ,CACP,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,sBAAsB,GAC7B,OAAO,CACT;QACC,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;KACb,EAAE,CACH,CAAC;CACF,CAAC"}
@@ -1,9 +1,49 @@
1
1
  import type { UserId } from "../../common/entities/common-entity";
2
2
  import type { Url } from "../entities/article-entity";
3
3
  import type { IArticlesQueryRepository } from "../repositories/articles-query-repository.interface";
4
+ /**
5
+ * Domain service for Article business logic.
6
+ *
7
+ * @remarks
8
+ * Encapsulates complex business rules that don't belong to a single entity.
9
+ * Uses dependency injection for repository access.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const queryRepo: IArticlesQueryRepository = new PrismaArticlesQueryRepository();
14
+ * const domainService = new ArticlesDomainService(queryRepo);
15
+ *
16
+ * try {
17
+ * await domainService.ensureNoDuplicate(url, userId);
18
+ * // Safe to create the article
19
+ * } catch (error) {
20
+ * if (error instanceof DuplicateError) {
21
+ * // Handle duplicate URL
22
+ * }
23
+ * }
24
+ * ```
25
+ *
26
+ * @see {@link IArticlesQueryRepository} for repository interface
27
+ * @see {@link DuplicateError} for duplicate handling
28
+ */
4
29
  export declare class ArticlesDomainService {
5
30
  private readonly articlesQueryRepository;
31
+ /**
32
+ * Creates a new ArticlesDomainService instance.
33
+ *
34
+ * @param articlesQueryRepository - The query repository for checking duplicates
35
+ */
6
36
  constructor(articlesQueryRepository: IArticlesQueryRepository);
37
+ /**
38
+ * Validates that no article with the same URL exists for the user.
39
+ *
40
+ * @param url - The URL to check for duplicates
41
+ * @param userId - The user ID for tenant isolation
42
+ * @throws {DuplicateError} When an article with this URL already exists
43
+ *
44
+ * @remarks
45
+ * This is a domain invariant check that should be called before creating articles.
46
+ */
7
47
  ensureNoDuplicate(url: Url, userId: UserId): Promise<void>;
8
48
  }
9
49
  //# sourceMappingURL=articles-domain-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"articles-domain-service.d.ts","sourceRoot":"","sources":["../../../articles/services/articles-domain-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAapG,qBAAa,qBAAqB;IAEhC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;gBAAvB,uBAAuB,EAAE,wBAAwB;IAGtD,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM;CAGvD"}
1
+ {"version":3,"file":"articles-domain-service.d.ts","sourceRoot":"","sources":["../../../articles/services/articles-domain-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAElE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAuBpG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,qBAAqB;IAOhC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IANzC;;;;OAIG;gBAEe,uBAAuB,EAAE,wBAAwB;IAGnE;;;;;;;;;OASG;IACU,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM;CAGvD"}
@@ -1,15 +1,65 @@
1
1
  import { DuplicateError } from "../../errors/error-classes";
2
+ /**
3
+ * Checks if an article with the given URL already exists.
4
+ *
5
+ * @param articlesQueryRepository - The query repository to check against
6
+ * @param url - The URL to check for duplicates
7
+ * @param userId - The user ID for tenant isolation
8
+ * @throws {DuplicateError} When an article with this URL already exists
9
+ *
10
+ * @internal
11
+ */
2
12
  async function ensureNoDuplicateArticle(articlesQueryRepository, url, userId) {
3
13
  const exists = await articlesQueryRepository.findByUrl(url, userId);
4
14
  if (exists !== null) {
5
15
  throw new DuplicateError();
6
16
  }
7
17
  }
18
+ /**
19
+ * Domain service for Article business logic.
20
+ *
21
+ * @remarks
22
+ * Encapsulates complex business rules that don't belong to a single entity.
23
+ * Uses dependency injection for repository access.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const queryRepo: IArticlesQueryRepository = new PrismaArticlesQueryRepository();
28
+ * const domainService = new ArticlesDomainService(queryRepo);
29
+ *
30
+ * try {
31
+ * await domainService.ensureNoDuplicate(url, userId);
32
+ * // Safe to create the article
33
+ * } catch (error) {
34
+ * if (error instanceof DuplicateError) {
35
+ * // Handle duplicate URL
36
+ * }
37
+ * }
38
+ * ```
39
+ *
40
+ * @see {@link IArticlesQueryRepository} for repository interface
41
+ * @see {@link DuplicateError} for duplicate handling
42
+ */
8
43
  export class ArticlesDomainService {
9
44
  articlesQueryRepository;
45
+ /**
46
+ * Creates a new ArticlesDomainService instance.
47
+ *
48
+ * @param articlesQueryRepository - The query repository for checking duplicates
49
+ */
10
50
  constructor(articlesQueryRepository) {
11
51
  this.articlesQueryRepository = articlesQueryRepository;
12
52
  }
53
+ /**
54
+ * Validates that no article with the same URL exists for the user.
55
+ *
56
+ * @param url - The URL to check for duplicates
57
+ * @param userId - The user ID for tenant isolation
58
+ * @throws {DuplicateError} When an article with this URL already exists
59
+ *
60
+ * @remarks
61
+ * This is a domain invariant check that should be called before creating articles.
62
+ */
13
63
  async ensureNoDuplicate(url, userId) {
14
64
  return ensureNoDuplicateArticle(this.articlesQueryRepository, url, userId);
15
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"articles-domain-service.js","sourceRoot":"","sources":["../../../articles/services/articles-domain-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI5D,KAAK,UAAU,wBAAwB,CACtC,uBAAiD,EACjD,GAAQ,EACR,MAAc;IAEd,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,EAAE,CAAC;IAC5B,CAAC;AACF,CAAC;AAED,MAAM,OAAO,qBAAqB;IAEf;IADlB,YACkB,uBAAiD;QAAjD,4BAAuB,GAAvB,uBAAuB,CAA0B;IAChE,CAAC;IAEG,KAAK,CAAC,iBAAiB,CAAC,GAAQ,EAAE,MAAc;QACtD,OAAO,wBAAwB,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;CACD"}
1
+ {"version":3,"file":"articles-domain-service.js","sourceRoot":"","sources":["../../../articles/services/articles-domain-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI5D;;;;;;;;;GASG;AACH,KAAK,UAAU,wBAAwB,CACtC,uBAAiD,EACjD,GAAQ,EACR,MAAc;IAEd,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,EAAE,CAAC;IAC5B,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,OAAO,qBAAqB;IAOf;IANlB;;;;OAIG;IACH,YACkB,uBAAiD;QAAjD,4BAAuB,GAAvB,uBAAuB,CAA0B;IAChE,CAAC;IAEJ;;;;;;;;;OASG;IACI,KAAK,CAAC,iBAAiB,CAAC,GAAQ,EAAE,MAAc;QACtD,OAAO,wBAAwB,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;CACD"}
@@ -1,6 +1,25 @@
1
+ /**
2
+ * Cache configuration for repository queries.
3
+ *
4
+ * @remarks
5
+ * Provides fine-grained control over caching behavior.
6
+ * Uses stale-while-revalidate (SWR) pattern for optimal performance.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const strategy: CacheStrategy = {
11
+ * ttl: 60, // Cache for 60 seconds
12
+ * swr: 300, // Serve stale for 5 minutes while revalidating
13
+ * tags: ["articles"] // Cache tags for invalidation
14
+ * };
15
+ * ```
16
+ */
1
17
  export type CacheStrategy = {
18
+ /** Time-to-live in seconds */
2
19
  ttl?: number;
20
+ /** Stale-while-revalidate duration in seconds */
3
21
  swr?: number;
22
+ /** Cache tags for targeted invalidation */
4
23
  tags?: string[];
5
24
  };
6
25
  //# sourceMappingURL=cache-strategy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cache-strategy.d.ts","sourceRoot":"","sources":["../../../articles/types/cache-strategy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC"}
1
+ {"version":3,"file":"cache-strategy.d.ts","sourceRoot":"","sources":["../../../articles/types/cache-strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,aAAa,GAAG;IAC3B,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC"}
@@ -1,23 +1,101 @@
1
1
  import type { CacheStrategy } from "./cache-strategy";
2
2
  import type { SortOrder } from "./sort-order";
3
- type ArticleOrderByField = "id" | "title" | "url" | "quote" | "ogImageUrl" | "ogTitle" | "ogDescription" | "status" | "createdAt" | "updatedAt" | "exportedAt";
4
- type CategoryOrderByField = "id" | "name" | "createdAt" | "updatedAt";
5
- type ArticleOrderBy = {
3
+ /**
4
+ * Available fields for sorting article queries.
5
+ *
6
+ * @remarks
7
+ * All fields correspond to Article entity properties.
8
+ * Used with {@link ArticleOrderBy} to specify sort criteria.
9
+ */
10
+ export type ArticleOrderByField = "id" | "title" | "url" | "quote" | "ogImageUrl" | "ogTitle" | "ogDescription" | "status" | "createdAt" | "updatedAt" | "exportedAt";
11
+ /**
12
+ * Available fields for sorting category queries.
13
+ *
14
+ * @remarks
15
+ * Used with {@link CategoryOrderBy} to specify sort criteria.
16
+ */
17
+ export type CategoryOrderByField = "id" | "name" | "createdAt" | "updatedAt";
18
+ /**
19
+ * Sort configuration for article queries.
20
+ *
21
+ * @remarks
22
+ * Maps field names to sort directions.
23
+ * Typically only one field should be specified at a time.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const orderBy: ArticleOrderBy = { createdAt: "desc" };
28
+ * ```
29
+ *
30
+ * @see {@link ArticleOrderByField} for available fields
31
+ * @see {@link SortOrder} for sort directions
32
+ */
33
+ export type ArticleOrderBy = {
6
34
  [K in ArticleOrderByField]?: SortOrder;
7
35
  };
8
- type CategoryOrderBy = {
36
+ /**
37
+ * Sort configuration for category queries.
38
+ *
39
+ * @remarks
40
+ * Maps field names to sort directions.
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const orderBy: CategoryOrderBy = { name: "asc" };
45
+ * ```
46
+ *
47
+ * @see {@link CategoryOrderByField} for available fields
48
+ * @see {@link SortOrder} for sort directions
49
+ */
50
+ export type CategoryOrderBy = {
9
51
  [K in CategoryOrderByField]?: SortOrder;
10
52
  };
53
+ /**
54
+ * Parameters for paginated article queries.
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const params: ArticlesFindManyParams = {
59
+ * orderBy: { createdAt: "desc" },
60
+ * take: 20,
61
+ * skip: 0,
62
+ * cacheStrategy: { ttl: 60, tags: ["articles"] },
63
+ * };
64
+ * ```
65
+ *
66
+ * @see {@link ArticleOrderBy} for sorting options
67
+ * @see {@link CacheStrategy} for caching configuration
68
+ */
11
69
  export type ArticlesFindManyParams = {
70
+ /** Sort configuration */
12
71
  orderBy?: ArticleOrderBy;
72
+ /** Maximum number of results to return */
13
73
  take?: number;
74
+ /** Number of results to skip (for pagination) */
14
75
  skip?: number;
76
+ /** Caching configuration for the query */
15
77
  cacheStrategy?: CacheStrategy;
16
78
  };
79
+ /**
80
+ * Parameters for paginated category queries.
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * const params: CategoryFindManyParams = {
85
+ * orderBy: { name: "asc" },
86
+ * take: 50,
87
+ * skip: 0,
88
+ * };
89
+ * ```
90
+ *
91
+ * @see {@link CategoryOrderBy} for sorting options
92
+ */
17
93
  export type CategoryFindManyParams = {
94
+ /** Sort configuration */
18
95
  orderBy?: CategoryOrderBy;
96
+ /** Maximum number of results to return */
19
97
  take?: number;
98
+ /** Number of results to skip (for pagination) */
20
99
  skip?: number;
21
100
  };
22
- export {};
23
101
  //# sourceMappingURL=query-params.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../../articles/types/query-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,KAAK,mBAAmB,GACrB,IAAI,GACJ,OAAO,GACP,KAAK,GACL,OAAO,GACP,YAAY,GACZ,SAAS,GACT,eAAe,GACf,QAAQ,GACR,WAAW,GACX,WAAW,GACX,YAAY,CAAC;AAEhB,KAAK,oBAAoB,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;AAEtE,KAAK,cAAc,GAAG;KACpB,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,SAAS;CACtC,CAAC;AAEF,KAAK,eAAe,GAAG;KACrB,CAAC,IAAI,oBAAoB,CAAC,CAAC,EAAE,SAAS;CACvC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACpC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACpC,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC"}
1
+ {"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../../articles/types/query-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,mBAAmB,GAC5B,IAAI,GACJ,OAAO,GACP,KAAK,GACL,OAAO,GACP,YAAY,GACZ,SAAS,GACT,eAAe,GACf,QAAQ,GACR,WAAW,GACX,WAAW,GACX,YAAY,CAAC;AAEhB;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;AAE7E;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,cAAc,GAAG;KAC3B,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,SAAS;CACtC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,eAAe,GAAG;KAC5B,CAAC,IAAI,oBAAoB,CAAC,CAAC,EAAE,SAAS;CACvC,CAAC;AAEF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACpC,yBAAyB;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC9B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACpC,yBAAyB;IACzB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;CACd,CAAC"}
@@ -1,2 +1,14 @@
1
+ /**
2
+ * Sort direction for query ordering.
3
+ *
4
+ * @remarks
5
+ * Standard SQL-style sort order used across all domain queries.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const ascending: SortOrder = "asc";
10
+ * const descending: SortOrder = "desc";
11
+ * ```
12
+ */
1
13
  export type SortOrder = "asc" | "desc";
2
14
  //# sourceMappingURL=sort-order.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sort-order.d.ts","sourceRoot":"","sources":["../../../articles/types/sort-order.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"sort-order.d.ts","sourceRoot":"","sources":["../../../articles/types/sort-order.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,MAAM,CAAC"}