@rytass/cms-base-nestjs-graphql-module 0.1.26 → 0.1.28

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 (147) hide show
  1. package/LICENSE +21 -0
  2. package/cms-base-graphql.module.d.ts +9 -0
  3. package/cms-base-graphql.module.js +114 -0
  4. package/constants/enum/base-action.enum.d.ts +14 -0
  5. package/constants/enum/base-action.enum.js +17 -0
  6. package/constants/enum/base-resource.enum.d.ts +4 -0
  7. package/constants/enum/base-resource.enum.js +7 -0
  8. package/constants/option-providers.d.ts +2 -0
  9. package/constants/option-providers.js +20 -0
  10. package/data-loaders/article.dataloader.d.ts +17 -0
  11. package/data-loaders/article.dataloader.js +68 -0
  12. package/data-loaders/members.dataloader.d.ts +8 -0
  13. package/data-loaders/members.dataloader.js +56 -0
  14. package/decorators/language.decorator.d.ts +2 -0
  15. package/decorators/language.decorator.js +32 -0
  16. package/dto/article-collection.dto.d.ts +5 -0
  17. package/dto/article-collection.dto.js +27 -0
  18. package/dto/article-multi-language-content.dto.d.ts +7 -0
  19. package/dto/article-multi-language-content.dto.js +41 -0
  20. package/dto/article-signature-step.dto.d.ts +4 -0
  21. package/dto/article-signature-step.dto.js +28 -0
  22. package/dto/article-signature.dto.d.ts +7 -0
  23. package/dto/article-signature.dto.js +44 -0
  24. package/dto/article-stage-version.dto.d.ts +9 -0
  25. package/dto/article-stage-version.dto.js +59 -0
  26. package/dto/article-version-content.input.d.ts +7 -0
  27. package/dto/article-version-content.input.js +43 -0
  28. package/dto/article.dto.d.ts +7 -0
  29. package/dto/article.dto.js +37 -0
  30. package/dto/articles.args.d.ts +6 -0
  31. package/dto/articles.args.js +48 -0
  32. package/dto/backstage-article-collection.dto.d.ts +5 -0
  33. package/dto/backstage-article-collection.dto.js +27 -0
  34. package/dto/backstage-article.args.d.ts +6 -0
  35. package/dto/backstage-article.args.js +38 -0
  36. package/dto/backstage-article.dto.d.ts +6 -0
  37. package/dto/backstage-article.dto.js +38 -0
  38. package/dto/backstage-category.dto.d.ts +3 -0
  39. package/dto/backstage-category.dto.js +16 -0
  40. package/dto/base-article.dto.d.ts +7 -0
  41. package/dto/base-article.dto.js +47 -0
  42. package/dto/base-category.dto.d.ts +5 -0
  43. package/dto/base-category.dto.js +33 -0
  44. package/dto/categories.args.d.ts +8 -0
  45. package/dto/categories.args.js +62 -0
  46. package/dto/category-multi-language-name.dto.d.ts +4 -0
  47. package/dto/category-multi-language-name.dto.js +28 -0
  48. package/dto/category-multi-language-name.input.d.ts +4 -0
  49. package/dto/category-multi-language-name.input.js +30 -0
  50. package/dto/category.dto.d.ts +4 -0
  51. package/dto/category.dto.js +24 -0
  52. package/dto/collection.dto.d.ts +5 -0
  53. package/dto/collection.dto.js +33 -0
  54. package/dto/create-article.args.d.ts +11 -0
  55. package/dto/create-article.args.js +71 -0
  56. package/dto/create-category.args.d.ts +7 -0
  57. package/dto/create-category.args.js +45 -0
  58. package/dto/custom-field.input.d.ts +4 -0
  59. package/dto/custom-field.input.js +28 -0
  60. package/dto/update-article.args.d.ts +4 -0
  61. package/dto/update-article.args.js +24 -0
  62. package/dto/update-category.args.d.ts +4 -0
  63. package/dto/update-category.args.js +24 -0
  64. package/dto/user.dto.d.ts +4 -0
  65. package/dto/user.dto.js +28 -0
  66. package/index.cjs.js +2334 -0
  67. package/{src/index.ts → index.d.ts} +0 -2
  68. package/index.js +8 -0
  69. package/mutations/article.mutations.d.ts +22 -0
  70. package/mutations/article.mutations.js +338 -0
  71. package/mutations/category.mutations.d.ts +15 -0
  72. package/mutations/category.mutations.js +134 -0
  73. package/package.json +6 -10
  74. package/queries/article.queries.d.ts +16 -0
  75. package/queries/article.queries.js +132 -0
  76. package/queries/category.queries.d.ts +13 -0
  77. package/queries/category.queries.js +124 -0
  78. package/resolvers/article-signature.resolver.d.ts +10 -0
  79. package/resolvers/article-signature.resolver.js +68 -0
  80. package/resolvers/article.resolver.d.ts +14 -0
  81. package/resolvers/article.resolver.js +95 -0
  82. package/resolvers/backstage-article.resolver.d.ts +33 -0
  83. package/resolvers/backstage-article.resolver.js +296 -0
  84. package/resolvers/backstage-category.resolver.d.ts +8 -0
  85. package/resolvers/backstage-category.resolver.js +76 -0
  86. package/scalars/quadrats-element.scalar.d.ts +3 -0
  87. package/scalars/quadrats-element.scalar.js +47 -0
  88. package/typings/cms-graphql-base-providers.d.ts +3 -0
  89. package/typings/cms-graphql-base-providers.js +5 -0
  90. package/{src/typings/cms-graphql-base-root-module-async-options.dto.ts → typings/cms-graphql-base-root-module-async-options.dto.d.ts} +4 -6
  91. package/{src/typings/cms-graphql-base-root-module-option-factory.ts → typings/cms-graphql-base-root-module-option-factory.d.ts} +1 -2
  92. package/typings/cms-graphql-base-root-module-options.dto.d.ts +6 -0
  93. package/typings/dto/resolved-create-article-args.dto.d.ts +24 -0
  94. package/typings/dto/resolved-create-category-args.dto.d.ts +13 -0
  95. package/CHANGELOG.md +0 -306
  96. package/__tests__/enums.spec.ts +0 -76
  97. package/__tests__/language-decorator.spec.ts +0 -17
  98. package/__tests__/quadrats-element-scalar.spec.ts +0 -123
  99. package/llms.txt +0 -361
  100. package/project.json +0 -23
  101. package/src/cms-base-graphql.module.ts +0 -101
  102. package/src/constants/enum/base-action.enum.ts +0 -17
  103. package/src/constants/enum/base-resource.enum.ts +0 -4
  104. package/src/constants/option-providers.ts +0 -35
  105. package/src/data-loaders/article.dataloader.ts +0 -84
  106. package/src/data-loaders/members.dataloader.ts +0 -36
  107. package/src/decorators/language.decorator.ts +0 -45
  108. package/src/dto/article-collection.dto.ts +0 -9
  109. package/src/dto/article-multi-language-content.dto.ts +0 -18
  110. package/src/dto/article-signature-step.dto.ts +0 -10
  111. package/src/dto/article-signature.dto.ts +0 -21
  112. package/src/dto/article-stage-version.dto.ts +0 -23
  113. package/src/dto/article-version-content.input.ts +0 -18
  114. package/src/dto/article.dto.ts +0 -16
  115. package/src/dto/articles.args.ts +0 -16
  116. package/src/dto/backstage-article-collection.dto.ts +0 -9
  117. package/src/dto/backstage-article.args.ts +0 -20
  118. package/src/dto/backstage-article.dto.ts +0 -14
  119. package/src/dto/backstage-category.dto.ts +0 -5
  120. package/src/dto/base-article.dto.ts +0 -19
  121. package/src/dto/base-category.dto.ts +0 -13
  122. package/src/dto/categories.args.ts +0 -27
  123. package/src/dto/category-multi-language-name.dto.ts +0 -10
  124. package/src/dto/category-multi-language-name.input.ts +0 -10
  125. package/src/dto/category.dto.ts +0 -8
  126. package/src/dto/collection.dto.ts +0 -13
  127. package/src/dto/create-article.args.ts +0 -27
  128. package/src/dto/create-category.args.ts +0 -15
  129. package/src/dto/custom-field.input.ts +0 -10
  130. package/src/dto/update-article.args.ts +0 -8
  131. package/src/dto/update-category.args.ts +0 -8
  132. package/src/dto/user.dto.ts +0 -10
  133. package/src/mutations/article.mutations.ts +0 -177
  134. package/src/mutations/category.mutations.ts +0 -78
  135. package/src/queries/article.queries.ts +0 -71
  136. package/src/queries/category.queries.ts +0 -53
  137. package/src/resolvers/article-signature.resolver.ts +0 -29
  138. package/src/resolvers/article.resolver.ts +0 -41
  139. package/src/resolvers/backstage-article.resolver.ts +0 -161
  140. package/src/resolvers/backstage-category.resolver.ts +0 -40
  141. package/src/scalars/quadrats-element.scalar.ts +0 -56
  142. package/src/typings/cms-graphql-base-providers.ts +0 -3
  143. package/src/typings/cms-graphql-base-root-module-options.dto.ts +0 -11
  144. package/src/typings/dto/resolved-create-article-args.dto.ts +0 -33
  145. package/src/typings/dto/resolved-create-category-args.dto.ts +0 -19
  146. package/tsconfig.build.json +0 -8
  147. /package/{src/typings/custom-field-value.type.ts → typings/custom-field-value.type.d.ts} +0 -0
