@unchainedshop/core 4.6.1 → 4.6.2

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 (91) hide show
  1. package/lib/directors/FileDirector.d.ts +10 -0
  2. package/lib/directors/FileDirector.js +25 -0
  3. package/lib/errors/common.d.ts +568 -0
  4. package/lib/errors/common.js +789 -0
  5. package/lib/errors/index.d.ts +1 -0
  6. package/lib/errors/index.js +1 -0
  7. package/lib/plugins/PluginRegistry.d.ts +42 -0
  8. package/lib/plugins/PluginRegistry.js +113 -0
  9. package/lib/services/addCartDiscount.d.ts +10 -0
  10. package/lib/services/addCartDiscount.js +27 -0
  11. package/lib/services/addCartItem.d.ts +15 -0
  12. package/lib/services/addCartItem.js +41 -0
  13. package/lib/services/addCartQuotation.d.ts +16 -0
  14. package/lib/services/addCartQuotation.js +52 -0
  15. package/lib/services/addEmail.d.ts +7 -0
  16. package/lib/services/addEmail.js +17 -0
  17. package/lib/services/addProductAssignment.d.ts +3 -0
  18. package/lib/services/addProductAssignment.js +63 -0
  19. package/lib/services/authenticateWithPassword.d.ts +15 -0
  20. package/lib/services/authenticateWithPassword.js +34 -0
  21. package/lib/services/changePassword.d.ts +10 -0
  22. package/lib/services/changePassword.js +19 -0
  23. package/lib/services/countOrdersWithFilters.d.ts +3 -0
  24. package/lib/services/countOrdersWithFilters.js +25 -0
  25. package/lib/services/createAssortment.d.ts +7 -0
  26. package/lib/services/createAssortment.js +10 -0
  27. package/lib/services/createBookmark.d.ts +8 -0
  28. package/lib/services/createBookmark.js +21 -0
  29. package/lib/services/createDeliveryProvider.d.ts +6 -0
  30. package/lib/services/createDeliveryProvider.js +19 -0
  31. package/lib/services/createEnrollment.d.ts +17 -0
  32. package/lib/services/createEnrollment.js +33 -0
  33. package/lib/services/createProduct.d.ts +7 -0
  34. package/lib/services/createProduct.js +8 -0
  35. package/lib/services/createProductBundleItem.d.ts +5 -0
  36. package/lib/services/createProductBundleItem.js +25 -0
  37. package/lib/services/createProductReview.d.ts +8 -0
  38. package/lib/services/createProductReview.js +12 -0
  39. package/lib/services/deliverOrder.d.ts +5 -0
  40. package/lib/services/deliverOrder.js +26 -0
  41. package/lib/services/findActiveWorkTypes.d.ts +2 -0
  42. package/lib/services/findActiveWorkTypes.js +6 -0
  43. package/lib/services/findDeliveryInterfaces.d.ts +7 -0
  44. package/lib/services/findDeliveryInterfaces.js +13 -0
  45. package/lib/services/findOrdersWithFilters.d.ts +9 -0
  46. package/lib/services/findOrdersWithFilters.js +25 -0
  47. package/lib/services/findPaymentInterfaces.d.ts +7 -0
  48. package/lib/services/findPaymentInterfaces.js +13 -0
  49. package/lib/services/findWarehousingInterfaces.d.ts +7 -0
  50. package/lib/services/findWarehousingInterfaces.js +13 -0
  51. package/lib/services/getDeliveryDiscounts.d.ts +8 -0
  52. package/lib/services/getDeliveryDiscounts.js +14 -0
  53. package/lib/services/getPaymentDiscounts.d.ts +8 -0
  54. package/lib/services/getPaymentDiscounts.js +14 -0
  55. package/lib/services/getShopInfo.d.ts +25 -0
  56. package/lib/services/getShopInfo.js +47 -0
  57. package/lib/services/impersonateUser.d.ts +8 -0
  58. package/lib/services/impersonateUser.js +20 -0
  59. package/lib/services/loginAsGuest.d.ts +10 -0
  60. package/lib/services/loginAsGuest.js +19 -0
  61. package/lib/services/obfuscateWorkerData.d.ts +4 -0
  62. package/lib/services/obfuscateWorkerData.js +4 -0
  63. package/lib/services/orderPricingAccessors.d.ts +18 -0
  64. package/lib/services/orderPricingAccessors.js +29 -0
  65. package/lib/services/payOrder.d.ts +5 -0
  66. package/lib/services/payOrder.js +25 -0
  67. package/lib/services/registerUser.d.ts +14 -0
  68. package/lib/services/registerUser.js +44 -0
  69. package/lib/services/removeBookmark.d.ts +6 -0
  70. package/lib/services/removeBookmark.js +10 -0
  71. package/lib/services/removeCartItem.d.ts +6 -0
  72. package/lib/services/removeCartItem.js +19 -0
  73. package/lib/services/resetPasswordWithMigration.d.ts +14 -0
  74. package/lib/services/resetPasswordWithMigration.js +31 -0
  75. package/lib/services/resolveWorkType.d.ts +1 -0
  76. package/lib/services/resolveWorkType.js +7 -0
  77. package/lib/services/searchProductsWithAssortment.d.ts +19 -0
  78. package/lib/services/searchProductsWithAssortment.js +17 -0
  79. package/lib/services/toggleBookmark.d.ts +8 -0
  80. package/lib/services/toggleBookmark.js +33 -0
  81. package/lib/services/updateCart.d.ts +15 -0
  82. package/lib/services/updateCart.js +27 -0
  83. package/lib/services/updateCartItem.d.ts +11 -0
  84. package/lib/services/updateCartItem.js +37 -0
  85. package/lib/services/updateEnrollment.d.ts +13 -0
  86. package/lib/services/updateEnrollment.js +36 -0
  87. package/lib/services/verifyEmailWithMigration.d.ts +15 -0
  88. package/lib/services/verifyEmailWithMigration.js +23 -0
  89. package/lib/utils/getFileAdapter.d.ts +1 -0
  90. package/lib/utils/getFileAdapter.js +7 -0
  91. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ export * from './common.ts';
