@merkaly/api 0.2.5-4 → 0.2.5-6

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 (241) hide show
  1. package/.bin/deploy.sh +9 -0
  2. package/.bin/package.sh +12 -0
  3. package/.docker/Dockerfile +21 -0
  4. package/.dockerignore +12 -0
  5. package/.github/dependabot.yml +17 -0
  6. package/.github/semantic.yml +5 -0
  7. package/.github/workflows/pull_request.yml +35 -0
  8. package/.prettierrc +5 -0
  9. package/app.ts +11 -0
  10. package/authCertificate.pem +19 -0
  11. package/nest-cli.json +8 -0
  12. package/package.json +66 -78
  13. package/src/abstracts/abstarct.repository.ts +62 -0
  14. package/src/abstracts/abstract.controller.ts +18 -0
  15. package/src/abstracts/abstract.entity.ts +22 -0
  16. package/src/abstracts/abstract.router.ts +7 -0
  17. package/src/abstracts/abstract.validator.ts +61 -0
  18. package/src/app.config.ts +59 -0
  19. package/src/app.console.ts +24 -0
  20. package/src/app.guard.ts +39 -0
  21. package/src/app.module.ts +54 -0
  22. package/src/app.strategy.ts +21 -0
  23. package/src/commands/seed.command.ts +263 -0
  24. package/src/decorators/public.decorator.ts +5 -0
  25. package/src/decorators/user.decorator.ts +30 -0
  26. package/src/exceptions/missing-identity.exception.ts +11 -0
  27. package/src/interceptors/mongoose.interceptor.ts +63 -0
  28. package/src/main.ts +27 -0
  29. package/src/middlewares/router.middleware.ts +14 -0
  30. package/src/modules/asset/asset.module.ts +19 -0
  31. package/src/modules/asset/files/file.controller.ts +22 -0
  32. package/src/modules/asset/files/file.entity.ts +24 -0
  33. package/src/modules/asset/files/file.module.ts +21 -0
  34. package/src/modules/asset/files/file.repository.ts +44 -0
  35. package/src/modules/asset/files/file.schema.ts +8 -0
  36. package/src/modules/asset/files/file.service.ts +4 -0
  37. package/src/modules/auth/auth.controller.ts +57 -0
  38. package/src/modules/auth/auth.module.ts +20 -0
  39. package/src/modules/auth/organizations/organization.controller.ts +20 -0
  40. package/src/modules/auth/organizations/organization.entity.ts +22 -0
  41. package/src/modules/auth/organizations/organization.module.ts +21 -0
  42. package/src/modules/auth/organizations/organization.repository.ts +16 -0
  43. package/src/modules/auth/organizations/organization.schema.ts +8 -0
  44. package/src/modules/auth/users/user.controller.ts +23 -0
  45. package/src/modules/auth/users/user.entity.ts +25 -0
  46. package/src/modules/auth/users/user.module.ts +20 -0
  47. package/src/modules/auth/users/user.repository.ts +79 -0
  48. package/src/modules/auth/users/user.schema.ts +8 -0
  49. package/src/modules/auth/users/user.validator.ts +32 -0
  50. package/src/modules/command.module.ts +15 -0
  51. package/src/modules/global.module.ts +46 -0
  52. package/src/modules/inventory/brands/brand.controller.ts +44 -0
  53. package/src/modules/inventory/brands/brand.entity.ts +20 -0
  54. package/src/modules/inventory/brands/brand.module.ts +20 -0
  55. package/src/modules/inventory/brands/brand.repository.ts +40 -0
  56. package/src/modules/inventory/brands/brand.schema.ts +8 -0
  57. package/src/modules/inventory/brands/brand.validator.ts +31 -0
  58. package/src/modules/inventory/categories/category.controller.ts +42 -0
  59. package/src/modules/inventory/categories/category.entity.ts +15 -0
  60. package/src/modules/inventory/categories/category.module.ts +19 -0
  61. package/src/modules/inventory/categories/category.repository.ts +34 -0
  62. package/src/modules/inventory/categories/category.schema.ts +8 -0
  63. package/src/modules/inventory/categories/category.validator.ts +20 -0
  64. package/src/modules/inventory/complements/complement.controller.ts +41 -0
  65. package/src/modules/inventory/complements/complement.entity.ts +15 -0
  66. package/src/modules/inventory/complements/complement.module.ts +19 -0
  67. package/src/modules/inventory/complements/complement.repository.ts +37 -0
  68. package/src/modules/inventory/complements/complement.schema.ts +8 -0
  69. package/src/modules/inventory/complements/complement.validator.ts +28 -0
  70. package/src/modules/inventory/inventory.module.ts +23 -0
  71. package/src/modules/inventory/products/documents/attribute.document.ts +14 -0
  72. package/src/modules/inventory/products/documents/dimension.document.ts +16 -0
  73. package/src/modules/inventory/products/product.controller.ts +62 -0
  74. package/src/modules/inventory/products/product.entity.ts +46 -0
  75. package/src/modules/inventory/products/product.module.ts +19 -0
  76. package/src/modules/inventory/products/product.repository.ts +64 -0
  77. package/src/modules/inventory/products/product.schema.ts +19 -0
  78. package/src/modules/inventory/products/product.validator.ts +132 -0
  79. package/src/modules/inventory/products/validators/attributes.validator.ts +15 -0
  80. package/src/modules/inventory/products/validators/dimension.validator.ts +19 -0
  81. package/src/modules/sale/customers/customer.controller.ts +41 -0
  82. package/src/modules/sale/customers/customer.entity.ts +19 -0
  83. package/src/modules/sale/customers/customer.module.ts +18 -0
  84. package/src/modules/sale/customers/customer.repository.ts +30 -0
  85. package/src/modules/sale/customers/customer.schema.ts +8 -0
  86. package/src/modules/sale/customers/customer.validator.ts +43 -0
  87. package/src/modules/sale/orders/documents/address.document.ts +22 -0
  88. package/src/modules/sale/orders/documents/status.document.ts +17 -0
  89. package/src/modules/sale/orders/entities/item.entity.ts +24 -0
  90. package/src/modules/sale/orders/enums/order.status.ts +6 -0
  91. package/src/modules/sale/orders/order.controller.ts +65 -0
  92. package/src/modules/sale/orders/order.entity.ts +46 -0
  93. package/src/modules/sale/orders/order.module.ts +22 -0
  94. package/src/modules/sale/orders/order.repository.ts +122 -0
  95. package/src/modules/sale/orders/order.schema.ts +36 -0
  96. package/src/modules/sale/orders/order.validator.ts +44 -0
  97. package/src/modules/sale/orders/validators/address.validator.ts +50 -0
  98. package/src/modules/sale/orders/validators/billing.validator.ts +11 -0
  99. package/src/modules/sale/orders/validators/item.validator.ts +14 -0
  100. package/src/modules/sale/orders/validators/payment.validator.ts +44 -0
  101. package/src/modules/sale/orders/validators/shipping.validator.ts +14 -0
  102. package/src/modules/sale/payments/entities/status.entity.ts +17 -0
  103. package/src/modules/sale/payments/enums/billing.type.ts +6 -0
  104. package/src/modules/sale/payments/enums/payment.status.ts +7 -0
  105. package/src/modules/sale/payments/enums/shipping.type.ts +4 -0
  106. package/src/modules/sale/payments/payment.controller.ts +45 -0
  107. package/src/modules/sale/payments/payment.entity.ts +25 -0
  108. package/src/modules/sale/payments/payment.module.ts +20 -0
  109. package/src/modules/sale/payments/payment.repository.ts +57 -0
  110. package/src/modules/sale/payments/payment.schema.ts +14 -0
  111. package/src/modules/sale/payments/payment.validator.ts +32 -0
  112. package/src/modules/sale/sale.module.ts +20 -0
  113. package/src/services/auth0.service.ts +49 -0
  114. package/src/services/mongo.service.ts +52 -0
  115. package/test/auth/auth.spec.ts +20 -0
  116. package/test/main.ts +12 -0
  117. package/tsconfig.build.json +4 -0
  118. package/tsconfig.json +21 -0
  119. package/tsconfig.package.json +22 -0
  120. package/.output/abstract/abstract.entity.d.ts +0 -9
  121. package/.output/abstract/abstract.exception.d.ts +0 -11
  122. package/.output/abstract/abstract.exception.js +0 -53
  123. package/.output/abstract/abstract.fixture.d.ts +0 -4
  124. package/.output/abstract/abstract.fixture.js +0 -11
  125. package/.output/abstract/abstract.validator.d.ts +0 -20
  126. package/.output/abstract/abstract.validator.js +0 -105
  127. package/.output/exceptions/missing-identity.exception.d.ts +0 -5
  128. package/.output/exceptions/missing-identity.exception.js +0 -30
  129. package/.output/exceptions/store-not-implemented.exception.d.ts +0 -5
  130. package/.output/exceptions/store-not-implemented.exception.js +0 -31
  131. package/.output/exceptions/store-not-recognized.exception.d.ts +0 -5
  132. package/.output/exceptions/store-not-recognized.exception.js +0 -30
  133. package/.output/modules/asset/files/file.entity.d.ts +0 -10
  134. package/.output/modules/auth/auth.types.d.ts +0 -3
  135. package/.output/modules/auth/auth.types.js +0 -7
  136. package/.output/modules/auth/users/user.validator.d.ts +0 -10
  137. package/.output/modules/auth/users/user.validator.js +0 -50
  138. package/.output/modules/config/organization/organization.entity.d.ts +0 -21
  139. package/.output/modules/config/organization/organization.types.d.ts +0 -23
  140. package/.output/modules/config/organization/organization.types.js +0 -107
  141. package/.output/modules/config/organization/organization.validator.d.ts +0 -18
  142. package/.output/modules/config/organization/organization.validator.js +0 -88
  143. package/.output/modules/insight/validators/order.validator.d.ts +0 -4
  144. package/.output/modules/insight/validators/order.validator.js +0 -27
  145. package/.output/modules/inventory/brands/brand.entity.d.ts +0 -9
  146. package/.output/modules/inventory/brands/brand.exception.d.ts +0 -5
  147. package/.output/modules/inventory/brands/brand.exception.js +0 -40
  148. package/.output/modules/inventory/brands/brand.validator.d.ts +0 -11
  149. package/.output/modules/inventory/brands/brand.validator.js +0 -75
  150. package/.output/modules/inventory/categories/category.entity.d.ts +0 -12
  151. package/.output/modules/inventory/categories/category.exception.d.ts +0 -5
  152. package/.output/modules/inventory/categories/category.exception.js +0 -40
  153. package/.output/modules/inventory/categories/category.fixture.d.ts +0 -5
  154. package/.output/modules/inventory/categories/category.fixture.js +0 -38
  155. package/.output/modules/inventory/categories/category.validator.d.ts +0 -13
  156. package/.output/modules/inventory/categories/category.validator.js +0 -88
  157. package/.output/modules/inventory/products/entities/code.entity.d.ts +0 -5
  158. package/.output/modules/inventory/products/entities/dimension.entity.d.ts +0 -6
  159. package/.output/modules/inventory/products/entities/seo.entity.d.ts +0 -5
  160. package/.output/modules/inventory/products/entities/variant.entity.d.ts +0 -10
  161. package/.output/modules/inventory/products/product.entity.d.ts +0 -26
  162. package/.output/modules/inventory/products/product.exception.d.ts +0 -5
  163. package/.output/modules/inventory/products/product.exception.js +0 -40
  164. package/.output/modules/inventory/products/product.fixture.d.ts +0 -5
  165. package/.output/modules/inventory/products/product.fixture.js +0 -39
  166. package/.output/modules/inventory/products/product.validator.d.ts +0 -38
  167. package/.output/modules/inventory/products/product.validator.js +0 -235
  168. package/.output/modules/inventory/products/schemas/variant.schema.d.ts +0 -27
  169. package/.output/modules/inventory/products/schemas/variant.schema.js +0 -6
  170. package/.output/modules/inventory/products/validators/code.validator.d.ts +0 -5
  171. package/.output/modules/inventory/products/validators/code.validator.js +0 -37
  172. package/.output/modules/inventory/products/validators/dimension.validator.d.ts +0 -6
  173. package/.output/modules/inventory/products/validators/dimension.validator.js +0 -43
  174. package/.output/modules/inventory/products/validators/seo.validator.d.ts +0 -5
  175. package/.output/modules/inventory/products/validators/seo.validator.js +0 -34
  176. package/.output/modules/inventory/products/validators/variant.validator.d.ts +0 -9
  177. package/.output/modules/inventory/products/validators/variant.validator.js +0 -39
  178. package/.output/modules/inventory/properties/property.entity.d.ts +0 -8
  179. package/.output/modules/inventory/properties/property.exception.d.ts +0 -5
  180. package/.output/modules/inventory/properties/property.exception.js +0 -40
  181. package/.output/modules/inventory/properties/property.types.d.ts +0 -6
  182. package/.output/modules/inventory/properties/property.types.js +0 -10
  183. package/.output/modules/inventory/properties/property.validator.d.ts +0 -12
  184. package/.output/modules/inventory/properties/property.validator.js +0 -79
  185. package/.output/modules/layout/pages/page.entity.d.ts +0 -8
  186. package/.output/modules/layout/pages/page.fixture.d.ts +0 -5
  187. package/.output/modules/layout/pages/page.fixture.js +0 -36
  188. package/.output/modules/layout/pages/page.types.d.ts +0 -20
  189. package/.output/modules/layout/pages/page.types.js +0 -2
  190. package/.output/modules/layout/pages/page.validator.d.ts +0 -8
  191. package/.output/modules/layout/pages/page.validator.js +0 -61
  192. package/.output/modules/sale/customers/customer.entity.d.ts +0 -12
  193. package/.output/modules/sale/customers/customer.exception.d.ts +0 -5
  194. package/.output/modules/sale/customers/customer.exception.js +0 -40
  195. package/.output/modules/sale/customers/customer.validator.d.ts +0 -18
  196. package/.output/modules/sale/customers/customer.validator.js +0 -107
  197. package/.output/modules/sale/orders/billing/billing.entity.d.ts +0 -10
  198. package/.output/modules/sale/orders/billing/billing.types.d.ts +0 -9
  199. package/.output/modules/sale/orders/billing/billing.types.js +0 -14
  200. package/.output/modules/sale/orders/billing/billing.validator.d.ts +0 -9
  201. package/.output/modules/sale/orders/billing/billing.validator.js +0 -42
  202. package/.output/modules/sale/orders/billing/entities/address.entity.d.ts +0 -10
  203. package/.output/modules/sale/orders/billing/entities/customer.entity.d.ts +0 -5
  204. package/.output/modules/sale/orders/billing/entities/status.entity.d.ts +0 -6
  205. package/.output/modules/sale/orders/billing/validators/address.validator.d.ts +0 -10
  206. package/.output/modules/sale/orders/billing/validators/address.validator.js +0 -56
  207. package/.output/modules/sale/orders/billing/validators/customer.validator.d.ts +0 -5
  208. package/.output/modules/sale/orders/billing/validators/customer.validator.js +0 -36
  209. package/.output/modules/sale/orders/customer/customer.entity.d.ts +0 -5
  210. package/.output/modules/sale/orders/customer/customer.validator.d.ts +0 -5
  211. package/.output/modules/sale/orders/customer/customer.validator.js +0 -36
  212. package/.output/modules/sale/orders/item/item.entity.d.ts +0 -9
  213. package/.output/modules/sale/orders/item/item.schema.d.ts +0 -27
  214. package/.output/modules/sale/orders/item/item.schema.js +0 -9
  215. package/.output/modules/sale/orders/item/item.validator.d.ts +0 -4
  216. package/.output/modules/sale/orders/item/item.validator.js +0 -29
  217. package/.output/modules/sale/orders/order.entity.d.ts +0 -21
  218. package/.output/modules/sale/orders/order.exception.d.ts +0 -13
  219. package/.output/modules/sale/orders/order.exception.js +0 -46
  220. package/.output/modules/sale/orders/order.validator.d.ts +0 -28
  221. package/.output/modules/sale/orders/order.validator.js +0 -140
  222. package/.output/modules/sale/orders/shipping/entities/address.entity.d.ts +0 -10
  223. package/.output/modules/sale/orders/shipping/entities/customer.entity.d.ts +0 -5
  224. package/.output/modules/sale/orders/shipping/entities/status.entity.d.ts +0 -6
  225. package/.output/modules/sale/orders/shipping/shipping.entity.d.ts +0 -11
  226. package/.output/modules/sale/orders/shipping/shipping.types.d.ts +0 -11
  227. package/.output/modules/sale/orders/shipping/shipping.types.js +0 -16
  228. package/.output/modules/sale/orders/shipping/shipping.validator.d.ts +0 -10
  229. package/.output/modules/sale/orders/shipping/shipping.validator.js +0 -48
  230. package/.output/modules/sale/orders/shipping/validators/address.validator.d.ts +0 -10
  231. package/.output/modules/sale/orders/shipping/validators/address.validator.js +0 -56
  232. package/.output/modules/sale/orders/shipping/validators/customer.validator.d.ts +0 -5
  233. package/.output/modules/sale/orders/shipping/validators/customer.validator.js +0 -36
  234. package/.output/modules/sale/orders/status/status.entity.d.ts +0 -6
  235. package/.output/modules/sale/orders/status/status.validator.d.ts +0 -8
  236. package/.output/modules/sale/orders/status/status.validator.js +0 -12
  237. package/.output/services/logger.service.d.ts +0 -11
  238. package/.output/services/logger.service.js +0 -50
  239. package/.output/types.d.ts +0 -18
  240. package/.output/types.js +0 -2
  241. package/LICENSE +0 -674