package/llms.txt DELETED
@@ -1,361 +0,0 @@
1
- # @rytass/cms-base-nestjs-graphql-module
2
-
3
- Rytass Content Management System NestJS GraphQL Module - A GraphQL extension for the CMS base module providing GraphQL resolvers, queries, mutations, and DTOs for building GraphQL-enabled CMS applications.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @rytass/cms-base-nestjs-graphql-module
9
- ```
10
-
11
- ## Features
12
-
13
- ### GraphQL Resolvers
14
- - **ArticleResolver**: Basic article field resolution with author and category relationships
15
- - **BackstageArticleResolver**: Administrative article management operations
16
- - **ArticleSignatureResolver**: Article approval workflow resolution
17
- - **BackstageCategoryResolver**: Administrative category management
18
-
19
- ### Queries & Mutations
20
- - **ArticleQueries**: Public article data queries
21
- - **CategoryQueries**: Public category data queries
22
- - **ArticleMutations**: Article CRUD operations
23
- - **CategoryMutations**: Category CRUD operations
24
-
25
- ### Data Loaders
26
- - **ArticleDataLoader**: Efficient GraphQL article loading
27
- - **MemberDataLoader**: User/author data loading for article relationships
28
-
29
- ### GraphQL DTOs
30
- - **ArticleDto**: Public article representation
31
- - **BackstageArticleDto**: Administrative article with full metadata
32
- - **CategoryDto**: Public category representation
33
- - **BackstageCategoryDto**: Administrative category operations
34
- - **ArticleCollectionDto**: Paginated article collections
35
-
36
- ### Custom Scalars
37
- - **QuadratsElementScalar**: Support for rich content editor elements
38
-
39
- ## Usage
40
-
41
- ### Basic Setup
42
-
43
- ```typescript
44
- import { Module } from '@nestjs/common';
45
- import { GraphQLModule } from '@nestjs/graphql';
46
- import { CMSBaseGraphQLModule } from '@rytass/cms-base-nestjs-graphql-module';
47
-
48
- @Module({
49
- imports: [
50
- GraphQLModule.forRoot({
51
- autoSchemaFile: true,
52
- }),
53
- CMSBaseGraphQLModule.forRoot({
54
- multipleLanguageMode: true,
55
- enableDraftMode: true,
56
- }),
57
- ],
58
- })
59
- export class AppModule {}
60
- ```
61
-
62
- ### Async Configuration
63
-
64
- ```typescript
65
- @Module({
66
- imports: [
67
- CMSBaseGraphQLModule.forRootAsync({
68
- imports: [ConfigModule],
69
- useFactory: (config: ConfigService) => ({
70
- multipleLanguageMode: config.get('CMS_MULTI_LANG'),
71
- enableDraftMode: config.get('CMS_DRAFT_MODE'),
72
- }),
73
- inject: [ConfigService],
74
- }),
75
- ],
76
- })
77
- export class AppModule {}
78
- ```
79
-
80
- ## GraphQL Schema Examples
81
-
82
- ### Article Queries
83
-
84
- ```graphql
85
- # Get public articles
86
- query GetArticles($first: Int!, $after: String) {
87
- articles(first: $first, after: $after) {
88
- edges {
89
- node {
90
- articleId
91
- title
92
- content
93
- publishedAt
94
- author {
95
- id
96
- name
97
- }
98
- categories {
99
- id
100
- name
101
- }
102
- }
103
- }
104
- pageInfo {
105
- hasNextPage
106
- endCursor
107
- }
108
- }
109
- }
110
-
111
- # Get single article
112
- query GetArticle($id: ID!) {
113
- article(id: $id) {
114
- articleId
115
- title
116
- content
117
- publishedAt
118
- categories {
119
- id
120
- name
121
- }
122
- }
123
- }
124
- ```
125
-
126
- ### Backstage Operations
127
-
128
- ```graphql
129
- # Create article (admin)
130
- mutation CreateArticle($input: CreateArticleInput!) {
131
- createArticle(input: $input) {
132
- id
133
- title
134
- stage
135
- createdAt
136
- }
137
- }
138
-
139
- # Update article (admin)
140
- mutation UpdateArticle($id: ID!, $input: UpdateArticleInput!) {
141
- updateArticle(id: $id, input: $input) {
142
- id
143
- title
144
- updatedAt
145
- }
146
- }
147
- ```
148
-
149
- ### Category Operations
150
-
151
- ```graphql
152
- # Get categories
153
- query GetCategories {
154
- categories {
155
- id
156
- name
157
- slug
158
- parent {
159
- id
160
- name
161
- }
162
- children {
163
- id
164
- name
165
- }
166
- }
167
- }
168
-
169
- # Create category (admin)
170
- mutation CreateCategory($input: CreateCategoryInput!) {
171
- createCategory(input: $input) {
172
- id
173
- name
174
- slug
175
- }
176
- }
177
- ```
178
-
179
- ## TypeScript Integration
180
-
181
- ### Using GraphQL DTOs
182
-
183
- ```typescript
184
- import { Field, ObjectType, ID } from '@nestjs/graphql';
185
- import { ArticleDto, CategoryDto } from '@rytass/cms-base-nestjs-graphql-module';
186
-
187
- @ObjectType()
188
- export class CustomArticleDto extends ArticleDto {
189
- @Field(() => String, { nullable: true })
190
- customField?: string;
191
- }
192
- ```
193
-
194
- ### Custom Resolvers
195
-
196
- ```typescript
197
- import { Resolver, Query, Args } from '@nestjs/graphql';
198
- import { ArticleDto } from '@rytass/cms-base-nestjs-graphql-module';
199
-
200
- @Resolver(() => ArticleDto)
201
- export class CustomArticleResolver {
202
- @Query(() => [ArticleDto])
203
- async featuredArticles(): Promise<ArticleDto[]> {
204
- // custom logic
205
- return [];
206
- }
207
- }
208
- ```
209
-
210
- ## Configuration Options
211
-
212
- Inherits all options from `@rytass/cms-base-nestjs-module` plus:
213
-
214
- ```typescript
215
- interface CMSGraphqlBaseModuleOptionsDto extends CMSBaseModuleOptionsDto {
216
- // All base CMS options are available
217
- multipleLanguageMode?: boolean;
218
- enableDraftMode?: boolean;
219
- // ... other CMS base options
220
- }
221
- ```
222
-
223
- ## Key GraphQL Types
224
-
225
- ```typescript
226
- // Article representation
227
- @ObjectType()
228
- export class ArticleDto {
229
- @Field(() => ID)
230
- articleId: string;
231
-
232
- @Field()
233
- title: string;
234
-
235
- @Field()
236
- content: string;
237
-
238
- @Field(() => Date, { nullable: true })
239
- publishedAt?: Date;
240
-
241
- @Field(() => [CategoryDto])
242
- categories: CategoryDto[];
243
-
244
- @Field(() => UserDto, { nullable: true })
245
- author?: UserDto;
246
- }
247
-
248
- // Category representation
249
- @ObjectType()
250
- export class CategoryDto {
251
- @Field(() => ID)
252
- id: string;
253
-
254
- @Field()
255
- name: string;
256
-
257
- @Field()
258
- slug: string;
259
-
260
- @Field(() => CategoryDto, { nullable: true })
261
- parent?: CategoryDto;
262
-
263
- @Field(() => [CategoryDto])
264
- children: CategoryDto[];
265
- }
266
-
267
- // Collection with pagination
268
- @ObjectType()
269
- export class ArticleCollectionDto {
270
- @Field(() => [ArticleDto])
271
- edges: ArticleDto[];
272
-
273
- @Field()
274
- totalCount: number;
275
-
276
- @Field(() => PageInfo)
277
- pageInfo: PageInfo;
278
- }
279
- ```
280
-
281
- ## Data Loading
282
-
283
- The module uses DataLoader pattern for efficient N+1 query prevention:
284
-
285
- ```typescript
286
- // Automatic batched loading
287
- @ResolveField(() => UserDto)
288
- async author(@Root() article: ArticleDto): Promise<UserDto> {
289
- return this.memberDataLoader.load(article.authorId);
290
- }
291
-
292
- @ResolveField(() => [CategoryDto])
293
- async categories(@Root() article: ArticleDto): Promise<CategoryDto[]> {
294
- return this.articleDataLoader.loadCategories(article.id);
295
- }
296
- ```
297
-
298
- ## Language Support
299
-
300
- When `multipleLanguageMode` is enabled:
301
-
302
- ```typescript
303
- // Language-aware resolvers
304
- @ResolveField(() => String)
305
- title(
306
- @Root() article: ArticleDto,
307
- @Language() language: string
308
- ): string {
309
- return this.getLocalizedContent(article, language, 'title');
310
- }
311
- ```
312
-
313
- ## Dependencies
314
-
315
- - `@rytass/cms-base-nestjs-module`: Core CMS functionality
316
- - `@rytass/member-base-nestjs-module`: User management integration
317
- - `dataloader`: Efficient data loading
318
- - `lru-cache`: Caching support
319
-
320
- ## Peer Dependencies
321
-
322
- - `@nestjs/common`: NestJS framework
323
- - `@nestjs/typeorm`: Database integration
324
- - `@node-rs/jieba`: Text processing
325
- - `@quadrats/core`: Rich content support
326
- - `typeorm`: ORM
327
-
328
- ## Testing
329
-
330
- ```typescript
331
- import { Test } from '@nestjs/testing';
332
- import { ArticleResolver } from '@rytass/cms-base-nestjs-graphql-module';
333
-
334
- describe('ArticleResolver', () => {
335
- let resolver: ArticleResolver;
336
-
337
- beforeEach(async () => {
338
- const module = await Test.createTestingModule({
339
- providers: [
340
- ArticleResolver,
341
- {
342
- provide: 'MemberDataLoader',
343
- useValue: mockDataLoader,
344
- },
345
- ],
346
- }).compile();
347
-
348
- resolver = module.get<ArticleResolver>(ArticleResolver);
349
- });
350
-
351
- // tests...
352
- });
353
- ```
354
-
355
- ## License
356
-
357
- MIT
358
-
359
- ## Support
360
-
361
- For issues and questions, visit the [GitHub repository](https://github.com/Rytass/Utils/issues).
package/project.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "name": "@rytass/cms-base-nestjs-graphql-module",
3
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
- "projectType": "library",
5
- "sourceRoot": "packages/cms-base-nestjs-graphql-module/src",
6
- "targets": {
7
- "test": {
8
- "executor": "@nx/jest:jest"
9
- },
10
- "test:watch": {
11
- "executor": "@nx/jest:jest"
12
- },
13
- "lint": {
14
- "executor": "nx:run-commands"
15
- },
16
- "clean": {
17
- "executor": "nx:run-commands"
18
- },
19
- "build": {
20
- "executor": "nx:run-commands"
21
- }
22
- }
23
- }
@@ -1,101 +0,0 @@
1
- import { Module, DynamicModule, Provider, Type } from '@nestjs/common';
2
- import { CMSBaseModule } from '@rytass/cms-base-nestjs-module';
3
- import { ArticleMutations } from './mutations/article.mutations';
4
- import { CategoryMutations } from './mutations/category.mutations';
5
- import { ArticleQueries } from './queries/article.queries';
6
- import { CategoryQueries } from './queries/category.queries';
7
- import { MemberDataLoader } from './data-loaders/members.dataloader';
8
- import { ArticleDataLoader } from './data-loaders/article.dataloader';
9
- import { ArticleResolver } from './resolvers/article.resolver';
10
- import { BackstageArticleResolver } from './resolvers/backstage-article.resolver';
11
- import { ArticleSignatureResolver } from './resolvers/article-signature.resolver';
12
- import { BackstageCategoryResolver } from './resolvers/backstage-category.resolver';
13
- import { CMSGraphqlBaseModuleOptionsDto } from './typings/cms-graphql-base-root-module-options.dto';
14
- import { CMSGraphqlBaseModuleAsyncOptionsDto } from './typings/cms-graphql-base-root-module-async-options.dto';
15
- import { OptionProviders } from './constants/option-providers';
16
- import { CMS_BASE_GRAPHQL_MODULE_OPTIONS } from './typings/cms-graphql-base-providers';
17
- import { CMSGraphqlBaseModuleOptionFactory } from './typings/cms-graphql-base-root-module-option-factory';
18
-
19
- @Module({})
20
- export class CMSBaseGraphQLModule {
21
- static forRootAsync(options: CMSGraphqlBaseModuleAsyncOptionsDto): DynamicModule {
22
- return {
23
- module: CMSBaseGraphQLModule,
24
- imports: [...(options.imports || []), CMSBaseModule.forRootAsync(options)],
25
- exports: [CMSBaseModule],
26
- providers: [
27
- ...this.createAsyncProvider(options),
28
- ...OptionProviders,
29
- MemberDataLoader,
30
- ArticleDataLoader,
31
- ArticleResolver,
32
- BackstageArticleResolver,
33
- ArticleSignatureResolver,
34
- ArticleQueries,
35
- ArticleMutations,
36
- CategoryQueries,
37
- CategoryMutations,
38
- BackstageCategoryResolver,
39
- ],
40
- };
41
- }
42
-
43
- static forRoot(options: CMSGraphqlBaseModuleOptionsDto): DynamicModule {
44
- return {
45
- module: CMSBaseGraphQLModule,
46
- imports: [CMSBaseModule.forRoot(options)],
47
- exports: [CMSBaseModule],
48
- providers: [
49
- {
50
- provide: CMS_BASE_GRAPHQL_MODULE_OPTIONS,
51
- useValue: options,
52
- },
53
- ...OptionProviders,
54
- MemberDataLoader,
55
- ArticleDataLoader,
56
- ArticleResolver,
57
- BackstageArticleResolver,
58
- ArticleSignatureResolver,
59
- ArticleQueries,
60
- ArticleMutations,
61
- CategoryQueries,
62
- CategoryMutations,
63
- BackstageCategoryResolver,
64
- ],
65
- };
66
- }
67
-
68
- private static createAsyncProvider(options: CMSGraphqlBaseModuleAsyncOptionsDto): Provider[] {
69
- if (options.useExisting || options.useFactory) {
70
- return [this.createAsyncOptionsProvider(options)];
71
- }
72
-
73
- return [
74
- this.createAsyncOptionsProvider(options),
75
- ...(options.useClass
76
- ? [
77
- {
78
- provide: options.useClass,
79
- useClass: options.useClass,
80
- },
81
- ]
82
- : []),
83
- ];
84
- }
85
-
86
- private static createAsyncOptionsProvider(options: CMSGraphqlBaseModuleAsyncOptionsDto): Provider {
87
- if (options.useFactory) {
88
- return {
89
- provide: CMS_BASE_GRAPHQL_MODULE_OPTIONS,
90
- useFactory: options.useFactory,
91
- inject: options.inject || [],
92
- };
93
- }
94
-
95
- return {
96
- provide: CMS_BASE_GRAPHQL_MODULE_OPTIONS,
97
- useFactory: async (optionsFactory: CMSGraphqlBaseModuleOptionFactory) => await optionsFactory.createCMSOptions(),
98
- inject: [(options.useExisting || options.useClass) as Type<CMSGraphqlBaseModuleOptionFactory>],
99
- };
100
- }
101
- }
@@ -1,17 +0,0 @@
1
- export enum BaseAction {
2
- LIST = 'LIST',
3
- READ = 'READ',
4
- CREATE = 'CREATE',
5
- UPDATE = 'UPDATE',
6
- DELETE = 'DELETE',
7
- DELETE_VERSION = 'DELETE_VERSION',
8
-
9
- SUBMIT = 'SUBMIT',
10
- PUT_BACK = 'PUT_BACK',
11
-
12
- APPROVE = 'APPROVE',
13
- REJECT = 'REJECT',
14
-
15
- RELEASE = 'RELEASE',
16
- WITHDRAW = 'WITHDRAW',
17
- }
@@ -1,4 +0,0 @@
1
- export enum BaseResource {
2
- ARTICLE = 'ARTICLE',
3
- CATEGORY = 'CATEGORY',
4
- }
@@ -1,35 +0,0 @@
1
- import { Provider } from '@nestjs/common';
2
- import {
3
- CMS_BASE_GRAPHQL_MODULE_OPTIONS,
4
- MAP_ARTICLE_CUSTOM_FIELDS_TO_ENTITY_COLUMNS,
5
- MAP_CATEGORY_CUSTOM_FIELDS_TO_ENTITY_COLUMNS,
6
- } from '../typings/cms-graphql-base-providers';
7
- import { CMSGraphqlBaseModuleOptionsDto } from '../typings/cms-graphql-base-root-module-options.dto';
8
- import { CustomFieldInput } from '../dto/custom-field.input';
9
-
10
- export const OptionProviders = [
11
- {
12
- provide: MAP_ARTICLE_CUSTOM_FIELDS_TO_ENTITY_COLUMNS,
13
- useFactory: async (
14
- options?: CMSGraphqlBaseModuleOptionsDto,
15
- ): Promise<
16
- (customFields: CustomFieldInput[]) => Promise<Record<string, string | object>> | Record<string, string | object>
17
- > =>
18
- options?.mapArticleCustomFieldsToEntityColumns
19
- ? options.mapArticleCustomFieldsToEntityColumns
20
- : (): Record<string, string | object> => ({}),
21
- inject: [CMS_BASE_GRAPHQL_MODULE_OPTIONS],
22
- },
23
- {
24
- provide: MAP_CATEGORY_CUSTOM_FIELDS_TO_ENTITY_COLUMNS,
25
- useFactory: async (
26
- options?: CMSGraphqlBaseModuleOptionsDto,
27
- ): Promise<
28
- (customFields: CustomFieldInput[]) => Promise<Record<string, string | object>> | Record<string, string | object>
29
- > =>
30
- options?.mapCategoryCustomFieldsToEntityColumns
31
- ? options.mapCategoryCustomFieldsToEntityColumns
32
- : (): Record<string, string | object> => ({}),
33
- inject: [CMS_BASE_GRAPHQL_MODULE_OPTIONS],
34
- },
35
- ] as Provider[];
@@ -1,84 +0,0 @@
1
- import { Inject, Injectable } from '@nestjs/common';
2
- import DataLoader from 'dataloader';
3
- import { Repository } from 'typeorm';
4
- import { LRUCache } from 'lru-cache';
5
- import { BaseArticleEntity, DEFAULT_LANGUAGE, RESOLVED_ARTICLE_REPO } from '@rytass/cms-base-nestjs-module';
6
- import { CategoryDto } from '../dto/category.dto';
7
-
8
- @Injectable()
9
- export class ArticleDataLoader {
10
- constructor(
11
- @Inject(RESOLVED_ARTICLE_REPO)
12
- private readonly articleRepo: Repository<BaseArticleEntity>,
13
- ) {}
14
-
15
- private readonly batchLoadCategories = async (
16
- queryArgs: readonly {
17
- articleId: string;
18
- language?: string;
19
- }[],
20
- ): Promise<CategoryDto[][]> => {
21
- const qb = this.articleRepo.createQueryBuilder('articles');
22
-
23
- qb.leftJoinAndSelect('articles.categories', 'categories');
24
- qb.leftJoinAndSelect('categories.multiLanguageNames', 'multiLanguageNames');
25
-
26
- qb.andWhere('articles.id IN (:...ids)', {
27
- ids: queryArgs.map(arg => arg.articleId),
28
- });
29
-
30
- const articles = await qb.getMany();
31
-
32
- const categoryMap = articles.reduce<Record<string, CategoryDto[]>>(
33
- (vars, article) =>
34
- article.categories.reduce(
35
- (cVars, category) =>
36
- category.multiLanguageNames.reduce(
37
- (mVars, multiLanguageName) => ({
38
- ...mVars,
39
- [`${article.id}:${multiLanguageName.language}`]: [
40
- ...(mVars[`${article.id}:${multiLanguageName.language}`] || []),
41
- {
42
- ...category,
43
- ...multiLanguageName,
44
- },
45
- ],
46
- }),
47
- cVars,
48
- ),
49
- vars,
50
- ),
51
- {},
52
- );
53
-
54
- return queryArgs.map(arg => categoryMap[`${arg.articleId}:${arg.language ?? DEFAULT_LANGUAGE}`] ?? []);
55
- };
56
-
57
- readonly categoriesLoader = new DataLoader<
58
- {
59
- articleId: string;
60
- language?: string;
61
- },
62
- CategoryDto[],
63
- string
64
- >(this.batchLoadCategories, {
65
- cache: true,
66
- cacheMap: new LRUCache<string, Promise<CategoryDto[]>>({
67
- ttl: 1000 * 60, // 1 minute
68
- ttlAutopurge: true,
69
- max: 1000,
70
- }),
71
- cacheKeyFn: (queryArgs): string => `${queryArgs.articleId}:${queryArgs.language ?? DEFAULT_LANGUAGE}`,
72
- });
73
-
74
- readonly categoriesLoaderNoCache = new DataLoader<
75
- {
76
- articleId: string;
77
- language?: string;
78
- },
79
- CategoryDto[],
80
- string
81
- >(this.batchLoadCategories, {
82
- cache: false,
83
- });
84
- }
@@ -1,36 +0,0 @@
1
- import { Inject, Injectable } from '@nestjs/common';
2
- import { BaseMemberEntity, RESOLVED_MEMBER_REPO } from '@rytass/member-base-nestjs-module';
3
- import DataLoader from 'dataloader';
4
- import { LRUCache } from 'lru-cache';
5
- import { Repository } from 'typeorm';
6
-
7
- @Injectable()
8
- export class MemberDataLoader {
9
- constructor(
10
- @Inject(RESOLVED_MEMBER_REPO)
11
- private readonly memberRepo: Repository<BaseMemberEntity>,
12
- ) {}
13
-
14
- readonly loader = new DataLoader<string, BaseMemberEntity | null>(
15
- async (ids): Promise<(BaseMemberEntity | null)[]> => {
16
- const qb = this.memberRepo.createQueryBuilder('members');
17
-
18
- qb.withDeleted();
19
- qb.andWhere('members.id IN (:...ids)', { ids });
20
-
21
- const users = await qb.getMany();
22
-
23
- const userMap = new Map(users.map(user => [user.id, user]));
24
-
25
- return ids.map(id => userMap.get(id) ?? null);
26
- },
27
- {
28
- cache: true,
29
- cacheMap: new LRUCache<string, Promise<BaseMemberEntity | null>>({
30
- ttl: 1000 * 60 * 10, // 10 minutes
31
- ttlAutopurge: true,
32
- max: 1000,
33
- }),
34
- },
35
- );
36
- }
@@ -1,45 +0,0 @@
1
- import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
- import { DEFAULT_LANGUAGE } from '@rytass/cms-base-nestjs-module';
3
- import { Request } from 'express';
4
-
5
- export const LANGUAGE_HEADER_KEY = 'x-language';
6
-
7
- export const Language = createParamDecorator(async (_data: unknown, context: ExecutionContext): Promise<string> => {
8
- const contextType = context.getType<'http' | 'graphql'>();
9
-
10
- switch (contextType) {
11
- case 'graphql': {
12
- const { GqlExecutionContext } = await import('@nestjs/graphql');
13
-
14
- const ctx = GqlExecutionContext.create(context).getContext<{
15
- req: Request;
16
- }>();
17
-
18
- const headers = ctx.req.headers;
19
- const requestLanguage = headers[LANGUAGE_HEADER_KEY];
20
-
21
- if (typeof requestLanguage === 'string') return requestLanguage;
22
-
23
- const acceptLanguage = headers['accept-language'] ?? '';
24
-
25
- if (!acceptLanguage || typeof acceptLanguage !== 'string') return DEFAULT_LANGUAGE;
26
-
27
- return acceptLanguage.split(',')[0].split(';')[0].trim();
28
- }
29
-
30
- case 'http':
31
- default: {
32
- const headers = (context.switchToHttp().getRequest() as Request).headers;
33
-
34
- const requestLanguage = headers[LANGUAGE_HEADER_KEY];
35
-
36
- if (typeof requestLanguage === 'string') return requestLanguage;
37
-
38
- const acceptLanguage = headers['accept-language'] ?? '';
39
-
40
- if (!acceptLanguage || typeof acceptLanguage !== 'string') return DEFAULT_LANGUAGE;
41
-
42
- return acceptLanguage.split(',')[0].split(';')[0].trim();
43
- }
44
- }
45
- });