@merkaly/api 0.2.4-5 → 0.2.4-7

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 (260) hide show
  1. package/.DS_Store +0 -0
  2. package/.bin/deploy.sh +9 -0
  3. package/.bin/package.sh +7 -0
  4. package/.docker/Dockerfile +21 -0
  5. package/.dockerignore +12 -0
  6. package/.env +21 -0
  7. package/.eslintignore +8 -0
  8. package/.eslintrc.js +35 -0
  9. package/.github/dependabot.yml +17 -0
  10. package/.github/semantic.yml +5 -0
  11. package/.github/workflows/pull_request.yml +35 -0
  12. package/.gitignore +42 -0
  13. package/.husky/.gitignore +1 -0
  14. package/.husky/commit-msg +5 -0
  15. package/.husky/common.sh +8 -0
  16. package/.husky/pre-commit +5 -0
  17. package/.husky/pre-push +4 -0
  18. package/.idea/.gitignore +5 -0
  19. package/.idea/api.iml +13 -0
  20. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  21. package/.idea/inspectionProfiles/Project_Default.xml +11 -0
  22. package/.idea/modules.xml +8 -0
  23. package/.idea/vcs.xml +12 -0
  24. package/.idea/workspace.xml +2320 -0
  25. package/.output/modules/sales/orders/billing/billing.entity.d.ts +8 -6
  26. package/.output/modules/sales/orders/billing/billing.entity.js +14 -9
  27. package/.output/modules/sales/orders/billing/billing.types.d.ts +9 -0
  28. package/.output/modules/sales/orders/billing/billing.types.js +14 -0
  29. package/.output/modules/sales/orders/billing/billing.validator.d.ts +6 -10
  30. package/.output/modules/sales/orders/billing/billing.validator.js +10 -15
  31. package/.output/modules/sales/orders/{address → billing/entities}/address.entity.d.ts +2 -1
  32. package/.output/modules/sales/orders/{address → billing/entities}/address.entity.js +17 -17
  33. package/.output/modules/sales/orders/billing/entities/customer.entity.d.ts +5 -0
  34. package/.output/modules/sales/orders/billing/entities/customer.entity.js +52 -0
  35. package/.output/modules/sales/orders/billing/entities/status.entity.d.ts +6 -0
  36. package/.output/modules/sales/orders/billing/entities/status.entity.js +37 -0
  37. package/.output/modules/sales/orders/{address → billing/validators}/address.validator.d.ts +2 -1
  38. package/.output/modules/sales/orders/{address → billing/validators}/address.validator.js +12 -14
  39. package/.output/modules/sales/orders/billing/validators/customer.validator.d.ts +5 -0
  40. package/.output/modules/sales/orders/billing/validators/customer.validator.js +36 -0
  41. package/.output/modules/sales/orders/customer/customer.validator.d.ts +1 -1
  42. package/.output/modules/sales/orders/customer/customer.validator.js +8 -8
  43. package/.output/modules/sales/orders/order.entity.d.ts +1 -1
  44. package/.output/modules/sales/orders/order.validator.d.ts +2 -2
  45. package/.output/modules/sales/orders/order.validator.js +3 -4
  46. package/.output/modules/sales/orders/shipping/entities/address.entity.d.ts +10 -0
  47. package/.output/modules/sales/orders/shipping/entities/address.entity.js +68 -0
  48. package/.output/modules/sales/orders/shipping/entities/customer.entity.d.ts +5 -0
  49. package/.output/modules/sales/orders/shipping/entities/customer.entity.js +52 -0
  50. package/.output/modules/sales/orders/shipping/entities/status.entity.d.ts +6 -0
  51. package/.output/modules/sales/orders/shipping/entities/status.entity.js +37 -0
  52. package/.output/modules/sales/orders/shipping/shipping.entity.d.ts +8 -6
  53. package/.output/modules/sales/orders/shipping/shipping.entity.js +14 -9
  54. package/.output/modules/sales/orders/shipping/shipping.types.d.ts +11 -0
  55. package/.output/modules/sales/orders/shipping/shipping.types.js +16 -0
  56. package/.output/modules/sales/orders/shipping/shipping.validator.d.ts +6 -9
  57. package/.output/modules/sales/orders/shipping/shipping.validator.js +10 -14
  58. package/.output/modules/sales/orders/shipping/validators/address.validator.d.ts +10 -0
  59. package/.output/modules/sales/orders/shipping/validators/address.validator.js +56 -0
  60. package/.output/modules/sales/orders/shipping/validators/customer.validator.d.ts +5 -0
  61. package/.output/modules/sales/orders/shipping/validators/customer.validator.js +36 -0
  62. package/authCertificate.pem +19 -0
  63. package/cloudbuild.yaml +20 -0
  64. package/commitlint.config.js +3 -0
  65. package/jest.config.js +14 -0
  66. package/merkaly-api-0.2.4-6.tgz +0 -0
  67. package/nest-cli.json +9 -0
  68. package/package.json +8 -7
  69. package/serviceAccount.json +7 -0
  70. package/src/abstract/absctract.listener.ts +2 -0
  71. package/src/abstract/abstract.controller.ts +27 -0
  72. package/src/abstract/abstract.entity.ts +19 -0
  73. package/src/abstract/abstract.exception.ts +56 -0
  74. package/src/abstract/abstract.fixture.ts +7 -0
  75. package/src/abstract/abstract.migration.ts +13 -0
  76. package/src/abstract/abstract.repository.ts +79 -0
  77. package/src/abstract/abstract.router.ts +7 -0
  78. package/src/abstract/abstract.validator.ts +62 -0
  79. package/src/app.config.ts +57 -0
  80. package/src/app.console.ts +30 -0
  81. package/src/app.controller.ts +48 -0
  82. package/src/app.migration.ts +7 -0
  83. package/src/app.module.ts +92 -0
  84. package/src/app.strategy.ts +25 -0
  85. package/src/commands/assets.command.ts +38 -0
  86. package/src/commands/deploy.command.ts +6 -0
  87. package/src/commands/fixture.command.ts +11 -0
  88. package/src/commands/generate.command.ts +286 -0
  89. package/src/decorators/public.decorator.ts +5 -0
  90. package/src/decorators/user.decorator.ts +21 -0
  91. package/src/exceptions/missing-identity.exception.ts +11 -0
  92. package/src/exceptions/store-not-implemented.exception.ts +13 -0
  93. package/src/exceptions/store-not-recognized.exception.ts +11 -0
  94. package/src/guards/auth.guard.ts +43 -0
  95. package/src/guards/organization.guard.ts +39 -0
  96. package/src/interceptors/mongo.interceptor.ts +16 -0
  97. package/src/main.ts +37 -0
  98. package/src/middlewares/logger.middleware.ts +15 -0
  99. package/src/middlewares/organization.middleware.ts +76 -0
  100. package/src/migrations/1667226478717-product_price_enhance.ts +29 -0
  101. package/src/migrations/1667329249561-product_add_seo_code_dimension.ts +37 -0
  102. package/src/migrations/1667601099139-product_activve_and_hashtag.ts +35 -0
  103. package/src/migrations/1668136428972-content_banners-use-as-image.ts +56 -0
  104. package/src/migrations/1680483744321-order-billing-shipping-status.ts +32 -0
  105. package/src/modules/assets/asset.controller.ts +33 -0
  106. package/src/modules/assets/asset.entity.ts +26 -0
  107. package/src/modules/assets/asset.module.ts +21 -0
  108. package/src/modules/assets/asset.repository.ts +51 -0
  109. package/src/modules/assets/asset.schema.ts +4 -0
  110. package/src/modules/assets/asset.service.ts +41 -0
  111. package/src/modules/auth/auth.controller.ts +42 -0
  112. package/src/modules/auth/auth.module.ts +18 -0
  113. package/src/modules/auth/logout.ts +0 -0
  114. package/src/modules/command.module.ts +19 -0
  115. package/src/modules/content/banners/banner.controller.ts +56 -0
  116. package/src/modules/content/banners/banner.entity.ts +17 -0
  117. package/src/modules/content/banners/banner.fixture.ts +19 -0
  118. package/src/modules/content/banners/banner.listener.ts +6 -0
  119. package/src/modules/content/banners/banner.module.ts +21 -0
  120. package/src/modules/content/banners/banner.repository.ts +38 -0
  121. package/src/modules/content/banners/banner.schema.ts +4 -0
  122. package/src/modules/content/banners/banner.types.ts +7 -0
  123. package/src/modules/content/banners/banner.validator.ts +19 -0
  124. package/src/modules/content/content.module.ts +20 -0
  125. package/src/modules/content/pages/page.controller.ts +53 -0
  126. package/src/modules/content/pages/page.entity.ts +27 -0
  127. package/src/modules/content/pages/page.fixture.ts +19 -0
  128. package/src/modules/content/pages/page.listener.ts +6 -0
  129. package/src/modules/content/pages/page.module.ts +21 -0
  130. package/src/modules/content/pages/page.repository.ts +44 -0
  131. package/src/modules/content/pages/page.schema.ts +4 -0
  132. package/src/modules/content/pages/page.types.ts +9 -0
  133. package/src/modules/content/pages/page.validator.ts +29 -0
  134. package/src/modules/global.module.ts +70 -0
  135. package/src/modules/insight/controllers/address.controller.ts +29 -0
  136. package/src/modules/insight/controllers/order.controller.ts +70 -0
  137. package/src/modules/insight/controllers/products.controller.ts +18 -0
  138. package/src/modules/insight/insight.module.ts +24 -0
  139. package/src/modules/insight/validators/order.validator.ts +10 -0
  140. package/src/modules/inventory/brands/brand.controller.ts +59 -0
  141. package/src/modules/inventory/brands/brand.entity.ts +14 -0
  142. package/src/modules/inventory/brands/brand.exception.ts +9 -0
  143. package/src/modules/inventory/brands/brand.listener.ts +18 -0
  144. package/src/modules/inventory/brands/brand.module.ts +19 -0
  145. package/src/modules/inventory/brands/brand.repository.ts +39 -0
  146. package/src/modules/inventory/brands/brand.schema.ts +4 -0
  147. package/src/modules/inventory/brands/brand.validator.ts +23 -0
  148. package/src/modules/inventory/categories/category.controller.ts +59 -0
  149. package/src/modules/inventory/categories/category.entity.ts +21 -0
  150. package/src/modules/inventory/categories/category.exception.ts +9 -0
  151. package/src/modules/inventory/categories/category.fixture.ts +18 -0
  152. package/src/modules/inventory/categories/category.listener.ts +17 -0
  153. package/src/modules/inventory/categories/category.module.ts +19 -0
  154. package/src/modules/inventory/categories/category.repository.ts +40 -0
  155. package/src/modules/inventory/categories/category.schema.ts +4 -0
  156. package/src/modules/inventory/categories/category.validator.ts +30 -0
  157. package/src/modules/inventory/inventory.module.ts +22 -0
  158. package/src/modules/inventory/products/entities/code.entity.ts +15 -0
  159. package/src/modules/inventory/products/entities/dimension.entity.ts +18 -0
  160. package/src/modules/inventory/products/entities/price.entity.ts +12 -0
  161. package/src/modules/inventory/products/entities/seo.entity.ts +15 -0
  162. package/src/modules/inventory/products/product.controller.ts +59 -0
  163. package/src/modules/inventory/products/product.entity.ts +53 -0
  164. package/src/modules/inventory/products/product.exception.ts +9 -0
  165. package/src/modules/inventory/products/product.fixture.ts +19 -0
  166. package/src/modules/inventory/products/product.listener.ts +27 -0
  167. package/src/modules/inventory/products/product.module.ts +20 -0
  168. package/src/modules/inventory/products/product.repository.ts +108 -0
  169. package/src/modules/inventory/products/product.schema.ts +15 -0
  170. package/src/modules/inventory/products/product.validator.ts +71 -0
  171. package/src/modules/inventory/products/validators/code.validator.ts +15 -0
  172. package/src/modules/inventory/products/validators/dimension.validator.ts +19 -0
  173. package/src/modules/inventory/products/validators/price.validator.ts +10 -0
  174. package/src/modules/inventory/products/validators/seo.validator.ts +15 -0
  175. package/src/modules/inventory/properties/property.controller.ts +56 -0
  176. package/src/modules/inventory/properties/property.entity.ts +18 -0
  177. package/src/modules/inventory/properties/property.exception.ts +9 -0
  178. package/src/modules/inventory/properties/property.listener.ts +20 -0
  179. package/src/modules/inventory/properties/property.module.ts +21 -0
  180. package/src/modules/inventory/properties/property.repository.ts +23 -0
  181. package/src/modules/inventory/properties/property.schema.ts +4 -0
  182. package/src/modules/inventory/properties/property.validator.ts +27 -0
  183. package/src/modules/sales/clients/client.controller.ts +60 -0
  184. package/src/modules/sales/clients/client.entity.ts +25 -0
  185. package/src/modules/sales/clients/client.exception.ts +9 -0
  186. package/src/modules/sales/clients/client.listener.ts +20 -0
  187. package/src/modules/sales/clients/client.module.ts +19 -0
  188. package/src/modules/sales/clients/client.repository.ts +37 -0
  189. package/src/modules/sales/clients/client.schema.ts +4 -0
  190. package/src/modules/sales/clients/client.validator.ts +43 -0
  191. package/src/modules/sales/orders/billing/billing.entity.ts +22 -0
  192. package/src/modules/sales/orders/billing/billing.types.ts +10 -0
  193. package/src/modules/sales/orders/billing/billing.validator.ts +21 -0
  194. package/src/modules/sales/orders/billing/entities/address.entity.ts +27 -0
  195. package/src/modules/sales/orders/billing/entities/customer.entity.ts +14 -0
  196. package/src/modules/sales/orders/billing/entities/status.entity.ts +16 -0
  197. package/src/modules/sales/orders/billing/validators/address.validator.ts +28 -0
  198. package/src/modules/sales/orders/billing/validators/customer.validator.ts +14 -0
  199. package/src/modules/sales/orders/customer/customer.entity.ts +14 -0
  200. package/src/modules/sales/orders/customer/customer.validator.ts +14 -0
  201. package/src/modules/sales/orders/item/item.entity.ts +21 -0
  202. package/src/modules/sales/orders/item/item.schema.ts +8 -0
  203. package/src/modules/sales/orders/item/item.validator.ts +10 -0
  204. package/src/modules/sales/orders/order.controller.ts +93 -0
  205. package/src/modules/sales/orders/order.entity.ts +47 -0
  206. package/src/modules/sales/orders/order.listener.ts +20 -0
  207. package/src/modules/sales/orders/order.module.ts +19 -0
  208. package/src/modules/sales/orders/order.repository.ts +189 -0
  209. package/src/modules/sales/orders/order.schema.ts +35 -0
  210. package/src/modules/sales/orders/order.validator.ts +72 -0
  211. package/src/modules/sales/orders/shipping/entities/address.entity.ts +27 -0
  212. package/src/modules/sales/orders/shipping/entities/customer.entity.ts +14 -0
  213. package/src/modules/sales/orders/shipping/entities/status.entity.ts +16 -0
  214. package/src/modules/sales/orders/shipping/shipping.entity.ts +25 -0
  215. package/src/modules/sales/orders/shipping/shipping.types.ts +12 -0
  216. package/src/modules/sales/orders/shipping/shipping.validator.ts +25 -0
  217. package/src/modules/sales/orders/shipping/validators/address.validator.ts +28 -0
  218. package/src/modules/sales/orders/shipping/validators/customer.validator.ts +14 -0
  219. package/src/modules/sales/orders/status/status.entity.ts +16 -0
  220. package/src/modules/sales/orders/status/status.validator.ts +8 -0
  221. package/src/modules/sales/sales.module.ts +20 -0
  222. package/src/modules/setting/connections/connection.controller.ts +27 -0
  223. package/src/modules/setting/connections/connection.module.ts +17 -0
  224. package/src/modules/setting/connections/connection.validator.ts +15 -0
  225. package/src/modules/setting/layout/layout.controller.ts +34 -0
  226. package/src/modules/setting/layout/layout.entity.ts +13 -0
  227. package/src/modules/setting/layout/layout.listener.ts +7 -0
  228. package/src/modules/setting/layout/layout.module.ts +21 -0
  229. package/src/modules/setting/layout/layout.repository.ts +29 -0
  230. package/src/modules/setting/layout/layout.schema.ts +4 -0
  231. package/src/modules/setting/members/member.controller.ts +22 -0
  232. package/src/modules/setting/members/member.module.ts +17 -0
  233. package/src/modules/setting/members/member.validator.ts +3 -0
  234. package/src/modules/setting/organization/organization.controller.ts +33 -0
  235. package/src/modules/setting/organization/organization.entity.ts +27 -0
  236. package/src/modules/setting/organization/organization.listener.ts +46 -0
  237. package/src/modules/setting/organization/organization.module.ts +21 -0
  238. package/src/modules/setting/organization/organization.repository.ts +55 -0
  239. package/src/modules/setting/organization/organization.types.ts +65 -0
  240. package/src/modules/setting/organization/organization.validator.ts +56 -0
  241. package/src/modules/setting/setting.module.ts +23 -0
  242. package/src/modules/setting/theme/theme.controller.ts +34 -0
  243. package/src/modules/setting/theme/theme.entity.ts +13 -0
  244. package/src/modules/setting/theme/theme.listener.ts +6 -0
  245. package/src/modules/setting/theme/theme.module.ts +21 -0
  246. package/src/modules/setting/theme/theme.repository.ts +23 -0
  247. package/src/modules/setting/theme/theme.schema.ts +4 -0
  248. package/src/modules/users/user.controller.ts +75 -0
  249. package/src/modules/users/user.module.ts +20 -0
  250. package/src/modules/users/user.validator.ts +28 -0
  251. package/src/providers/auth0.provider.ts +36 -0
  252. package/src/providers/storage.provider.ts +22 -0
  253. package/src/services/auth0.service.ts +7 -0
  254. package/src/services/logger.service.ts +33 -0
  255. package/src/services/mongo.service.ts +44 -0
  256. package/src/services/storage.service.ts +39 -0
  257. package/src/types.ts +19 -0
  258. package/tsconfig.json +40 -0
  259. package/tsconfig.package.json +20 -0
  260. package/yarn.lock +8782 -0