@@ -0,0 +1,54 @@
1
+ import { MiddlewareConsumer, Module, NestModule, RequestMethod, Scope } from '@nestjs/common';
2
+ import { ConfigModule } from '@nestjs/config';
3
+ import { APP_GUARD, APP_INTERCEPTOR, RouterModule, Routes } from '@nestjs/core';
4
+ import { JwtModule } from '@nestjs/jwt';
5
+ import { PassportModule } from '@nestjs/passport';
6
+ import { ConsoleModule } from 'nestjs-console';
7
+ import { AuthGuard } from './app.guard';
8
+ import { AppStrategy } from './app.strategy';
9
+ import { MongoInterceptor } from './interceptors/mongoose.interceptor';
10
+ import { RouterMiddleware } from './middlewares/router.middleware';
11
+ import { AssetModule } from './modules/asset/asset.module';
12
+ import { AuthModule } from './modules/auth/auth.module';
13
+ import { CommandsModule } from './modules/command.module';
14
+ import { GlobalModule } from './modules/global.module';
15
+ import { InventoryModule } from './modules/inventory/inventory.module';
16
+ import { SaleModule } from './modules/sale/sale.module';
17
+
18
+ export const router = [AuthModule, AssetModule, ConfigModule, InventoryModule, SaleModule];
19
+
20
+ @Module({
21
+ controllers: [],
22
+ imports: [
23
+ ...router,
24
+ GlobalModule.register(),
25
+ RouterModule.register(router as Routes),
26
+ JwtModule.register({ global: true, signOptions: { expiresIn: '60s' } }),
27
+ ConfigModule.forRoot({ isGlobal: true }),
28
+ PassportModule,
29
+ ConsoleModule,
30
+ CommandsModule.register(),
31
+ ],
32
+ providers: [
33
+ AppStrategy,
34
+ {
35
+ provide: APP_GUARD,
36
+ useClass: AuthGuard,
37
+ },
38
+ {
39
+ provide: APP_INTERCEPTOR,
40
+ scope: Scope.REQUEST,
41
+ useClass: MongoInterceptor,
42
+ },
43
+ ],
44
+ })
45
+ export class AppModule implements NestModule {
46
+ public configure(consumer: MiddlewareConsumer) {
47
+ consumer
48
+ .apply(RouterMiddleware)
49
+ .exclude({ path: '/auth/resolve', method: RequestMethod.GET })
50
+ .forRoutes({ path: '/*', method: RequestMethod.ALL });
51
+
52
+ return consumer;
53
+ }
54
+ }
@@ -0,0 +1,21 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { PassportStrategy } from '@nestjs/passport';
3
+ import { ExtractJwt, Strategy, StrategyOptions } from 'passport-jwt';
4
+ import { AppConfig } from './app.config';
5
+ import { DecodedUser } from './decorators/user.decorator';
6
+
7
+ @Injectable()
8
+ export class AppStrategy extends PassportStrategy(Strategy) {
9
+ public constructor() {
10
+ const strategy: StrategyOptions = {
11
+ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
12
+ secretOrKey: AppConfig.AUTH0.certificate,
13
+ };
14
+
15
+ super(strategy);
16
+ }
17
+
18
+ public validate(user: DecodedUser) {
19
+ return user;
20
+ }
21
+ }
@@ -0,0 +1,263 @@
1
+ import { faker } from '@faker-js/faker/locale/pt_BR';
2
+ import { Inject } from '@nestjs/common';
3
+ import { InjectConnection } from '@nestjs/mongoose';
4
+ import { Connection } from 'mongoose';
5
+ import { Command, Console } from 'nestjs-console';
6
+ import process from 'process';
7
+ import { FileRepository } from '../modules/asset/files/file.repository';
8
+ import { FileSchema } from '../modules/asset/files/file.schema';
9
+ import { UserRepository } from '../modules/auth/users/user.repository';
10
+ import { UserSchema } from '../modules/auth/users/user.schema';
11
+ import { CreateUserValidator } from '../modules/auth/users/user.validator';
12
+ import { BrandSchema } from '../modules/inventory/brands/brand.schema';
13
+ import { CategoryRepository } from '../modules/inventory/categories/category.repository';
14
+ import { CategorySchema } from '../modules/inventory/categories/category.schema';
15
+ import { CreateCategoryValidator } from '../modules/inventory/categories/category.validator';
16
+ import { ProductRepository } from '../modules/inventory/products/product.repository';
17
+ import { ProductSchema } from '../modules/inventory/products/product.schema';
18
+ import { CreateProductValidator } from '../modules/inventory/products/product.validator';
19
+ import { OrderStatus } from '../modules/sale/orders/enums/order.status';
20
+ import { OrderRepository } from '../modules/sale/orders/order.repository';
21
+ import { CreateOrderValidator } from '../modules/sale/orders/order.validator';
22
+ import { BillingType } from '../modules/sale/payments/enums/billing.type';
23
+ import { PaymentStatus } from '../modules/sale/payments/enums/payment.status';
24
+ import { ShippingType } from '../modules/sale/payments/enums/shipping.type';
25
+
26
+ @Console({ command: 'seed' })
27
+ export class SeedCommand {
28
+ @Inject()
29
+ protected readonly $productRepository: ProductRepository;
30
+
31
+ @Inject()
32
+ protected readonly $categoryRepository: CategoryRepository;
33
+
34
+ @Inject()
35
+ protected readonly $userRepository: UserRepository;
36
+
37
+ @Inject()
38
+ protected readonly $orderRepository: OrderRepository;
39
+
40
+ @Inject()
41
+ protected readonly $usersRepository: UserRepository;
42
+
43
+ @Inject()
44
+ protected readonly $categoriesRepository: CategoryRepository;
45
+
46
+ @Inject()
47
+ protected readonly $filesRepository: FileRepository;
48
+
49
+ @InjectConnection()
50
+ private connection: Connection;
51
+
52
+ @Command({ command: 'app', description: 'Seed entire app with random data' })
53
+ public async seedEntireApp() {
54
+ const list = [];
55
+
56
+ list.push(
57
+ this.connection.collection(ProductSchema.name).deleteMany(),
58
+ this.connection.collection(CategorySchema.name).deleteMany(),
59
+ this.connection.collection(BrandSchema.name).deleteMany(),
60
+
61
+ this.connection.collection(FileSchema.name).deleteMany(),
62
+ this.connection.collection(UserSchema.name).deleteMany(),
63
+ );
64
+
65
+ await Promise.all(list);
66
+
67
+ await this.generateUser();
68
+ await this.generateCategories();
69
+ await this.generateProducts();
70
+ await this.generateOrders();
71
+
72
+ return process?.exit?.(1);
73
+ }
74
+
75
+ @Command({ command: 'categories <counter>', description: 'Generate random categories' })
76
+ public async generateCategories(counter = 10) {
77
+ return this.generate(() => {
78
+ const category = new CreateCategoryValidator();
79
+ category.name = faker.lorem.words(2).concat(faker.helpers.replaceSymbols('********'));
80
+ category.description = faker.lorem.sentence();
81
+
82
+ return this.$categoryRepository.create(category);
83
+ }, counter);
84
+ }
85
+
86
+ @Command({ command: 'products <counter>', description: 'Generate random products' })
87
+ public async generateProducts(counter = 50) {
88
+ const { items: categories } = await this.$categoriesRepository.find();
89
+
90
+ await this.generate(async () => {
91
+ const validator = new CreateProductValidator();
92
+
93
+ validator.active = faker.datatype.boolean({ probability: 0.9 });
94
+ validator.name = `${faker.commerce.productName()} ${faker.helpers.replaceSymbols('*****')}`;
95
+ validator.description = faker.lorem.lines({ max: 6, min: 3 });
96
+ validator.price = Math.round(Math.random() * 100_000);
97
+
98
+ validator.attributes.units = faker.helpers.arrayElement([1, 5, 10]);
99
+ validator.attributes.sku = faker.helpers.replaceSymbols('*******');
100
+ validator.attributes.stock = faker.number.int({ min: 0, max: 100 });
101
+
102
+ if (faker.datatype.boolean({ probability: 0.9 })) {
103
+ validator.category = faker.helpers.arrayElement(categories)._id;
104
+ }
105
+
106
+ if (faker.datatype.boolean({ probability: 0.8 })) {
107
+ const files = await this.generate(() => {
108
+ const url = `https://cartzilla.createx.studio/img/shop/catalog/${faker.number
109
+ .int({ max: 72, min: 1 })
110
+ .toString()
111
+ .padStart(2, '0')}.jpg`;
112
+
113
+ return this.$filesRepository.create({
114
+ description: faker.lorem.sentence(),
115
+ name: faker.helpers.replaceSymbols('********.jpg'),
116
+ size: faker.number.int(),
117
+ type: faker.system.mimeType(),
118
+ url: url,
119
+ weak: false,
120
+ });
121
+ }, faker.number.int({ max: 5, min: 0 }));
122
+
123
+ validator.pictures = files.map(({ _id }) => _id);
124
+ }
125
+
126
+ return this.$productRepository.create(validator);
127
+ }, counter);
128
+ }
129
+
130
+ @Command({ command: 'users <counter>', description: 'Generate random users' })
131
+ public async generateUser(counter = 50) {
132
+ return this.generate(() => {
133
+ const user = new CreateUserValidator();
134
+
135
+ user.auth0 = faker.database.mongodbObjectId();
136
+ user.name = faker.person.fullName();
137
+ user.email = faker.internet.email({ lastName: user.name });
138
+ user.picture = faker.internet.avatar();
139
+ user.locale = faker.helpers.arrayElement(['es', 'pt', 'en']);
140
+
141
+ return this.$userRepository.create(user);
142
+ }, counter);
143
+ }
144
+
145
+ @Command({ command: 'orders <counter>', description: 'Generate random users' })
146
+ public async generateOrders(counter = 300) {
147
+ const { items: users } = await this.$userRepository.find();
148
+ const { items: products } = await this.$productRepository.find();
149
+
150
+ return this.generate(async () => {
151
+ const order = new CreateOrderValidator();
152
+ order.description = faker.lorem.sentence();
153
+
154
+ order.billing.type = faker.helpers.enumValue(BillingType);
155
+ order.billing.address = {
156
+ city: faker.location.city(),
157
+ code: faker.location.zipCode(),
158
+ country: faker.location.countryCode('alpha-2'),
159
+ line1: `${faker.location.buildingNumber()} ${faker.location.street()}`,
160
+ line2: faker.location.secondaryAddress(),
161
+ state: faker.location.state(),
162
+ };
163
+
164
+ order.shipping.type = faker.helpers.enumValue(ShippingType);
165
+ order.shipping.email = faker.internet.email();
166
+ order.shipping.phone = faker.phone.number();
167
+ order.shipping.name = faker.person.fullName();
168
+ order.shipping.address = {
169
+ city: faker.location.city(),
170
+ code: faker.location.zipCode(),
171
+ country: faker.location.countryCode('alpha-2'),
172
+ line1: `${faker.location.buildingNumber()} ${faker.location.street()}`,
173
+ line2: faker.location.secondaryAddress(),
174
+ state: faker.location.state(),
175
+ };
176
+
177
+ const items = faker.number.int({ max: 10, min: 1 });
178
+
179
+ order.items = [...Array(items)].map(() => ({
180
+ product: faker.helpers.arrayElement(products)._id,
181
+ quantity: Number(faker.number.int({ max: 10, min: 1 })),
182
+ }));
183
+
184
+ const randomUser = faker.helpers.arrayElement(users);
185
+
186
+ const createdOrder = await this.$orderRepository.create(order, randomUser);
187
+
188
+ const generateStatus = (state: OrderStatus) => {
189
+ const lastDate = faker.date.past({
190
+ refDate: createdOrder.status[createdOrder.status.length - 1]?.date,
191
+ years: 1,
192
+ });
193
+
194
+ return createdOrder.status.push({
195
+ date: lastDate,
196
+ name: state,
197
+ user: randomUser._id as any,
198
+ });
199
+ };
200
+
201
+ const generatePayment = (state: PaymentStatus) => {
202
+ const lastDate = faker.date.past({
203
+ refDate: createdOrder.status[createdOrder.status.length - 1]?.date,
204
+ years: 1,
205
+ });
206
+
207
+ if (typeof createdOrder.payment === 'string') {
208
+ return createdOrder;
209
+ }
210
+
211
+ return createdOrder.payment.status.push({
212
+ date: lastDate,
213
+ name: state,
214
+ user: randomUser._id as any,
215
+ });
216
+ };
217
+
218
+ faker.helpers.maybe(() => generateStatus(OrderStatus.ACCEPTED), {
219
+ probability: 0.9,
220
+ });
221
+ faker.helpers.maybe(() => generateStatus(OrderStatus.COMPLETED), {
222
+ probability: 0.6,
223
+ });
224
+ faker.helpers.maybe(() => generateStatus(OrderStatus.CANCELED), {
225
+ probability: 0.3,
226
+ });
227
+
228
+ faker.helpers.maybe(() => generatePayment(PaymentStatus.WAITING), {
229
+ probability: 0.8,
230
+ });
231
+ faker.helpers.maybe(() => generatePayment(PaymentStatus.PAID), {
232
+ probability: 0.6,
233
+ });
234
+ faker.helpers.maybe(() => generatePayment(PaymentStatus.CANCELLED), {
235
+ probability: 0.4,
236
+ });
237
+ faker.helpers.maybe(() => generatePayment(PaymentStatus.REFUNDED), {
238
+ probability: 0.2,
239
+ });
240
+
241
+ await createdOrder.updateOne({
242
+ $set: { createdAt: faker.date.past({ years: 3 }) },
243
+ });
244
+
245
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
246
+ // @ts-ignore
247
+ await createdOrder.payment.save();
248
+ await createdOrder.save();
249
+
250
+ return createdOrder;
251
+ }, counter);
252
+ }
253
+
254
+ private generate<T = unknown>(hook: (index: number) => Promise<T>, lenght: number) {
255
+ const listOfPromises: Promise<T>[] = [];
256
+
257
+ for (let iterator = 0; iterator < Number(lenght); iterator++) {
258
+ listOfPromises.push(hook(iterator));
259
+ }
260
+
261
+ return Promise.all(listOfPromises);
262
+ }
263
+ }
@@ -0,0 +1,5 @@
1
+ import { CustomDecorator, SetMetadata } from '@nestjs/common';
2
+
3
+ export const IS_PUBLIC_KEY = 'isPublic';
4
+
5
+ export const Public: () => CustomDecorator = () => SetMetadata(IS_PUBLIC_KEY, true);
@@ -0,0 +1,30 @@
1
+ import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+
4
+ export interface DecodedUser {
5
+ iss: string;
6
+ sub: string;
7
+ aud: string[];
8
+ iat: number;
9
+ exp: number;
10
+ azp: string;
11
+ scope: string;
12
+ org_id?: string;
13
+ given_name: string;
14
+ family_name: string;
15
+ nickname?: string;
16
+ name: string;
17
+ picture: string;
18
+ locale: 'es';
19
+ updated_at: Date;
20
+ email: string;
21
+ email_verified: boolean;
22
+ sid: string;
23
+ nonce: string;
24
+ }
25
+
26
+ export const GetUser = createParamDecorator((key: keyof DecodedUser, ctx: ExecutionContext) => {
27
+ const { user } = ctx.switchToHttp().getRequest<Request>();
28
+
29
+ return key ? user?.[key] : user;
30
+ });
@@ -0,0 +1,11 @@
1
+ import { PreconditionFailedException } from '@nestjs/common';
2
+
3
+ export class MissingIdentityException extends PreconditionFailedException {
4
+ public constructor() {
5
+ super('Missing identity parameter on your request');
6
+ }
7
+
8
+ public static throw() {
9
+ throw new MissingIdentityException();
10
+ }
11
+ }
@@ -0,0 +1,63 @@
1
+ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
2
+ import { InjectConnection, InjectModel } from '@nestjs/mongoose';
3
+ import { Connection, Model } from 'mongoose';
4
+ import { finalize } from 'rxjs/operators';
5
+ import { FileEntity } from '../modules/asset/files/file.entity';
6
+ import { FileSchema } from '../modules/asset/files/file.schema';
7
+ import { OrganizationEntity } from '../modules/auth/organizations/organization.entity';
8
+ import { OrganizationSchema } from '../modules/auth/organizations/organization.schema';
9
+ import { UserEntity } from '../modules/auth/users/user.entity';
10
+ import { BrandEntity } from '../modules/inventory/brands/brand.entity';
11
+ import { BrandSchema } from '../modules/inventory/brands/brand.schema';
12
+ import { CategoryEntity } from '../modules/inventory/categories/category.entity';
13
+ import { CategorySchema } from '../modules/inventory/categories/category.schema';
14
+ import { ComplementEntity } from '../modules/inventory/complements/complement.entity';
15
+ import { ComplementSchema } from '../modules/inventory/complements/complement.schema';
16
+ import { ProductEntity } from '../modules/inventory/products/product.entity';
17
+ import { ProductSchema } from '../modules/inventory/products/product.schema';
18
+ import { CustomerEntity } from '../modules/sale/customers/customer.entity';
19
+ import { CustomerSchema } from '../modules/sale/customers/customer.schema';
20
+ import { OrderEntity } from '../modules/sale/orders/order.entity';
21
+ import { OrderSchema } from '../modules/sale/orders/order.schema';
22
+ import { PaymentEntity } from '../modules/sale/payments/payment.entity';
23
+ import { PaymentSchema } from '../modules/sale/payments/payment.schema';
24
+
25
+ @Injectable()
26
+ export class MongoInterceptor implements NestInterceptor {
27
+ @InjectConnection()
28
+ protected readonly $connection: Connection;
29
+
30
+ @InjectModel(OrganizationSchema.name)
31
+ protected readonly authOrganization: Model<OrganizationEntity>;
32
+
33
+ @InjectModel(OrganizationSchema.name)
34
+ protected readonly authUser: Model<UserEntity>;
35
+
36
+ @InjectModel(CategorySchema.name)
37
+ protected readonly inventoryCategory: Model<CategoryEntity>;
38
+
39
+ @InjectModel(FileSchema.name)
40
+ protected readonly assetFile: Model<FileEntity>;
41
+
42
+ @InjectModel(BrandSchema.name)
43
+ protected readonly inventoryBrand: Model<BrandEntity>;
44
+
45
+ @InjectModel(ProductSchema.name)
46
+ protected readonly inventoryProduct: Model<ProductEntity>;
47
+
48
+ @InjectModel(ComplementSchema.name)
49
+ protected readonly inventoryComplement: Model<ComplementEntity>;
50
+
51
+ @InjectModel(OrderSchema.name)
52
+ protected readonly saleOrder: Model<OrderEntity>;
53
+
54
+ @InjectModel(CustomerSchema.name)
55
+ protected readonly saleCustomer: Model<CustomerEntity>;
56
+
57
+ @InjectModel(PaymentSchema.name)
58
+ protected readonly salePayment: Model<PaymentEntity>;
59
+
60
+ public intercept(context: ExecutionContext, next: CallHandler) {
61
+ return next.handle().pipe(finalize(() => this.$connection.close()));
62
+ }
63
+ }
package/src/main.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { Logger } from '@nestjs/common';
2
+ import { HttpsOptions } from '@nestjs/common/interfaces/external/https-options.interface';
3
+ import { NestApplication, NestFactory } from '@nestjs/core';
4
+ // import { readFileSync } from 'fs';
5
+ import { createNestApp } from '../app';
6
+ import { AppConfig } from './app.config';
7
+ import { AppModule } from './app.module';
8
+
9
+ (async () => {
10
+ const httpsOptions: HttpsOptions = undefined;
11
+
12
+ // if (AppConfig.SERVER.isDEV) {
13
+ // httpsOptions = {
14
+ // key: readFileSync('./.cert/key.pem'),
15
+ // cert: readFileSync('./.cert/cert.pem'),
16
+ // };
17
+ // }
18
+
19
+ const app = await NestFactory.create(AppModule, {
20
+ cors: true,
21
+ httpsOptions,
22
+ });
23
+
24
+ return createNestApp(app)
25
+ .listen(AppConfig.SERVER.port)
26
+ .then(async () => Logger.verbose(`Running on: ${await app.getUrl()}`, NestApplication.name));
27
+ })();
@@ -0,0 +1,14 @@
1
+ import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
2
+ import { NextFunction, Request, Response } from 'express';
3
+ import { MongoService } from '../services/mongo.service';
4
+
5
+ @Injectable()
6
+ export class RouterMiddleware implements NestMiddleware {
7
+ public use(req: Request, res: Response, next: NextFunction) {
8
+ const identity = MongoService.extractIdentityFromRequest(req);
9
+
10
+ Logger.debug(`[${req.method}]: ${req.originalUrl}`, identity);
11
+
12
+ return next();
13
+ }
14
+ }
@@ -0,0 +1,19 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { AbstractRouter } from '../../abstracts/abstract.router';
3
+ import { FileModule } from './files/file.module';
4
+
5
+ export const metadata: ModuleMetadata = {
6
+ controllers: [],
7
+ exports: [FileModule],
8
+ imports: [FileModule],
9
+ providers: [],
10
+ };
11
+
12
+ @Module(metadata)
13
+ export class AssetModule extends AbstractRouter {
14
+ public static readonly path = '/asset';
15
+
16
+ public static readonly module = AssetModule;
17
+
18
+ public static readonly children = metadata.imports;
19
+ }
@@ -0,0 +1,22 @@
1
+ import { Controller, Delete, Inject, Param, Post, UploadedFiles, UseInterceptors } from '@nestjs/common';
2
+ import { AnyFilesInterceptor } from '@nestjs/platform-express';
3
+ import { ApiTags } from '@nestjs/swagger';
4
+ import { FileRepository } from './file.repository';
5
+
6
+ @Controller()
7
+ @ApiTags('asset')
8
+ export class FileController {
9
+ @Inject()
10
+ protected readonly $repository: FileRepository;
11
+
12
+ @Post('/')
13
+ @UseInterceptors(AnyFilesInterceptor())
14
+ public async files(@UploadedFiles() images: Express.Multer.File[] = []) {
15
+ return this.$repository.upload(images);
16
+ }
17
+
18
+ @Delete('/:id')
19
+ public delete(@Param('id') id: string) {
20
+ return this.$repository.delete(id);
21
+ }
22
+ }
@@ -0,0 +1,24 @@
1
+ import { Prop, Schema } from '@nestjs/mongoose';
2
+ import { Schema as MongoSchema } from 'mongoose';
3
+ import { AbstractEntity } from '../../../abstracts/abstract.entity';
4
+
5
+ @Schema({ timestamps: true })
6
+ export class FileEntity extends AbstractEntity {
7
+ @Prop({ type: MongoSchema.Types.String, required: true, unique: true })
8
+ public name: string;
9
+
10
+ @Prop({ type: MongoSchema.Types.String, required: true })
11
+ public url: string;
12
+
13
+ @Prop({ type: MongoSchema.Types.Boolean, default: true })
14
+ public weak = true;
15
+
16
+ @Prop({ type: MongoSchema.Types.String, nullable: true })
17
+ public description: string;
18
+
19
+ @Prop({ type: MongoSchema.Types.String })
20
+ public type: string;
21
+
22
+ @Prop({ type: MongoSchema.Types.Number, required: true, default: 0 })
23
+ public size = 0;
24
+ }
@@ -0,0 +1,21 @@
1
+ import { Module, ModuleMetadata } from '@nestjs/common';
2
+ import { AbstractRouter } from '../../../abstracts/abstract.router';
3
+ import { FileController } from './file.controller';
4
+ import { FileRepository } from './file.repository';
5
+ import { FileService } from './file.service';
6
+
7
+ export const metadata: ModuleMetadata = {
8
+ imports: [],
9
+ controllers: [FileController],
10
+ providers: [FileRepository, FileService],
11
+ exports: [FileRepository],
12
+ };
13
+
14
+ @Module(metadata)
15
+ export class FileModule extends AbstractRouter {
16
+ public static readonly path = '/files';
17
+
18
+ public static readonly module = FileModule;
19
+
20
+ public static readonly children = metadata.imports;
21
+ }
@@ -0,0 +1,44 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectModel } from '@nestjs/mongoose';
3
+ import { writeFileSync } from 'fs';
4
+ import { Model } from 'mongoose';
5
+ import { AbstractRepository } from '../../../abstracts/abstarct.repository';
6
+ import { FileEntity } from './file.entity';
7
+ import { FileSchema } from './file.schema';
8
+
9
+ @Injectable()
10
+ export class FileRepository extends AbstractRepository<FileEntity> {
11
+ @InjectModel(FileSchema.name)
12
+ public readonly $model: Model<FileEntity>;
13
+
14
+ public async upload(files: Express.Multer.File[] = []) {
15
+ const assets: FileEntity[] = [];
16
+
17
+ for (const file of files) {
18
+ const asset: FileEntity = new this.$model();
19
+
20
+ const ext = file.originalname.split('.').pop();
21
+ const name = `${asset._id}.${ext}`;
22
+ const filePath = `uploads/${name}`;
23
+
24
+ asset.url = filePath;
25
+ asset.name = name;
26
+ asset.size = file.size;
27
+ asset.type = file.mimetype;
28
+
29
+ assets.push(await this.$model.create(asset));
30
+
31
+ writeFileSync(filePath, file.buffer);
32
+ }
33
+
34
+ return Promise.all(assets);
35
+ }
36
+
37
+ public create(partial: Partial<FileEntity>): Promise<FileEntity> {
38
+ return this.$model.create(partial);
39
+ }
40
+
41
+ public update(id: string, params: unknown): Promise<FileEntity> {
42
+ return Promise.resolve(undefined);
43
+ }
44
+ }
@@ -0,0 +1,8 @@
1
+ import { SchemaFactory } from '@nestjs/mongoose';
2
+ import { FileEntity } from './file.entity';
3
+
4
+ export namespace FileSchema {
5
+ export const name = 'asset_files';
6
+
7
+ export const schema = SchemaFactory.createForClass(FileEntity);
8
+ }
@@ -0,0 +1,4 @@
1
+ import { Injectable } from '@nestjs/common';
2
+
3
+ @Injectable()
4
+ export class FileService {}