@unchainedshop/utils 3.0.0-alpha2 → 3.0.0-alpha4

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 (76) hide show
  1. package/lib/calculation.d.ts +1 -1
  2. package/lib/calculation.d.ts.map +1 -1
  3. package/lib/director/BaseAdapter.d.ts +10 -1
  4. package/lib/director/BaseAdapter.d.ts.map +1 -1
  5. package/lib/director/BaseAdapter.js.map +1 -1
  6. package/lib/director/BaseDirector.d.ts +9 -1
  7. package/lib/director/BaseDirector.d.ts.map +1 -1
  8. package/lib/director/BaseDirector.js.map +1 -1
  9. package/lib/director/BaseDiscountAdapter.d.ts +36 -1
  10. package/lib/director/BaseDiscountAdapter.d.ts.map +1 -1
  11. package/lib/director/BaseDiscountAdapter.js.map +1 -1
  12. package/lib/director/BaseDiscountDirector.d.ts +11 -1
  13. package/lib/director/BaseDiscountDirector.d.ts.map +1 -1
  14. package/lib/director/BaseDiscountDirector.js.map +1 -1
  15. package/lib/director/BasePricingAdapter.d.ts +45 -2
  16. package/lib/director/BasePricingAdapter.d.ts.map +1 -1
  17. package/lib/director/BasePricingAdapter.js.map +1 -1
  18. package/lib/director/BasePricingDirector.d.ts +14 -1
  19. package/lib/director/BasePricingDirector.d.ts.map +1 -1
  20. package/lib/director/BasePricingDirector.js.map +1 -1
  21. package/lib/director/BasePricingSheet.d.ts +45 -1
  22. package/lib/director/BasePricingSheet.d.ts.map +1 -1
  23. package/lib/director/BasePricingSheet.js.map +1 -1
  24. package/lib/locale-helpers.d.ts +8 -6
  25. package/lib/locale-helpers.d.ts.map +1 -1
  26. package/lib/locale-helpers.js +8 -10
  27. package/lib/locale-helpers.js.map +1 -1
  28. package/lib/object-invert.d.ts +1 -1
  29. package/lib/object-invert.d.ts.map +1 -1
  30. package/lib/object-invert.js.map +1 -1
  31. package/lib/utils-index.d.ts +17 -8
  32. package/lib/utils-index.d.ts.map +1 -1
  33. package/lib/utils-index.js +12 -8
  34. package/lib/utils-index.js.map +1 -1
  35. package/package.json +5 -7
  36. package/src/calculation.test.ts +24 -32
  37. package/src/calculation.ts +1 -1
  38. package/src/director/BaseAdapter.ts +13 -1
  39. package/src/director/BaseDirector.ts +8 -1
  40. package/src/director/BaseDiscountAdapter.ts +32 -1
  41. package/src/director/BaseDiscountDirector.ts +15 -2
  42. package/src/director/BasePricingAdapter.ts +59 -11
  43. package/src/director/BasePricingDirector.ts +36 -9
  44. package/src/director/BasePricingSheet.ts +45 -5
  45. package/src/director/base-director.test.ts +55 -66
  46. package/src/director/base-discount-adapter.test.ts +22 -25
  47. package/src/director/base-price-sheet.test.ts +50 -56
  48. package/src/locale-helpers.ts +17 -16
  49. package/src/object-invert.ts +1 -1
  50. package/src/utils-index.test.ts +47 -57
  51. package/src/utils-index.ts +20 -8
  52. package/lib/schemas/AddressSchema.d.ts +0 -3
  53. package/lib/schemas/AddressSchema.d.ts.map +0 -1
  54. package/lib/schemas/AddressSchema.js +0 -13
  55. package/lib/schemas/AddressSchema.js.map +0 -1
  56. package/lib/schemas/ContactSchema.d.ts +0 -3
  57. package/lib/schemas/ContactSchema.d.ts.map +0 -1
  58. package/lib/schemas/ContactSchema.js +0 -6
  59. package/lib/schemas/ContactSchema.js.map +0 -1
  60. package/lib/schemas/UsersSchema.d.ts +0 -5
  61. package/lib/schemas/UsersSchema.d.ts.map +0 -1
  62. package/lib/schemas/UsersSchema.js +0 -52
  63. package/lib/schemas/UsersSchema.js.map +0 -1
  64. package/lib/schemas/commonSchemaFields.d.ts +0 -35
  65. package/lib/schemas/commonSchemaFields.d.ts.map +0 -1
  66. package/lib/schemas/commonSchemaFields.js +0 -28
  67. package/lib/schemas/commonSchemaFields.js.map +0 -1
  68. package/lib/schemas/index.d.ts +0 -43
  69. package/lib/schemas/index.d.ts.map +0 -1
  70. package/lib/schemas/index.js +0 -14
  71. package/lib/schemas/index.js.map +0 -1
  72. package/src/schemas/AddressSchema.ts +0 -16
  73. package/src/schemas/ContactSchema.ts +0 -9
  74. package/src/schemas/UsersSchema.ts +0 -67
  75. package/src/schemas/commonSchemaFields.ts +0 -29
  76. package/src/schemas/index.ts +0 -18