@@ -0,0 +1 @@
1
+ export * from "./common.js";
@@ -0,0 +1,42 @@
1
+ import type { UnchainedCore } from '../core-index.ts';
2
+ import type { IBaseAdapter } from '@unchainedshop/utils';
3
+ import type { mongodb } from '@unchainedshop/mongodb';
4
+ export interface PluginHttpRoute {
5
+ path: string;
6
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'ALL';
7
+ handler: (request: Request, context: UnchainedCore & {
8
+ params: Record<string, string>;
9
+ userId?: string;
10
+ impersonatorId?: string;
11
+ }) => Response | Promise<Response>;
12
+ }
13
+ export type PluginModuleFactory = (options: {
14
+ db: mongodb.Db;
15
+ }) => Record<string, any>;
16
+ export interface IPlugin {
17
+ key: string;
18
+ label: string;
19
+ version: string;
20
+ adapters?: IBaseAdapter[];
21
+ module?: PluginModuleFactory;
22
+ routes?: PluginHttpRoute[];
23
+ onRegister?: (unchainedAPI: UnchainedCore) => void | boolean | Promise<void | boolean>;
24
+ onShutdown?: (unchainedAPI: UnchainedCore) => void | Promise<void>;
25
+ }
26
+ declare class PluginRegistry {
27
+ private plugins;
28
+ private moduleFactories;
29
+ private skippedPlugins;
30
+ register(plugin: IPlugin): void;
31
+ initialize(unchainedAPI: UnchainedCore): Promise<void>;
32
+ getModuleFactories(): PluginModuleFactory[];
33
+ getRoutes(): PluginHttpRoute[];
34
+ shutdown(unchainedAPI: UnchainedCore): Promise<void>;
35
+ getPlugin(key: string): IPlugin | undefined;
36
+ getAllPlugins(): IPlugin[];
37
+ getAdapters(adapterType: symbol): IBaseAdapter[];
38
+ hasPlugin(key: string): boolean;
39
+ clear(): void;
40
+ }
41
+ export declare const pluginRegistry: PluginRegistry;
42
+ export {};
@@ -0,0 +1,113 @@
1
+ import { createLogger } from '@unchainedshop/logger';
2
+ const logger = createLogger('unchained:core');
3
+ class PluginRegistry {
4
+ plugins = new Map();
5
+ moduleFactories = [];
6
+ skippedPlugins = new Set();
7
+ register(plugin) {
8
+ if (this.plugins.has(plugin.key)) {
9
+ logger.warn(`Plugin ${plugin.key} already registered, skipping`, {
10
+ label: plugin.label,
11
+ });
12
+ return;
13
+ }
14
+ logger.info(`Registering plugin: ${plugin.label} (${plugin.key})`, {
15
+ version: plugin.version,
16
+ });
17
+ this.plugins.set(plugin.key, plugin);
18
+ if (plugin.module) {
19
+ this.moduleFactories.push(plugin.module);
20
+ }
21
+ }
22
+ async initialize(unchainedAPI) {
23
+ logger.info(`Initializing ${this.plugins.size} plugins`);
24
+ const skippedPlugins = new Set();
25
+ for (const plugin of this.plugins.values()) {
26
+ if (plugin.onRegister) {
27
+ try {
28
+ const result = await plugin.onRegister(unchainedAPI);
29
+ if (result === false) {
30
+ skippedPlugins.add(plugin.key);
31
+ logger.warn(`Plugin ${plugin.key} skipped adapter registration`, {
32
+ label: plugin.label,
33
+ });
34
+ }
35
+ else {
36
+ logger.debug(`Plugin ${plugin.key} initialized`, {
37
+ label: plugin.label,
38
+ });
39
+ }
40
+ }
41
+ catch (error) {
42
+ skippedPlugins.add(plugin.key);
43
+ const reason = error instanceof Error ? error.message : String(error);
44
+ logger.warn(`Plugin ${plugin.key} skipped adapter registration - ${reason}`, {
45
+ label: plugin.label,
46
+ });
47
+ }
48
+ }
49
+ }
50
+ this.skippedPlugins = skippedPlugins;
51
+ }
52
+ getModuleFactories() {
53
+ return this.moduleFactories;
54
+ }
55
+ getRoutes() {
56
+ const routes = [];
57
+ for (const plugin of this.plugins.values()) {
58
+ if (this.skippedPlugins.has(plugin.key)) {
59
+ continue;
60
+ }
61
+ if (plugin.routes) {
62
+ routes.push(...plugin.routes);
63
+ }
64
+ }
65
+ return routes;
66
+ }
67
+ async shutdown(unchainedAPI) {
68
+ logger.info('Shutting down plugins');
69
+ for (const plugin of this.plugins.values()) {
70
+ if (plugin.onShutdown) {
71
+ try {
72
+ await plugin.onShutdown(unchainedAPI);
73
+ logger.debug(`Plugin ${plugin.key} shutdown complete`, {
74
+ label: plugin.label,
75
+ });
76
+ }
77
+ catch (error) {
78
+ logger.error(`Error shutting down plugin ${plugin.key}`, {
79
+ error: error instanceof Error ? error.message : String(error),
80
+ });
81
+ }
82
+ }
83
+ }
84
+ }
85
+ getPlugin(key) {
86
+ return this.plugins.get(key);
87
+ }
88
+ getAllPlugins() {
89
+ return Array.from(this.plugins.values());
90
+ }
91
+ getAdapters(adapterType) {
92
+ const result = [];
93
+ for (const plugin of this.plugins.values()) {
94
+ if (!plugin.adapters)
95
+ continue;
96
+ for (const adapter of plugin.adapters) {
97
+ if (adapter.adapterType === adapterType) {
98
+ result.push(adapter);
99
+ }
100
+ }
101
+ }
102
+ return result;
103
+ }
104
+ hasPlugin(key) {
105
+ return this.plugins.has(key);
106
+ }
107
+ clear() {
108
+ this.plugins.clear();
109
+ this.moduleFactories = [];
110
+ this.skippedPlugins.clear();
111
+ }
112
+ }
113
+ export const pluginRegistry = new PluginRegistry();
@@ -0,0 +1,10 @@
1
+ import type { OrderDiscount } from '@unchainedshop/core-orders';
2
+ import type { Modules } from '../modules.ts';
3
+ import type { User } from '@unchainedshop/core-users';
4
+ export interface AddCartDiscountParams {
5
+ orderId?: string;
6
+ code: string;
7
+ user: User;
8
+ countryCode: string;
9
+ }
10
+ export declare function addCartDiscountService(this: Modules, params: AddCartDiscountParams): Promise<OrderDiscount>;
@@ -0,0 +1,27 @@
1
+ import { createManualOrderDiscountService } from "./createManualOrderDiscount.js";
2
+ import { updateCalculationService } from "./updateCalculation.js";
3
+ import { findOrInitCartService } from "./findOrInitCart.js";
4
+ import { OrderNotFoundError, OrderWrongStatusError, OrderDiscountCodeAlreadyPresentError, OrderDiscountCodeNotValidError, } from "../errors/index.js";
5
+ export async function addCartDiscountService(params) {
6
+ const { orderId, code, user, countryCode } = params;
7
+ const order = await findOrInitCartService.bind(this)({
8
+ orderId,
9
+ user,
10
+ countryCode,
11
+ });
12
+ if (!order) {
13
+ throw new OrderNotFoundError({ orderId: orderId || null });
14
+ }
15
+ if (!this.orders.isCart(order)) {
16
+ throw new OrderWrongStatusError({ status: order.status });
17
+ }
18
+ if (await this.orders.discounts.isDiscountCodeUsed({ code, orderId: order._id })) {
19
+ throw new OrderDiscountCodeAlreadyPresentError({ orderId: order._id, code });
20
+ }
21
+ const discount = await createManualOrderDiscountService.bind(this)({ order, code });
22
+ if (!discount) {
23
+ throw new OrderDiscountCodeNotValidError({ code });
24
+ }
25
+ await updateCalculationService.bind(this)(order._id);
26
+ return discount;
27
+ }
@@ -0,0 +1,15 @@
1
+ import { type OrderPosition } from '@unchainedshop/core-orders';
2
+ import type { User } from '@unchainedshop/core-users';
3
+ import type { Modules } from '../modules.ts';
4
+ export interface AddCartItemParams {
5
+ orderId?: string;
6
+ productId: string;
7
+ quantity: number;
8
+ configuration?: {
9
+ key: string;
10
+ value: string;
11
+ }[];
12
+ user: User;
13
+ countryCode: string;
14
+ }
15
+ export declare function addCartItemService(this: Modules, params: AddCartItemParams, context: any): Promise<OrderPosition>;
@@ -0,0 +1,41 @@
1
+ import { ordersSettings } from '@unchainedshop/core-orders';
2
+ import { findOrInitCartService } from "./findOrInitCart.js";
3
+ import { updateCalculationService } from "./updateCalculation.js";
4
+ import { ProductNotFoundError, OrderNotFoundError, OrderWrongStatusError, OrderQuantityTooLowError, } from "../errors/index.js";
5
+ export async function addCartItemService(params, context) {
6
+ const { orderId, productId: originalProductId, quantity, configuration, user, countryCode } = params;
7
+ if (quantity < 1) {
8
+ throw new OrderQuantityTooLowError({ quantity });
9
+ }
10
+ const originalProduct = await this.products.findProduct({ productId: originalProductId });
11
+ if (!originalProduct) {
12
+ throw new ProductNotFoundError({ productId: originalProductId });
13
+ }
14
+ const order = await findOrInitCartService.bind(this)({
15
+ orderId,
16
+ user,
17
+ countryCode,
18
+ });
19
+ if (!order) {
20
+ throw new OrderNotFoundError({ orderId });
21
+ }
22
+ if (!this.orders.isCart(order)) {
23
+ throw new OrderWrongStatusError({ status: order.status });
24
+ }
25
+ const product = await this.products.resolveOrderableProduct(originalProduct, { configuration });
26
+ await ordersSettings.validateOrderPosition({
27
+ order,
28
+ product,
29
+ configuration,
30
+ quantityDiff: quantity,
31
+ }, context);
32
+ const orderPosition = await this.orders.positions.addProductItem({
33
+ quantity,
34
+ configuration,
35
+ productId: product._id,
36
+ originalProductId,
37
+ orderId: order._id,
38
+ });
39
+ await updateCalculationService.bind(this)(order._id);
40
+ return (await this.orders.positions.findOrderPosition({ itemId: orderPosition._id }));
41
+ }
@@ -0,0 +1,16 @@
1
+ import type { OrderPosition } from '@unchainedshop/core-orders';
2
+ import type { User } from '@unchainedshop/core-users';
3
+ import type { Modules } from '../modules.ts';
4
+ export interface AddCartQuotationParams {
5
+ orderId?: string;
6
+ quotationId: string;
7
+ quantity: number;
8
+ configuration: {
9
+ key: string;
10
+ value: string;
11
+ }[];
12
+ user: User;
13
+ countryCode: string;
14
+ context: unknown;
15
+ }
16
+ export declare function addCartQuotationService(this: Modules, params: AddCartQuotationParams): Promise<OrderPosition>;
@@ -0,0 +1,52 @@
1
+ import { QuotationStatus } from '@unchainedshop/core-quotations';
2
+ import { QuotationDirector } from "../directors/QuotationDirector.js";
3
+ import { updateCalculationService } from "./updateCalculation.js";
4
+ import { findOrInitCartService } from "./findOrInitCart.js";
5
+ import { OrderNotFoundError, OrderWrongStatusError, OrderQuantityTooLowError, ProductNotFoundError, QuotationNotFoundError, QuotationWrongStatusError, QuotationItemConfigurationError, } from "../errors/index.js";
6
+ export async function addCartQuotationService(params) {
7
+ const { orderId, quotationId, quantity, configuration, user, countryCode, context } = params;
8
+ if (quantity < 1) {
9
+ throw new OrderQuantityTooLowError({ quantity });
10
+ }
11
+ const quotation = await this.quotations.findQuotation({ quotationId });
12
+ if (!quotation) {
13
+ throw new QuotationNotFoundError({ quotationId });
14
+ }
15
+ if (quotation.status !== QuotationStatus.PROPOSED) {
16
+ throw new QuotationWrongStatusError({ status: quotation.status });
17
+ }
18
+ const order = await findOrInitCartService.bind(this)({
19
+ orderId,
20
+ user,
21
+ countryCode,
22
+ });
23
+ if (!order) {
24
+ throw new OrderNotFoundError({ orderId: orderId || null });
25
+ }
26
+ if (!this.orders.isCart(order)) {
27
+ throw new OrderWrongStatusError({ status: order.status });
28
+ }
29
+ if (!(await this.products.productExists({ productId: quotation.productId }))) {
30
+ throw new ProductNotFoundError({ productId: quotation.productId });
31
+ }
32
+ const director = await QuotationDirector.actions({ quotation }, context);
33
+ const quotationConfiguration = await director.transformItemConfiguration({
34
+ quantity,
35
+ configuration,
36
+ });
37
+ if (!quotationConfiguration) {
38
+ throw new QuotationItemConfigurationError({ configuration });
39
+ }
40
+ const updatedOrderPosition = await this.orders.positions.addProductItem({
41
+ quantity: quotationConfiguration.quantity || 1,
42
+ configuration: quotationConfiguration.configuration,
43
+ quotationId,
44
+ productId: quotation.productId,
45
+ originalProductId: quotation.productId,
46
+ orderId: order._id,
47
+ });
48
+ await updateCalculationService.bind(this)(order._id);
49
+ return (await this.orders.positions.findOrderPosition({
50
+ itemId: updatedOrderPosition._id,
51
+ }));
52
+ }
@@ -0,0 +1,7 @@
1
+ import type { User } from '@unchainedshop/core-users';
2
+ import type { Modules } from '../modules.ts';
3
+ export interface AddEmailParams {
4
+ userId: string;
5
+ email: string;
6
+ }
7
+ export declare function addEmailService(this: Modules, params: AddEmailParams): Promise<User>;
@@ -0,0 +1,17 @@
1
+ import { UserNotFoundError, EmailAlreadyExistsError } from "../errors/index.js";
2
+ export async function addEmailService(params) {
3
+ const { userId, email } = params;
4
+ if (!(await this.users.userExists({ userId }))) {
5
+ throw new UserNotFoundError({ userId });
6
+ }
7
+ try {
8
+ await this.users.addEmail(userId, email);
9
+ }
10
+ catch (e) {
11
+ if (e.cause === 'EMAIL_INVALID') {
12
+ throw new EmailAlreadyExistsError({ email });
13
+ }
14
+ throw e;
15
+ }
16
+ return (await this.users.findUserById(userId));
17
+ }
@@ -0,0 +1,3 @@
1
+ import { type Product, type ProductConfiguration } from '@unchainedshop/core-products';
2
+ import type { Modules } from '../modules.ts';
3
+ export declare function addProductAssignmentService(this: Modules, proxyId: string, productId: string, vectors: ProductConfiguration[]): Promise<Product | null>;
@@ -0,0 +1,63 @@
1
+ import { ProductType, } from '@unchainedshop/core-products';
2
+ import { ProductNotFoundError, ProductWrongTypeError, ProductVariationInfinityLoopError, ProductVariationVectorInvalidError, ProductVariationVectorAlreadySetError, } from "../errors/index.js";
3
+ const extractVariationMatrix = (variations = []) => {
4
+ const cartesianProduct = (arrays) => {
5
+ return arrays.reduce((acc, array) => acc.flatMap((item) => array.map((value) => [...item, value])), [
6
+ [],
7
+ ]);
8
+ };
9
+ const keys = variations.map((item) => item.key);
10
+ const options = variations.map((item) => item.options);
11
+ const combinations = cartesianProduct(options);
12
+ return combinations.map((combination) => combination.reduce((acc, value, index) => {
13
+ acc[keys[index]] = value;
14
+ return acc;
15
+ }, {}));
16
+ };
17
+ const combinationExists = (matrix, combination) => {
18
+ return matrix.some((variation) => {
19
+ return (Object.keys(variation).length === Object.keys(combination).length &&
20
+ Object.entries(combination).every(([key, value]) => variation[key] === value));
21
+ });
22
+ };
23
+ export async function addProductAssignmentService(proxyId, productId, vectors) {
24
+ if (!(await this.products.productExists({ productId }))) {
25
+ throw new ProductNotFoundError({ productId });
26
+ }
27
+ const proxyProduct = await this.products.findProduct({ productId: proxyId });
28
+ if (!proxyProduct) {
29
+ throw new ProductNotFoundError({ productId: proxyId });
30
+ }
31
+ if (productId === proxyId) {
32
+ throw new ProductVariationInfinityLoopError({ productId });
33
+ }
34
+ if (proxyProduct.type !== ProductType.CONFIGURABLE_PRODUCT) {
35
+ throw new ProductWrongTypeError({
36
+ proxyId,
37
+ received: proxyProduct.type,
38
+ required: ProductType.CONFIGURABLE_PRODUCT,
39
+ });
40
+ }
41
+ const variations = await this.products.variations.findProductVariations({
42
+ productId: proxyId,
43
+ });
44
+ const variationMatrix = extractVariationMatrix(variations);
45
+ const normalizedVectors = vectors?.reduce((prev, { key, value }) => {
46
+ return {
47
+ ...prev,
48
+ [key]: value,
49
+ };
50
+ }, {});
51
+ if (!combinationExists(variationMatrix, normalizedVectors)) {
52
+ throw new ProductVariationVectorInvalidError({ proxyId, vectors });
53
+ }
54
+ const added = await this.products.assignments.addProxyAssignment({
55
+ productId,
56
+ proxyId,
57
+ vectors,
58
+ });
59
+ if (!added) {
60
+ throw new ProductVariationVectorAlreadySetError({ proxyId, vectors });
61
+ }
62
+ return this.products.findProduct({ productId: proxyId });
63
+ }
@@ -0,0 +1,15 @@
1
+ import type { User } from '@unchainedshop/core-users';
2
+ import type { Modules } from '../modules.ts';
3
+ export interface AuthenticateWithPasswordParams {
4
+ username?: string;
5
+ email?: string;
6
+ password: string;
7
+ }
8
+ export interface HttpContext {
9
+ remoteAddress?: string;
10
+ remotePort?: number;
11
+ userAgent?: string;
12
+ locale?: string;
13
+ countryCode: string;
14
+ }
15
+ export declare function authenticateWithPasswordService(this: Modules, params: AuthenticateWithPasswordParams, httpContext: HttpContext, currentUserId?: string): Promise<User>;
@@ -0,0 +1,34 @@
1
+ import { migrateUserDataService } from "./migrateUserData.js";
2
+ import { nextUserCartService } from "./nextUserCart.js";
3
+ import { UsernameOrEmailRequiredError, InvalidCredentialsError } from "../errors/index.js";
4
+ export async function authenticateWithPasswordService(params, httpContext, currentUserId) {
5
+ const { username, email, password } = params;
6
+ if (!username && !email) {
7
+ throw new UsernameOrEmailRequiredError();
8
+ }
9
+ let user = username
10
+ ? await this.users.findUserByUsername(username)
11
+ : await this.users.findUserByEmail(email);
12
+ if (!user) {
13
+ throw new InvalidCredentialsError({ username, email });
14
+ }
15
+ const verified = user.services?.password && (await this.users.verifyPassword(user.services.password, password));
16
+ if (!verified) {
17
+ throw new InvalidCredentialsError({ username, email });
18
+ }
19
+ if (user.guest) {
20
+ await this.users.updateGuest(user, false);
21
+ }
22
+ user = (await this.users.updateHeartbeat(user._id, {
23
+ remoteAddress: httpContext.remoteAddress,
24
+ remotePort: httpContext.remotePort,
25
+ userAgent: httpContext.userAgent,
26
+ locale: httpContext.locale,
27
+ countryCode: httpContext.countryCode,
28
+ }));
29
+ if (currentUserId) {
30
+ await migrateUserDataService.bind(this)(currentUserId, user._id);
31
+ }
32
+ await nextUserCartService.bind(this)({ user, countryCode: httpContext.countryCode });
33
+ return user;
34
+ }
@@ -0,0 +1,10 @@
1
+ import type { Modules } from '../modules.ts';
2
+ export interface ChangePasswordParams {
3
+ userId: string;
4
+ oldPassword: string;
5
+ newPassword: string;
6
+ }
7
+ export interface ChangePasswordResult {
8
+ success: boolean;
9
+ }
10
+ export declare function changePasswordService(this: Modules, params: ChangePasswordParams): Promise<ChangePasswordResult>;
@@ -0,0 +1,19 @@
1
+ import { InvalidCredentialsError, PasswordInvalidError } from "../errors/index.js";
2
+ export async function changePasswordService(params) {
3
+ const { userId, oldPassword, newPassword } = params;
4
+ const user = await this.users.findUserById(userId);
5
+ const isValidCurrentPassword = user?.services?.password && (await this.users.verifyPassword(user.services.password, oldPassword));
6
+ if (!isValidCurrentPassword) {
7
+ throw new InvalidCredentialsError();
8
+ }
9
+ try {
10
+ await this.users.setPassword(user._id, newPassword);
11
+ return { success: true };
12
+ }
13
+ catch (e) {
14
+ if (e.cause === 'PASSWORD_INVALID') {
15
+ throw new PasswordInvalidError({ userId });
16
+ }
17
+ throw e;
18
+ }
19
+ }
@@ -0,0 +1,3 @@
1
+ import type { OrderQuery } from '@unchainedshop/core-orders';
2
+ import type { Modules } from '../modules.ts';
3
+ export declare function countOrdersWithFiltersService(this: Modules, params: OrderQuery): Promise<number>;
@@ -0,0 +1,25 @@
1
+ export async function countOrdersWithFiltersService(params) {
2
+ const { paymentProviderIds, deliveryProviderIds, ...restParams } = params;
3
+ if (!paymentProviderIds?.length && !deliveryProviderIds?.length) {
4
+ return this.orders.count(restParams);
5
+ }
6
+ const [orderPayments, orderDeliveries] = await Promise.all([
7
+ paymentProviderIds?.length
8
+ ? this.orders.payments.findOrderPaymentsByProviderIds({ paymentProviderIds })
9
+ : [],
10
+ deliveryProviderIds?.length
11
+ ? this.orders.deliveries.findDeliveryByProvidersId({ deliveryProviderIds })
12
+ : [],
13
+ ]);
14
+ if ((paymentProviderIds?.length && !orderPayments.length) ||
15
+ (deliveryProviderIds?.length && !orderDeliveries.length)) {
16
+ return 0;
17
+ }
18
+ const paymentIds = orderPayments.map((p) => p._id);
19
+ const deliveryIds = orderDeliveries.map((d) => d._id);
20
+ return this.orders.count({
21
+ ...restParams,
22
+ paymentIds,
23
+ deliveryIds,
24
+ });
25
+ }
@@ -0,0 +1,7 @@
1
+ import type { Assortment, AssortmentText } from '@unchainedshop/core-assortments';
2
+ import type { Modules } from '../modules.ts';
3
+ export interface CreateAssortmentParams {
4
+ assortment: Partial<Assortment>;
5
+ texts?: AssortmentText[];
6
+ }
7
+ export declare function createAssortmentService(this: Modules, params: CreateAssortmentParams): Promise<Assortment>;
@@ -0,0 +1,10 @@
1
+ export async function createAssortmentService(params) {
2
+ const { assortment: assortmentData, texts } = params;
3
+ const assortment = await this.assortments.create({
4
+ ...assortmentData,
5
+ });
6
+ if (texts) {
7
+ await this.assortments.texts.updateTexts(assortment._id, texts);
8
+ }
9
+ return assortment;
10
+ }
@@ -0,0 +1,8 @@
1
+ import type { Bookmark } from '@unchainedshop/core-bookmarks';
2
+ import type { Modules } from '../modules.ts';
3
+ export interface CreateBookmarkParams {
4
+ productId: string;
5
+ userId: string;
6
+ meta?: any;
7
+ }
8
+ export declare function createBookmarkService(this: Modules, params: CreateBookmarkParams): Promise<Bookmark>;
@@ -0,0 +1,21 @@
1
+ import { ProductNotFoundError, BookmarkAlreadyExistsError } from "../errors/index.js";
2
+ export async function createBookmarkService(params) {
3
+ const { productId, userId, meta } = params;
4
+ if (!(await this.products.productExists({ productId }))) {
5
+ throw new ProductNotFoundError({ productId });
6
+ }
7
+ const [existingBookmark] = await this.bookmarks.findBookmarks({
8
+ productId,
9
+ userId,
10
+ meta,
11
+ });
12
+ if (existingBookmark) {
13
+ throw new BookmarkAlreadyExistsError({ bookmarkId: existingBookmark._id });
14
+ }
15
+ const bookmarkId = await this.bookmarks.create({
16
+ userId,
17
+ productId,
18
+ meta,
19
+ });
20
+ return (await this.bookmarks.findBookmarkById(bookmarkId));
21
+ }
@@ -0,0 +1,6 @@
1
+ import type { DeliveryProvider } from '@unchainedshop/core-delivery';
2
+ import type { Modules } from '../modules.ts';
3
+ export interface CreateDeliveryProviderParams {
4
+ deliveryProvider: Pick<DeliveryProvider, 'type' | 'adapterKey'>;
5
+ }
6
+ export declare function createDeliveryProviderService(this: Modules, params: CreateDeliveryProviderParams): Promise<DeliveryProvider | null>;
@@ -0,0 +1,19 @@
1
+ import { DeliveryDirector } from "../directors/DeliveryDirector.js";
2
+ import { ProviderConfigurationInvalidError } from "../errors/index.js";
3
+ export async function createDeliveryProviderService(params) {
4
+ const { deliveryProvider } = params;
5
+ const Adapter = DeliveryDirector.getAdapter(deliveryProvider.adapterKey);
6
+ if (!Adapter)
7
+ return null;
8
+ const provider = await this.delivery.create({
9
+ configuration: Adapter.initialConfiguration,
10
+ ...deliveryProvider,
11
+ });
12
+ if (!provider) {
13
+ throw new ProviderConfigurationInvalidError({
14
+ adapterKey: deliveryProvider.adapterKey,
15
+ type: deliveryProvider.type,
16
+ });
17
+ }
18
+ return provider;
19
+ }
@@ -0,0 +1,17 @@
1
+ import type { Enrollment, EnrollmentPlan } from '@unchainedshop/core-enrollments';
2
+ import type { Address, Contact } from '@unchainedshop/core-users';
3
+ import type { Modules } from '../modules.ts';
4
+ export interface CreateEnrollmentParams {
5
+ productId: string;
6
+ quantity?: number;
7
+ configuration?: EnrollmentPlan['configuration'];
8
+ billingAddress?: Address;
9
+ contact?: Contact;
10
+ payment?: Enrollment['payment'];
11
+ delivery?: Enrollment['delivery'];
12
+ meta?: any;
13
+ countryCode: string;
14
+ currencyCode: string;
15
+ userId: string;
16
+ }
17
+ export declare function createEnrollmentService(this: Modules, params: CreateEnrollmentParams): Promise<Enrollment>;