@@ -0,0 +1,286 @@
1
+ import { faker } from '@faker-js/faker';
2
+ import { Inject } from '@nestjs/common';
3
+ import { Command, Console, createSpinner } from 'nestjs-console';
4
+ import { AssetEntity } from '../modules/assets/asset.entity';
5
+ import { AssetRepository } from '../modules/assets/asset.repository';
6
+ import { PageFixture } from '../modules/content/pages/page.fixture';
7
+ import { PageRepository } from '../modules/content/pages/page.repository';
8
+ import { BrandRepository } from '../modules/inventory/brands/brand.repository';
9
+ import { CreateBrandValidator } from '../modules/inventory/brands/brand.validator';
10
+ import { CategoryRepository } from '../modules/inventory/categories/category.repository';
11
+ import { CreateCategoryValidator } from '../modules/inventory/categories/category.validator';
12
+ import { ProductRepository } from '../modules/inventory/products/product.repository';
13
+ import { CreateProductValidator } from '../modules/inventory/products/product.validator';
14
+ import { ClientRepository } from '../modules/sales/clients/client.repository';
15
+ import { CreateClientValidator } from '../modules/sales/clients/client.validator';
16
+ import { OrderRepository } from '../modules/sales/orders/order.repository';
17
+ import { CreateOrderValidator } from '../modules/sales/orders/order.validator';
18
+ import { StatusType } from '../modules/sales/orders/status/status.validator';
19
+ import { CustomerValidator } from "../modules/sales/orders/customer/customer.validator";
20
+ import { BillingMethod } from "../modules/sales/orders/billing/billing.types";
21
+ import { ShippingMethod } from "../modules/sales/orders/shipping/shipping.types";
22
+ import { MetaAddress } from "../types";
23
+
24
+ @Console({ command: 'generate', description: 'Generate massive fake data' })
25
+ export class GenerateCommand {
26
+ @Inject() protected readonly brandRepository: BrandRepository;
27
+ @Inject() protected readonly categoryRepository: CategoryRepository;
28
+ @Inject() protected readonly productRepository: ProductRepository;
29
+ @Inject() protected readonly clientRepository: ClientRepository;
30
+ @Inject() protected readonly assetRepository: AssetRepository;
31
+ @Inject() protected readonly orderRepository: OrderRepository;
32
+ @Inject() protected readonly pageRepository: PageRepository;
33
+
34
+ private static generate<T = unknown>(iterator: number, promiseCb: () => Promise<T>) {
35
+ const listOfPromises = [];
36
+
37
+ for (let i = 0; i < iterator; i++) {
38
+ listOfPromises.push(promiseCb());
39
+ }
40
+
41
+ return Promise.all(listOfPromises);
42
+ }
43
+
44
+ @Command({ command: 'brands <quantity>', description: 'Generate and persist fake brands' })
45
+ public async generateBrands(quantity = 5) {
46
+ const spinner = createSpinner();
47
+ spinner.start(`Creating ${quantity} new brands`);
48
+
49
+ const callback = () => {
50
+ const brand = new CreateBrandValidator();
51
+ brand.name = [faker.vehicle.manufacturer(), faker.vehicle.model(), faker.lorem.words(1)].join(' ');
52
+ brand.description = faker.lorem.sentence();
53
+
54
+ return this.brandRepository.create(brand);
55
+ };
56
+
57
+ return GenerateCommand.generate(quantity, callback)
58
+ .then(({ length }) => spinner.succeed(`Created ${length} of ${quantity} brands`));
59
+ }
60
+
61
+ @Command({ command: 'categories <quantity>', description: 'Generate and persist fake categories' })
62
+ public async generateCategories(quantity = 10) {
63
+ const spinner = createSpinner();
64
+ spinner.start(`Creating ${quantity} new categories`);
65
+
66
+ const callback = () => {
67
+ const category = new CreateCategoryValidator();
68
+ category.name = faker.lorem.words(3);
69
+ category.description = faker.lorem.sentence();
70
+
71
+ return this.categoryRepository.create(category);
72
+ };
73
+
74
+ return GenerateCommand.generate(quantity, callback)
75
+ .then(({ length }) => spinner.succeed(`Created ${length} of ${quantity} categories`));
76
+ }
77
+
78
+ @Command({ command: 'products <quantity>', description: 'Generate and persist fake products' })
79
+ public async generateProducts(quantity = 100) {
80
+ const spinner = createSpinner();
81
+ spinner.start(`Creating ${quantity} new products`);
82
+
83
+ const allBrands = await this.brandRepository.find();
84
+ const allCategories = await this.categoryRepository.find();
85
+
86
+ const callback = async () => {
87
+ const product = new CreateProductValidator();
88
+
89
+ product.name = `${faker.commerce.product()} ${faker.commerce.product()} ${faker.commerce.product()} `;
90
+ product.description = faker.commerce.productDescription();
91
+
92
+ product.price.sale = Number(faker.commerce.price(1000, 10000, 2));
93
+ product.price.purchase = product.price.sale - Number(faker.commerce.price(80, 100, 2));
94
+
95
+ product.brand = faker.helpers.arrayElement(allBrands.items)._id;
96
+ product.category = faker.helpers.arrayElement(allCategories.items)._id;
97
+
98
+ product.active = faker.datatype.boolean();
99
+
100
+ product.seo.slug = faker.lorem.slug();
101
+ product.seo.title = faker.commerce.productName();
102
+ product.seo.description = faker.commerce.productDescription();
103
+
104
+ product.dimension.depth = faker.datatype.number(100);
105
+ product.dimension.height = faker.datatype.number(100);
106
+ product.dimension.weight = faker.datatype.number(10);
107
+ product.dimension.width = faker.datatype.number(100);
108
+
109
+ product.code.sku = faker.lorem.slug();
110
+ product.code.gtin = faker.lorem.slug();
111
+ product.code.mpn = faker.lorem.slug();
112
+
113
+ product.hashtags = faker.lorem.words().split(' ');
114
+
115
+ const { _id: file1 } = await this.createAsset();
116
+ const { _id: file2 } = await this.createAsset();
117
+ const { _id: file3 } = await this.createAsset();
118
+ const { _id: file4 } = await this.createAsset();
119
+ const { _id: file5 } = await this.createAsset();
120
+
121
+ product.files.push(file1, file2, file3, file4, file5);
122
+
123
+ return this.productRepository.create(product);
124
+ };
125
+
126
+ return GenerateCommand.generate(quantity, callback)
127
+ .then(({ length }) => spinner.succeed(`Created ${length} of ${quantity} products`));
128
+ }
129
+
130
+ @Command({ command: 'clients <quantity>', description: 'Generate and persist fake clients' })
131
+ public async generateClients(quantity = 50) {
132
+ const spinner = createSpinner();
133
+ spinner.start(`Creating ${quantity} new clients`);
134
+
135
+ const callback = () => {
136
+ const client = new CreateClientValidator();
137
+
138
+ client.name = faker.company.name();
139
+ client.email = faker.internet.exampleEmail();
140
+ client.phone = faker.phone.number();
141
+ client.identificationNumber = faker.phone.imei();
142
+
143
+ return this.clientRepository.create(client);
144
+ };
145
+
146
+ return GenerateCommand.generate(quantity, callback)
147
+ .then(({ length }) => spinner.succeed(`Created ${length} of ${quantity} clients`));
148
+ }
149
+
150
+ @Command({ command: 'orders <quantity>', description: 'Generate and persist fake orders' })
151
+ public async generateOrders(quantity = 10) {
152
+ const spinner = createSpinner();
153
+ spinner.start(`Creating ${quantity} new orders`);
154
+
155
+ const allProducts = await this.productRepository.$model.find();
156
+ const allClients = await this.clientRepository.$model.find();
157
+
158
+ const callback = async () => {
159
+ const order = new CreateOrderValidator();
160
+
161
+ const generateAddress = (): MetaAddress => ({
162
+ street: faker.address.streetAddress(false),
163
+ number: faker.address.buildingNumber(),
164
+ complement: faker.address.secondaryAddress(),
165
+ city: faker.address.city(),
166
+ state: faker.address.stateAbbr(),
167
+ country: faker.address.countryCode('alpha-2'),
168
+ code: faker.address.zipCode(),
169
+ });
170
+
171
+ const generateCustomer = (): CustomerValidator => ({
172
+ email: faker.internet.email(),
173
+ name: faker.internet.userName(),
174
+ phone: faker.phone.number(),
175
+ });
176
+
177
+ order.billing = {
178
+ address: generateAddress(),
179
+ customer: generateCustomer(),
180
+ method: faker.helpers.arrayElement(Object.values(BillingMethod))
181
+ };
182
+
183
+ order.shipping = {
184
+ address: generateAddress(),
185
+ customer: generateCustomer(),
186
+ method: faker.helpers.arrayElement(Object.values(ShippingMethod)),
187
+ price: Number(faker.commerce.price(1000, 10000, 2))
188
+ };
189
+
190
+ order.customer = generateCustomer();
191
+
192
+ const items = Number(faker.random.numeric(1).toString());
193
+
194
+ order.items = [...Array(items)].map(() => ({
195
+ quantity: Number(faker.random.numeric(2)),
196
+ product: faker.helpers.arrayElement(allProducts)._id,
197
+ }));
198
+
199
+ order.client = faker.helpers.arrayElement(allClients)._id;
200
+
201
+ const createdOrder = await this.orderRepository.create(order);
202
+ await createdOrder.updateOne({
203
+ $set: {
204
+ createdAt: faker.date.recent(200)
205
+ }
206
+ })
207
+
208
+ const generateStatus = (status: StatusType, date: Date) => ({
209
+ name: status,
210
+ user: faker.internet.email(),
211
+ date: faker.date.recent(10, date),
212
+ });
213
+
214
+ faker.helpers.maybe(() => {
215
+ const status = generateStatus(StatusType.ACCEPTED, createdOrder.createdAt);
216
+ createdOrder.status.push(status);
217
+ return faker.helpers.maybe(() => {
218
+ const status1 = generateStatus(StatusType.IN_PREPARATION, status.date);
219
+ createdOrder.status.push();
220
+ return faker.helpers.maybe(() => {
221
+ const status2 = generateStatus(StatusType.SENDED, status1.date);
222
+ createdOrder.status.push(status2);
223
+ return faker.helpers.maybe(() => {
224
+ const status3 = generateStatus(StatusType.COMPLETED, status2.date);
225
+ createdOrder.status.push();
226
+ return faker.helpers.maybe(() => {
227
+ const status4 = generateStatus(StatusType.CANCELED, status3.date);
228
+ createdOrder.status.push(status4);
229
+ }, { probability: 0.1 });
230
+ }, { probability: 0.3 });
231
+ }, { probability: 0.5 });
232
+ }, { probability: 0.7 });
233
+ }, { probability: 0.9 });
234
+
235
+ return createdOrder.save();
236
+ };
237
+
238
+ for await(const iterator of Array(Number(quantity)).fill(null)) {
239
+ await callback()
240
+ .then(({ fullNumber }) => spinner.text = (`Created order [${fullNumber}]`))
241
+ }
242
+
243
+ return spinner.succeed(`Created ${quantity} orders`)
244
+ }
245
+
246
+ @Command({ command: 'pages <quantity>', description: 'Generate and persist fake content pages' })
247
+ public async generateContentPages(quantity = 10) {
248
+ const spinner = createSpinner();
249
+ spinner.start(`Creating ${quantity} new pages`);
250
+ const fixture = new PageFixture();
251
+
252
+ const callback = async () => {
253
+ const page = fixture.normal();
254
+
255
+ const createPage = await this.pageRepository.create(page);
256
+
257
+ return createPage.save();
258
+ };
259
+
260
+ return GenerateCommand.generate(quantity, callback)
261
+ .then(({ length }) => spinner.succeed(`Created ${length} of ${quantity} pages`));
262
+ }
263
+
264
+ @Command({ command: 'all', description: 'Execute all seeders' })
265
+ public async generateAll() {
266
+ await this.generateBrands(10);
267
+ await this.generateCategories(20);
268
+ await this.generateProducts(100);
269
+
270
+ await this.generateClients(10);
271
+ await this.generateOrders(100);
272
+ }
273
+
274
+ protected async createAsset() {
275
+ const asset: Partial<AssetEntity> = {};
276
+
277
+ asset.name = faker.lorem.words(3);
278
+ asset.description = faker.lorem.sentence();
279
+ asset.url = faker.image.food(635, 475, true);
280
+ asset.weak = false;
281
+ asset.type = faker.system.mimeType();
282
+ asset.size = Number(faker.random.numeric(5));
283
+
284
+ return this.assetRepository.create(asset);
285
+ }
286
+ }
@@ -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,21 @@
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
+ }
14
+
15
+ export const GetUser = createParamDecorator((key: keyof DecodedUser, ctx: ExecutionContext) => {
16
+ const { user } = ctx.switchToHttp().getRequest<Request>();
17
+
18
+ return key
19
+ ? user[key]
20
+ : user;
21
+ });
@@ -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,13 @@
1
+ import { Logger, NotFoundException } from '@nestjs/common';
2
+
3
+ export class StoreNotImplementedException extends NotFoundException {
4
+ public constructor(identity: string) {
5
+ super(`No store found by that id or name: [${identity}]`);
6
+ }
7
+
8
+ public static throw(identity: string) {
9
+
10
+ Logger.warn('Store not found or implemented', identity)
11
+ throw new StoreNotImplementedException(identity);
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ import { NotAcceptableException } from '@nestjs/common/exceptions/not-acceptable.exception';
2
+
3
+ export class StoreNotRecognizedException extends NotAcceptableException {
4
+ public constructor() {
5
+ super(`The store could not be accepted`);
6
+ }
7
+
8
+ public static throw() {
9
+ throw new StoreNotRecognizedException();
10
+ }
11
+ }
@@ -0,0 +1,43 @@
1
+ import { ExecutionContext, Inject, Injectable, UnauthorizedException } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { AuthGuard as JwtGuard } from '@nestjs/passport';
4
+ import { IS_PUBLIC_KEY } from '../decorators/public.decorator';
5
+ import { DecodedUser } from '../decorators/user.decorator';
6
+
7
+ declare module 'express' {
8
+ interface Request {
9
+ user?: DecodedUser;
10
+ }
11
+ }
12
+
13
+ @Injectable()
14
+ export class AuthGuard extends JwtGuard('jwt') {
15
+
16
+ @Inject() private reflector: Reflector;
17
+
18
+ public async canActivate(context: ExecutionContext): Promise<any> {
19
+ const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
20
+ context.getHandler(),
21
+ context.getClass(),
22
+ ]);
23
+
24
+ if (isPublic) {
25
+ return true;
26
+ }
27
+
28
+ return super.canActivate(context);
29
+ }
30
+
31
+ public handleRequest(err: Record<string, unknown>, user: DecodedUser): any {
32
+ if (err) {
33
+ throw err;
34
+ }
35
+
36
+ if (!user) {
37
+ throw new UnauthorizedException();
38
+ }
39
+
40
+ return user;
41
+ }
42
+
43
+ }
@@ -0,0 +1,39 @@
1
+ import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common';
2
+ import { Request } from 'express';
3
+ import { AppController } from '../app.controller';
4
+ import { IS_PUBLIC_KEY } from "../decorators/public.decorator";
5
+ import { Reflector } from "@nestjs/core";
6
+
7
+ @Injectable()
8
+ export class OrganizationGuard implements CanActivate {
9
+ @Inject() private reflector: Reflector;
10
+
11
+ public async canActivate(context: ExecutionContext) {
12
+
13
+ const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
14
+ context.getHandler(),
15
+ context.getClass(),
16
+ ]);
17
+
18
+ if (isPublic) {
19
+ return true;
20
+ }
21
+
22
+ if (context.getType() === 'http') {
23
+ const allowedHandlers: any[] = [AppController.prototype.userOrganizations];
24
+
25
+ if (allowedHandlers.includes(context.getHandler())) {
26
+ return true;
27
+ }
28
+
29
+ const request = context.switchToHttp().getRequest<Request>();
30
+
31
+ const { organization } = request.session;
32
+
33
+ return !!organization?.id;
34
+ }
35
+
36
+ return false;
37
+ }
38
+
39
+ }
@@ -0,0 +1,16 @@
1
+ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
2
+ import { InjectConnection } from '@nestjs/mongoose';
3
+ import { Connection } from 'mongoose';
4
+ import { Observable } from 'rxjs';
5
+ import { finalize } from 'rxjs/operators';
6
+
7
+ @Injectable()
8
+ export class MongoInterceptor implements NestInterceptor {
9
+ @InjectConnection()
10
+ protected readonly $connection: Connection;
11
+
12
+ public intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
13
+ return next.handle()
14
+ .pipe(finalize(() => this.$connection.close()));
15
+ }
16
+ }
package/src/main.ts ADDED
@@ -0,0 +1,37 @@
1
+ import { Logger, ValidationPipe } from '@nestjs/common';
2
+ import { NestApplication, NestFactory } from '@nestjs/core';
3
+ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
4
+ import session from 'express-session';
5
+ import { AppConfig } from './app.config';
6
+ import { AppModule } from './app.module';
7
+ import { AuthGuard } from './guards/auth.guard';
8
+ import { OrganizationGuard } from './guards/organization.guard';
9
+
10
+ (async () => {
11
+ const app = await NestFactory.create(AppModule, {
12
+ cors: true,
13
+ });
14
+
15
+ app.use(session({
16
+ secret: 'thisIsNotASecretAnyMore',
17
+ resave: false,
18
+ saveUninitialized: false,
19
+ }));
20
+
21
+ const builder = new DocumentBuilder()
22
+ .setTitle(AppConfig.server.name)
23
+ .setDescription(AppConfig.server.description)
24
+ .setVersion(AppConfig.server.version)
25
+ .addBearerAuth()
26
+ .build();
27
+
28
+ //Creating Swagger Doc for API
29
+ const document = SwaggerModule.createDocument(app, builder);
30
+ SwaggerModule.setup('/', app, document);
31
+
32
+ return app
33
+ .useGlobalGuards(app.get(AuthGuard), app.get(OrganizationGuard))
34
+ .useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true }))
35
+ .listen(AppConfig.server.port)
36
+ .then(async () => Logger.verbose(`Running on: ${await app.getUrl()}`, NestApplication.name));
37
+ })();
@@ -0,0 +1,15 @@
1
+ import { Inject, Injectable, NestMiddleware } from '@nestjs/common';
2
+ import { NextFunction, Request, Response } from 'express';
3
+ import { LoggerService } from '../services/logger.service';
4
+
5
+ @Injectable()
6
+ export class LoggerMiddleware implements NestMiddleware {
7
+ @Inject()
8
+ protected readonly $logger: LoggerService;
9
+
10
+ public use(req: Request, res: Response, next: NextFunction) {
11
+ this.$logger.debug(req.originalUrl, req.method);
12
+
13
+ return next();
14
+ }
15
+ }
@@ -0,0 +1,76 @@
1
+ import { Inject, Injectable, NestMiddleware, OnModuleInit } from '@nestjs/common';
2
+ import { Organization } from 'auth0';
3
+ import { NextFunction, Request } from 'express';
4
+ import { MissingIdentityException } from '../exceptions/missing-identity.exception';
5
+ import { StoreNotImplementedException } from '../exceptions/store-not-implemented.exception';
6
+ import { Auth0Service } from '../services/auth0.service';
7
+ import { OrganizationListener } from "../modules/setting/organization/organization.listener";
8
+
9
+ declare module 'http' {
10
+ interface IncomingHttpHeaders {
11
+ identity?: string;
12
+ }
13
+ }
14
+
15
+ declare module 'express-session' {
16
+ interface SessionData {
17
+ organization?: Organization;
18
+ }
19
+ }
20
+
21
+ @Injectable()
22
+ export class OrganizationMiddleware implements NestMiddleware, OnModuleInit {
23
+ public readonly organizations = [];
24
+ @Inject()
25
+ protected readonly $auth0: Auth0Service;
26
+ protected readonly $event = new OrganizationListener();
27
+ protected readonly allowedDomains = ['.store.merkaly.local', '.store.merkaly.io'];
28
+
29
+ public async onModuleInit() {
30
+ const organizations = await this.$auth0.organizations.getAll()
31
+
32
+ for await (const organization of organizations) {
33
+ this.organizations.push(this.$event.parseMetadata(organization))
34
+ }
35
+
36
+ return this.organizations
37
+ }
38
+
39
+ public async use(req: Request, res: Response, next: NextFunction) {
40
+ const identity = String(req.headers.identity || req.query.identity);
41
+
42
+ !identity && MissingIdentityException.throw();
43
+
44
+ let org: Organization | undefined
45
+
46
+ if (this.allowedDomains.some(dns => identity.endsWith(dns))) {
47
+ const [name] = identity.split('.');
48
+
49
+ org = this.organizations.find(org => org.name === name)
50
+ }
51
+
52
+ if (!org) {
53
+ org = this.organizations.find((org) => {
54
+ if (org.id === identity) {
55
+ return org
56
+ }
57
+
58
+ if (org.name === identity) {
59
+ return org
60
+ }
61
+
62
+ if (org.metadata?.domains?.includes(identity)) {
63
+ return org
64
+ }
65
+ })
66
+ }
67
+
68
+ if (org) {
69
+ req.session.organization = org
70
+
71
+ return next()
72
+ }
73
+
74
+ return StoreNotImplementedException.throw(identity)
75
+ }
76
+ }
@@ -0,0 +1,29 @@
1
+ import { UpdateQuery } from "mongoose";
2
+ import { connect } from '../abstract/abstract.migration';
3
+ import { ProductEntity } from "../modules/inventory/products/product.entity";
4
+
5
+ /**
6
+ * Make any changes you need to make to the database here
7
+ */
8
+ export const up = () => connect(async (connection) => {
9
+ const productRepository = await connection.collection('inventory_products');
10
+
11
+ const updateSentence: UpdateQuery<ProductEntity>[] = [
12
+ { $set: { price: { sale: '$price', purchase: '$price' } } },
13
+ ];
14
+
15
+ return productRepository.updateMany({}, updateSentence);
16
+ });
17
+
18
+ /**
19
+ * Make any changes that UNDO the up function side effects here (if possible)
20
+ */
21
+ export const down = () => connect(async (connection) => {
22
+ const productRepository = await connection.collection('inventory_products');
23
+
24
+ const updateSentence: UpdateQuery<ProductEntity>[] = [
25
+ { $set: { price: '$price.sale' } },
26
+ ];
27
+
28
+ return productRepository.updateMany({}, updateSentence);
29
+ });
@@ -0,0 +1,37 @@
1
+ import { connect } from '../abstract/abstract.migration';
2
+ import { UpdateQuery } from "mongoose";
3
+ import { ProductEntity } from "../modules/inventory/products/product.entity";
4
+
5
+ /**
6
+ * Make any changes you need to make to the database here
7
+ */
8
+ export const up = () => connect(async (connection) => {
9
+ const productRepository = await connection.collection('inventory_products');
10
+
11
+ const updateSentence: UpdateQuery<ProductEntity>[] = [{
12
+ $set: {
13
+ seo: { slug: null, title: '$name', description: '$description' },
14
+ code: { sku: undefined, gtin: undefined, mpn: undefined },
15
+ dimension: { weight: undefined, height: undefined, width: undefined, depth: undefined },
16
+ },
17
+ }];
18
+
19
+ return productRepository.updateMany({}, updateSentence);
20
+ });
21
+
22
+ /**
23
+ * Make any changes that UNDO the up function side effects here (if possible)
24
+ */
25
+ export const down = () => connect(async (connection) => {
26
+ const productRepository = await connection.collection('inventory_products');
27
+
28
+ const updateSentence: UpdateQuery<ProductEntity>[] = [{
29
+ $unset: {
30
+ seo: undefined,
31
+ code: undefined,
32
+ dimension: undefined,
33
+ },
34
+ }];
35
+
36
+ return productRepository.updateMany({}, updateSentence);
37
+ });