@@ -1,4 +1,11 @@
1
- import { applyRate, resolveRatioAndTaxDivisorForPricingSheet, roundToNext, resolveAmountAndTax, applyDiscountToMultipleShares, calculateAmountToSplit } from "./calculation";
1
+ import {
2
+ applyRate,
3
+ resolveRatioAndTaxDivisorForPricingSheet,
4
+ roundToNext,
5
+ resolveAmountAndTax,
6
+ applyDiscountToMultipleShares,
7
+ calculateAmountToSplit,
8
+ } from './calculation';
2
9
 
3
10
  describe('roundToNext', () => {
4
11
  it('rounds to the next multiple of precision correctly when the value is positive', () => {
@@ -20,10 +27,9 @@ describe('roundToNext', () => {
20
27
  it('returns the same value when the precision is 1', () => {
21
28
  expect(roundToNext(5, 1)).toBe(5);
22
29
  });
23
-
24
30
  });
25
31
 
26
- describe("resolveRatioAndTaxDivisorForPricingSheet", () => {
32
+ describe('resolveRatioAndTaxDivisorForPricingSheet', () => {
27
33
  it('total is 0 and pricing is provided', () => {
28
34
  const pricing: any = {
29
35
  taxSum: () => 10,
@@ -63,11 +69,9 @@ describe("resolveRatioAndTaxDivisorForPricingSheet", () => {
63
69
  const result = resolveRatioAndTaxDivisorForPricingSheet(pricing, 20);
64
70
  expect(result).toEqual({ ratio: 1, taxDivisor: 1 });
65
71
  });
72
+ });
66
73
 
67
- })
68
-
69
-
70
- describe("resolveAmountAndTax", () => {
74
+ describe('resolveAmountAndTax', () => {
71
75
  it('ratio is 0 and taxDivisor is 0', () => {
72
76
  const result = resolveAmountAndTax({ ratio: 0, taxDivisor: 0 }, 100);
73
77
  expect(result).toEqual([0, 0]);
@@ -83,7 +87,6 @@ describe("resolveAmountAndTax", () => {
83
87
  expect(result).toEqual([0, 0]);
84
88
  });
85
89
 
86
-
87
90
  it('ratio and taxDivisor are not 0', () => {
88
91
  const result = resolveAmountAndTax({ ratio: 0.5, taxDivisor: 2 }, 100);
89
92
  expect(result).toEqual([50, 25]);
@@ -93,9 +96,9 @@ describe("resolveAmountAndTax", () => {
93
96
  const result = resolveAmountAndTax({ ratio: Number.NaN, taxDivisor: Number.NaN }, 100);
94
97
  expect(result).toEqual([0, 0]);
95
98
  });
96
- })
99
+ });
97
100
 
98
- describe("resolveAmountAndTax", () => {
101
+ describe('resolveAmountAndTax', () => {
99
102
  it('shares are empty', () => {
100
103
  const result = applyDiscountToMultipleShares([], 100);
101
104
  expect(result).toEqual([0, 0]);
@@ -115,12 +118,12 @@ describe("resolveAmountAndTax", () => {
115
118
  const result = applyDiscountToMultipleShares(shares, 100);
116
119
  expect(result).toEqual([70, 31.666666666666664]);
117
120
  });
118
- })
121
+ });
119
122
 
120
123
  describe('applyRate', () => {
121
124
  it('applies the rate correctly when a rate is provided', () => {
122
125
  const configuration = {
123
- rate: 0.1
126
+ rate: 0.1,
124
127
  };
125
128
  const amount = 100;
126
129
  expect(applyRate(configuration, amount)).toBe(10);
@@ -128,7 +131,7 @@ describe('applyRate', () => {
128
131
 
129
132
  it('applies the fixed rate correctly when a fixed rate is provided', () => {
130
133
  const configuration = {
131
- fixedRate: 50
134
+ fixedRate: 50,
132
135
  };
133
136
  const amount = 100;
134
137
  expect(applyRate(configuration, amount)).toBe(50);
@@ -136,7 +139,7 @@ describe('applyRate', () => {
136
139
 
137
140
  it('applies the fixed rate correctly when a fixed rate is provided and the amount is less than fixed rate', () => {
138
141
  const configuration = {
139
- fixedRate: 150
142
+ fixedRate: 150,
140
143
  };
141
144
  const amount = 100;
142
145
  expect(applyRate(configuration, amount)).toBe(100);
@@ -144,48 +147,43 @@ describe('applyRate', () => {
144
147
 
145
148
  it('applies the rate correctly when rate is less than or equal to 0', () => {
146
149
  const configuration = {
147
- rate: -0.1
150
+ rate: -0.1,
148
151
  };
149
152
  const amount = 100;
150
153
  expect(applyRate(configuration, amount)).toBe(-10);
151
154
  });
152
155
  it('applies the rate correctly when only rate is provided and amount is negative', () => {
153
156
  const configuration = {
154
- rate: 0.1
157
+ rate: 0.1,
155
158
  };
156
159
  const amount = -100;
157
160
  expect(applyRate(configuration, amount)).toBe(-10);
158
161
  });
159
162
 
160
-
161
163
  it('applies the rate correctly when only rate is provided and amount is negative', () => {
162
164
  const configuration = {
163
- rate: 0.1
165
+ rate: 0.1,
164
166
  };
165
167
  const amount = -100;
166
168
  expect(applyRate(configuration, amount)).toBe(-10);
167
169
  });
168
170
 
169
-
170
171
  it('applies the rate correctly when only rate is provided and amount is negative', () => {
171
172
  const configuration = {
172
- rate: 0.1
173
+ rate: 0.1,
173
174
  };
174
175
  const amount = -100;
175
176
  expect(applyRate(configuration, amount)).toBe(-10);
176
177
  });
177
178
 
178
-
179
-
180
179
  it('applies the rate correctly when only rate is provided and amount is negative', () => {
181
180
  const configuration = {
182
- rate: 0.1
181
+ rate: 0.1,
183
182
  };
184
183
  const amount = -100;
185
184
  expect(applyRate(configuration, amount)).toBe(-10);
186
185
  });
187
186
 
188
-
189
187
  it('returns 0 when rate and fixed rate are not provided', () => {
190
188
  const configuration = {};
191
189
  const amount = 100;
@@ -194,7 +192,7 @@ describe('applyRate', () => {
194
192
 
195
193
  it('applies the rate correctly when only rate is provided and amount is negative', () => {
196
194
  const configuration = {
197
- rate: 0.1
195
+ rate: 0.1,
198
196
  };
199
197
  const amount = -100;
200
198
  expect(applyRate(configuration, amount)).toBe(-10);
@@ -205,11 +203,8 @@ describe('applyRate', () => {
205
203
  const amount = 100;
206
204
  expect(applyRate(configuration, amount)).toBe(0);
207
205
  });
208
-
209
-
210
206
  });
211
207
 
212
-
213
208
  describe('calculateAmountToSplit', () => {
214
209
  it('calculates the correct amount to split when using a rate', () => {
215
210
  const configuration = {
@@ -235,7 +230,6 @@ describe('calculateAmountToSplit', () => {
235
230
  expect(calculateAmountToSplit(configuration, amount)).toBe(0);
236
231
  });
237
232
 
238
-
239
233
  it('returns 0 when amount is negative', () => {
240
234
  const configuration = {
241
235
  rate: 0.1,
@@ -251,6 +245,4 @@ describe('calculateAmountToSplit', () => {
251
245
  const amount = 1000;
252
246
  expect(calculateAmountToSplit(configuration, amount)).toBe(0);
253
247
  });
254
-
255
-
256
- });
248
+ });
@@ -1,4 +1,4 @@
1
- import { IBasePricingSheet, PricingCalculation } from '@unchainedshop/types/pricing.js';
1
+ import { IBasePricingSheet, PricingCalculation } from './director/BasePricingSheet.js';
2
2
 
3
3
  export const roundToNext = (value: number, precision: number) =>
4
4
  Math.ceil(value / precision) * precision;
@@ -1,6 +1,18 @@
1
- import { IBaseAdapter } from '@unchainedshop/types/common.js';
2
1
  import { log, LogLevel } from '@unchainedshop/logger';
3
2
 
3
+ export interface IBaseAdapter {
4
+ key: string;
5
+ label: string;
6
+ version: string;
7
+ log: (
8
+ message: string,
9
+ options?: {
10
+ level?: LogLevel;
11
+ [x: string]: any;
12
+ },
13
+ ) => void;
14
+ }
15
+
4
16
  export const BaseAdapter: Omit<IBaseAdapter, 'key' | 'label' | 'version'> = {
5
17
  log(message: string, { level = LogLevel.Debug, ...options } = {}) {
6
18
  return log(message, { level, ...options });
@@ -1,5 +1,12 @@
1
- import { IBaseAdapter, IBaseDirector } from '@unchainedshop/types/common.js';
2
1
  import { log } from '@unchainedshop/logger';
2
+ import { IBaseAdapter } from './BaseAdapter.js';
3
+
4
+ export interface IBaseDirector<Adapter extends IBaseAdapter> {
5
+ getAdapters: (options?: { adapterFilter?: (adapter: Adapter) => boolean }) => Array<Adapter>;
6
+ getAdapter: (key: string) => Adapter;
7
+ registerAdapter: (A: Adapter) => void;
8
+ unregisterAdapter: (key: string) => boolean;
9
+ }
3
10
 
4
11
  export const BaseDirector = <AdapterType extends IBaseAdapter>(
5
12
  directorName: string,
@@ -1,6 +1,37 @@
1
1
  import { log, LogLevel } from '@unchainedshop/logger';
2
+ import { UnchainedCore } from '@unchainedshop/core';
3
+ import { IBaseAdapter } from './BaseAdapter.js';
4
+ import { IPricingSheet, PricingCalculation } from './BasePricingSheet.js';
2
5
 
3
- import { IDiscountAdapter } from '@unchainedshop/types/discount.js';
6
+ export interface DiscountContext {
7
+ code?: string;
8
+ orderDiscount?: { _id?: string; orderId: string };
9
+ order?: { _id?: string; userId: string };
10
+ }
11
+
12
+ export type IDiscountAdapter<DiscountConfiguration> = IBaseAdapter & {
13
+ orderIndex: number;
14
+
15
+ isManualAdditionAllowed: (code: string) => Promise<boolean>;
16
+ isManualRemovalAllowed: () => Promise<boolean>;
17
+
18
+ actions: (params: {
19
+ context: DiscountContext & UnchainedCore;
20
+ }) => Promise<DiscountAdapterActions<DiscountConfiguration>>;
21
+ };
22
+
23
+ export interface DiscountAdapterActions<DiscountConfiguration> {
24
+ isValidForSystemTriggering: () => Promise<boolean>;
25
+ isValidForCodeTriggering: (params: { code: string }) => Promise<boolean>;
26
+
27
+ discountForPricingAdapterKey: (params: {
28
+ pricingAdapterKey: string;
29
+ calculationSheet: IPricingSheet<PricingCalculation>;
30
+ }) => DiscountConfiguration;
31
+
32
+ reserve: (params: { code: string }) => Promise<any>;
33
+ release: () => Promise<void>;
34
+ }
4
35
 
5
36
  export const BaseDiscountAdapter: Omit<IDiscountAdapter<unknown>, 'key' | 'label' | 'version'> = {
6
37
  orderIndex: 0,
@@ -1,6 +1,19 @@
1
- import { IDiscountAdapter, IDiscountDirector } from '@unchainedshop/types/discount.js';
2
1
  import { log } from '@unchainedshop/logger';
3
- import { BaseDirector } from './BaseDirector.js';
2
+ import { BaseDirector, IBaseDirector } from './BaseDirector.js';
3
+ import { DiscountContext, IDiscountAdapter } from './BaseDiscountAdapter.js';
4
+ import { UnchainedCore } from '@unchainedshop/core';
5
+
6
+ export type IDiscountDirector<DiscountConfiguration> = IBaseDirector<
7
+ IDiscountAdapter<DiscountConfiguration>
8
+ > & {
9
+ actions: (
10
+ discountContext: DiscountContext,
11
+ unchainedAPI: UnchainedCore,
12
+ ) => Promise<{
13
+ resolveDiscountKeyFromStaticCode: (params: { code: string }) => Promise<string | null>;
14
+ findSystemDiscounts: () => Promise<Array<string>>;
15
+ }>;
16
+ };
4
17
 
5
18
  export const BaseDiscountDirector = <DiscountConfigurationType>(
6
19
  directorName: string,
@@ -1,16 +1,64 @@
1
- import {
2
- BasePricingAdapterContext,
3
- IPricingSheet,
4
- IPricingAdapter,
5
- PricingCalculation,
6
- IPricingAdapterActions,
7
- } from '@unchainedshop/types/pricing.js';
1
+ import { UnchainedCore } from '@unchainedshop/core';
2
+ import { User } from '@unchainedshop/core-users';
8
3
  import { log, LogLevel } from '@unchainedshop/logger';
4
+ import { IPricingSheet, PricingCalculation } from './BasePricingSheet.js';
5
+ import { IBaseAdapter } from './BaseAdapter.js';
6
+ import { Discount } from './BasePricingDirector.js';
7
+
8
+ type Order = { _id?: string };
9
+ type OrderDiscount = { _id?: string };
10
+
11
+ interface IDiscountableItem {
12
+ _id?: string;
13
+ orderId?: string;
14
+ }
15
+
16
+ export interface BasePricingAdapterContext extends UnchainedCore {
17
+ order?: Order;
18
+ user: User;
19
+ discounts: Array<OrderDiscount>;
20
+ }
21
+
22
+ export type BasePricingContext =
23
+ | {
24
+ order?: Order;
25
+ user?: User;
26
+ discounts?: Array<OrderDiscount>;
27
+ }
28
+ | {
29
+ item: IDiscountableItem;
30
+ };
31
+
32
+ export interface IPricingAdapterActions<
33
+ Calculation extends PricingCalculation,
34
+ PricingAdapterContext extends BasePricingAdapterContext,
35
+ > {
36
+ calculate: () => Promise<Array<Calculation>>;
37
+ getCalculation: () => Array<Calculation>;
38
+ getContext: () => PricingAdapterContext;
39
+ }
40
+
41
+ export type IPricingAdapter<
42
+ PricingAdapterContext extends BasePricingAdapterContext,
43
+ Calculation extends PricingCalculation,
44
+ Sheet extends IPricingSheet<Calculation>,
45
+ DiscountConfiguration = unknown,
46
+ > = IBaseAdapter & {
47
+ orderIndex: number;
48
+
49
+ isActivatedFor: (context: PricingAdapterContext) => boolean;
50
+
51
+ actions: (params: {
52
+ context: PricingAdapterContext;
53
+ calculationSheet: Sheet;
54
+ discounts: Array<Discount<DiscountConfiguration>>;
55
+ }) => IPricingAdapterActions<Calculation, PricingAdapterContext> & { resultSheet: () => Sheet };
56
+ };
9
57
 
10
58
  export const BasePricingAdapter = <
11
- Context extends BasePricingAdapterContext,
59
+ PricingAdapterContext extends BasePricingAdapterContext,
12
60
  Calculation extends PricingCalculation,
13
- >(): IPricingAdapter<Context, Calculation, IPricingSheet<Calculation>> => ({
61
+ >(): IPricingAdapter<PricingAdapterContext, Calculation, IPricingSheet<Calculation>> => ({
14
62
  key: '',
15
63
  label: '',
16
64
  version: '',
@@ -22,7 +70,7 @@ export const BasePricingAdapter = <
22
70
 
23
71
  actions: (params) => {
24
72
  const calculation = [];
25
- const actions: IPricingAdapterActions<Calculation, Context> = {
73
+ const actions: IPricingAdapterActions<Calculation, PricingAdapterContext> = {
26
74
  calculate: async () => {
27
75
  return [];
28
76
  },
@@ -30,7 +78,7 @@ export const BasePricingAdapter = <
30
78
  getContext: () => params.context,
31
79
  };
32
80
 
33
- return actions as IPricingAdapterActions<Calculation, Context> & {
81
+ return actions as IPricingAdapterActions<Calculation, PricingAdapterContext> & {
34
82
  resultSheet: () => IPricingSheet<Calculation>;
35
83
  };
36
84
  },
@@ -1,15 +1,42 @@
1
- import { Discount } from '@unchainedshop/types/discount.js';
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ import { BaseDirector, IBaseDirector } from './BaseDirector.js';
3
+ import { UnchainedCore } from '@unchainedshop/core';
2
4
  import {
3
5
  BasePricingAdapterContext,
4
6
  BasePricingContext,
5
- IPricingDirector,
6
7
  IPricingAdapter,
7
- IPricingSheet,
8
- PricingCalculation,
9
8
  IPricingAdapterActions,
10
- } from '@unchainedshop/types/pricing.js';
11
- import { log, LogLevel } from '@unchainedshop/logger';
12
- import { BaseDirector } from './BaseDirector.js';
9
+ } from './BasePricingAdapter.js';
10
+ import { IPricingSheet, PricingCalculation } from './BasePricingSheet.js';
11
+ export interface Discount<DiscountConfiguration> {
12
+ discountId: string;
13
+ configuration: DiscountConfiguration;
14
+ }
15
+
16
+ export type IPricingDirector<
17
+ PricingContext extends BasePricingContext,
18
+ Calculation extends PricingCalculation,
19
+ PricingAdapterContext extends BasePricingAdapterContext,
20
+ PricingAdapterSheet extends IPricingSheet<Calculation>,
21
+ Adapter extends IPricingAdapter<PricingAdapterContext, Calculation, PricingAdapterSheet>,
22
+ > = IBaseDirector<Adapter> & {
23
+ buildPricingContext: (
24
+ context: PricingContext,
25
+ unchainedAPI: UnchainedCore,
26
+ ) => Promise<PricingAdapterContext>;
27
+ actions: (
28
+ pricingContext: PricingContext,
29
+ unchainedAPI: UnchainedCore,
30
+ buildPricingContext?: (
31
+ pricingCtx: PricingContext,
32
+ _unchainedAPI: UnchainedCore,
33
+ ) => Promise<PricingAdapterContext>,
34
+ ) => Promise<
35
+ IPricingAdapterActions<Calculation, PricingAdapterContext> & {
36
+ calculationSheet: () => PricingAdapterSheet;
37
+ }
38
+ >;
39
+ };
13
40
 
14
41
  export const BasePricingDirector = <
15
42
  DirectorContext extends BasePricingContext,
@@ -61,10 +88,10 @@ export const BasePricingDirector = <
61
88
  context.discounts.map(async (discount) => ({
62
89
  discountId: discount._id,
63
90
  configuration: await context.modules.orders.discounts.configurationForPricingAdapterKey(
64
- discount,
91
+ discount as any,
65
92
  Adapter.key,
66
93
  this.calculationSheet(),
67
- context,
94
+ context as any,
68
95
  ),
69
96
  })),
70
97
  );
@@ -1,8 +1,48 @@
1
- import {
2
- PricingCalculation,
3
- IBasePricingSheet,
4
- PricingSheetParams,
5
- } from '@unchainedshop/types/pricing.js';
1
+ export interface PricingCalculation {
2
+ category: string;
3
+ amount: number;
4
+ baseCategory?: string;
5
+ meta?: any;
6
+ }
7
+ export interface PricingDiscount {
8
+ discountId: string;
9
+ amount: number;
10
+ currency: string;
11
+ }
12
+
13
+ export interface IPricingSheet<Calculation extends PricingCalculation>
14
+ extends IBasePricingSheet<Calculation> {
15
+ discountPrices: (discountId?: string) => Array<PricingDiscount>;
16
+ addDiscount: (params: { amount: number; discountId: string; meta?: any }) => void;
17
+ }
18
+
19
+ export interface IBasePricingSheet<Calculation extends PricingCalculation> {
20
+ calculation: Array<Calculation>;
21
+ currency?: string;
22
+ quantity?: number;
23
+
24
+ getRawPricingSheet: () => Array<Calculation>;
25
+ filterBy: (filter?: Partial<Calculation>) => Array<Calculation>;
26
+ isValid: () => boolean;
27
+
28
+ gross: () => number;
29
+ net: () => number;
30
+ sum: (filter?: Partial<Calculation>) => number;
31
+ total: (params?: { category?: string; discountId?: string; useNetPrice?: boolean }) => {
32
+ amount: number;
33
+ currency: string;
34
+ };
35
+
36
+ taxSum: (filter?: Partial<Calculation>) => number;
37
+
38
+ resetCalculation: (sheetToInvert: IBasePricingSheet<Calculation>) => Array<Calculation>;
39
+ }
40
+
41
+ export interface PricingSheetParams<Calculation extends PricingCalculation> {
42
+ calculation?: Array<Calculation>;
43
+ currency?: string;
44
+ quantity?: number;
45
+ }
6
46
 
7
47
  export const BasePricingSheet = <Calculation extends PricingCalculation>(
8
48
  params: PricingSheetParams<Calculation>,
@@ -1,4 +1,4 @@
1
- import { BaseDirector } from "./BaseDirector.js";
1
+ import { BaseDirector } from './BaseDirector.js';
2
2
 
3
3
  const adapter1 = {
4
4
  key: 'adapter1',
@@ -31,99 +31,88 @@ describe('BaseDirector', () => {
31
31
  director.registerAdapter(adapter2);
32
32
  });
33
33
 
34
- describe('registerAdapter', ()=> {
35
-
34
+ describe('registerAdapter', () => {
36
35
  it('should add the adapter to the director', () => {
37
36
  director.registerAdapter(adapter1);
38
37
  expect(director.getAdapter(adapter1.key)).toBe(adapter1);
39
38
  });
40
-
39
+
41
40
  xit('should generate a log message when an adapter is registered', () => {
42
- const spy = import.meta.jest.spyOn(console, 'log')
43
- expect(spy).toHaveBeenCalledWith(
44
- 'TestDirector -> Registered adapter1 1.0.0 (Adapter 1)',
45
- );
41
+ const spy = import.meta.jest.spyOn(console, 'log');
42
+ expect(spy).toHaveBeenCalledWith('TestDirector -> Registered adapter1 1.0.0 (Adapter 1)');
46
43
  });
47
-
44
+
48
45
  it('should allow multiple adapters to be registered', () => {
49
46
  expect(director.getAdapter(adapter1.key)).toBe(adapter1);
50
47
  expect(director.getAdapter(adapter2.key)).toBe(adapter2);
51
48
  });
52
-
49
+
53
50
  it('should register an adapter and add it to the internal map', () => {
54
51
  expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
55
52
  });
56
-
53
+
57
54
  it('should use the adapterKeyField specified in the options to store the adapter in the internal map', () => {
58
-
59
55
  director = BaseDirector('TestDirector', {
60
56
  adapterKeyField: 'label',
61
57
  });
62
58
  director.registerAdapter(adapter1);
63
59
  expect(director.getAdapter(adapter1.label)).toEqual(adapter1);
64
60
  });
65
-
66
- it('should return the correct Adapter object', () => {
67
- const directorName = 'TestDirector';
68
- const adapterKeyField = 'key';
69
- director = BaseDirector(directorName, { adapterKeyField });
70
- director.registerAdapter(adapter1);
71
-
72
- expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
73
- });
74
-
75
- it('should return undefined if the Adapter does not exist', () => {
76
- const directorName = 'TestDirector';
77
- const adapterKeyField = 'key';
78
- director = BaseDirector(directorName, { adapterKeyField });
79
- expect(director.getAdapter(adapter1.key)).toBeUndefined();
80
- });
81
-
82
- })
83
61
 
62
+ it('should return the correct Adapter object', () => {
63
+ const directorName = 'TestDirector';
64
+ const adapterKeyField = 'key';
65
+ director = BaseDirector(directorName, { adapterKeyField });
66
+ director.registerAdapter(adapter1);
84
67
 
85
- describe('getAdapter', () => {
86
- it('should return the correct Adapter object for a given key', () => {
87
- // Expect that calling getAdapter with the key 'foo' returns the fooAdapter
88
- expect(director.getAdapter(adapter1.key)).toBe(adapter1);
89
- });
90
-
91
- it('should return undefined if no Adapter is registered with the given key', () => {
92
- // Expect that calling getAdapter with a key that has not been registered returns undefined
93
- expect(director.getAdapter('invalid-key')).toBeUndefined();
94
- });
68
+ expect(director.getAdapter(adapter1.key)).toEqual(adapter1);
69
+ });
95
70
 
96
- it('should return the correct Adapter object when the keyField is set to a property other than "key"', () => {
97
- // Create a director with the keyField option set to 'label'
98
- director = BaseDirector('TestDirector', { adapterKeyField: 'label' });
99
- director.registerAdapter(adapter1);
100
- expect(director.getAdapter(adapter1.label)).toBe(adapter1);
71
+ it('should return undefined if the Adapter does not exist', () => {
72
+ const directorName = 'TestDirector';
73
+ const adapterKeyField = 'key';
74
+ director = BaseDirector(directorName, { adapterKeyField });
75
+ expect(director.getAdapter(adapter1.key)).toBeUndefined();
76
+ });
101
77
  });
102
- });
103
78
 
104
- describe('getAdapters', () => {
105
- it('should return an array of registered Adapter objects', () => {
106
- expect(director.getAdapters()).toEqual([adapter1, adapter3, adapter2]);
107
- });
79
+ describe('getAdapter', () => {
80
+ it('should return the correct Adapter object for a given key', () => {
81
+ // Expect that calling getAdapter with the key 'foo' returns the fooAdapter
82
+ expect(director.getAdapter(adapter1.key)).toBe(adapter1);
83
+ });
108
84
 
109
- it('should return an empty array if no Adapter objects have been registered', () => {
110
- const directorName = 'TestDirector';
111
- const adapterKeyField = 'key';
112
- const baseDirector = BaseDirector(directorName, { adapterKeyField });
113
- expect(baseDirector.getAdapters()).toEqual([]);
114
- });
85
+ it('should return undefined if no Adapter is registered with the given key', () => {
86
+ // Expect that calling getAdapter with a key that has not been registered returns undefined
87
+ expect(director.getAdapter('invalid-key')).toBeUndefined();
88
+ });
115
89
 
116
- it('should return an array of registered Adapter objects sorted by the adapterSortKey provided', () => {
117
- director = BaseDirector('TestDirector', { adapterSortKey: 'version' });
118
- director.registerAdapter(adapter1);
119
- director.registerAdapter(adapter3);
120
- director.registerAdapter(adapter2);
121
- expect(director.getAdapters()).toEqual([adapter1, adapter2, adapter3]);
90
+ it('should return the correct Adapter object when the keyField is set to a property other than "key"', () => {
91
+ // Create a director with the keyField option set to 'label'
92
+ director = BaseDirector('TestDirector', { adapterKeyField: 'label' });
93
+ director.registerAdapter(adapter1);
94
+ expect(director.getAdapter(adapter1.label)).toBe(adapter1);
95
+ });
122
96
  });
123
97
 
124
- })
125
-
126
-
127
- })
98
+ describe('getAdapters', () => {
99
+ it('should return an array of registered Adapter objects', () => {
100
+ expect(director.getAdapters()).toEqual([adapter1, adapter3, adapter2]);
101
+ });
128
102
 
103
+ it('should return an empty array if no Adapter objects have been registered', () => {
104
+ const directorName = 'TestDirector';
105
+ const adapterKeyField = 'key';
106
+ const baseDirector = BaseDirector(directorName, { adapterKeyField });
107
+ expect(baseDirector.getAdapters()).toEqual([]);
108
+ });
129
109
 
110
+ it('should return an array of registered Adapter objects sorted by the adapterSortKey provided', () => {
111
+ director = BaseDirector('TestDirector', { adapterSortKey: 'version' });
112
+ director.registerAdapter(adapter1);
113
+ director.registerAdapter(adapter3);
114
+ director.registerAdapter(adapter2);
115
+ expect(director.getAdapters()).toEqual([adapter1, adapter2, adapter3]);
116
+ });
117
+ });
118
+ });