@labdigital/commercetools-mock 0.5.13 → 0.5.16

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 (106) hide show
  1. package/README.md +6 -2
  2. package/dist/commercetools-mock.cjs.development.js +3087 -1642
  3. package/dist/commercetools-mock.cjs.development.js.map +1 -1
  4. package/dist/commercetools-mock.cjs.production.min.js +1 -1
  5. package/dist/commercetools-mock.cjs.production.min.js.map +1 -1
  6. package/dist/commercetools-mock.esm.js +3087 -1642
  7. package/dist/commercetools-mock.esm.js.map +1 -1
  8. package/dist/ctMock.d.ts +1 -0
  9. package/dist/lib/masking.d.ts +1 -0
  10. package/dist/repositories/abstract.d.ts +9 -7
  11. package/dist/repositories/cart-discount.d.ts +9 -0
  12. package/dist/repositories/cart.d.ts +16 -3
  13. package/dist/repositories/category.d.ts +18 -0
  14. package/dist/repositories/channel.d.ts +6 -0
  15. package/dist/repositories/custom-object.d.ts +2 -2
  16. package/dist/repositories/customer-group.d.ts +11 -0
  17. package/dist/repositories/customer.d.ts +2 -2
  18. package/dist/repositories/discount-code.d.ts +8 -0
  19. package/dist/repositories/errors.d.ts +2 -2
  20. package/dist/repositories/extension.d.ts +8 -0
  21. package/dist/repositories/inventory-entry.d.ts +2 -2
  22. package/dist/repositories/order.d.ts +2 -2
  23. package/dist/repositories/payment.d.ts +4 -3
  24. package/dist/repositories/product-projection.d.ts +2 -2
  25. package/dist/repositories/product-type.d.ts +5 -4
  26. package/dist/repositories/product.d.ts +2 -2
  27. package/dist/repositories/project.d.ts +8 -0
  28. package/dist/repositories/shipping-method.d.ts +7 -5
  29. package/dist/repositories/shopping-list.d.ts +2 -2
  30. package/dist/repositories/state.d.ts +5 -4
  31. package/dist/repositories/store.d.ts +6 -3
  32. package/dist/repositories/subscription.d.ts +6 -0
  33. package/dist/repositories/tax-category.d.ts +6 -5
  34. package/dist/repositories/type.d.ts +5 -3
  35. package/dist/repositories/zone.d.ts +8 -0
  36. package/dist/services/abstract.d.ts +4 -3
  37. package/dist/services/cart-discount.d.ts +9 -0
  38. package/dist/services/category.d.ts +9 -0
  39. package/dist/services/channel.d.ts +9 -0
  40. package/dist/services/customer-group.d.ts +9 -0
  41. package/dist/services/discount-code.d.ts +9 -0
  42. package/dist/services/extension.d.ts +9 -0
  43. package/dist/services/my-cart.d.ts +11 -0
  44. package/dist/services/project.d.ts +11 -0
  45. package/dist/services/subscription.d.ts +9 -0
  46. package/dist/services/zone.d.ts +9 -0
  47. package/dist/storage.d.ts +10 -1
  48. package/dist/types.d.ts +2 -1
  49. package/package.json +20 -20
  50. package/src/ctMock.ts +44 -17
  51. package/src/lib/masking.ts +22 -0
  52. package/src/oauth/server.ts +3 -1
  53. package/src/repositories/abstract.ts +39 -33
  54. package/src/repositories/cart-discount.ts +140 -0
  55. package/src/repositories/cart.ts +247 -3
  56. package/src/repositories/category.ts +140 -0
  57. package/src/repositories/channel.ts +23 -0
  58. package/src/repositories/custom-object.ts +2 -2
  59. package/src/repositories/customer-group.ts +42 -0
  60. package/src/repositories/customer.ts +2 -2
  61. package/src/repositories/discount-code.ts +143 -0
  62. package/src/repositories/errors.ts +7 -2
  63. package/src/repositories/extension.ts +65 -0
  64. package/src/repositories/inventory-entry.ts +2 -2
  65. package/src/repositories/order.ts +2 -2
  66. package/src/repositories/payment.ts +10 -6
  67. package/src/repositories/product-projection.ts +4 -3
  68. package/src/repositories/product-type.ts +57 -4
  69. package/src/repositories/product.ts +4 -2
  70. package/src/repositories/project.ts +156 -0
  71. package/src/repositories/shipping-method.ts +149 -13
  72. package/src/repositories/shopping-list.ts +2 -2
  73. package/src/repositories/state.ts +48 -4
  74. package/src/repositories/store.ts +69 -4
  75. package/src/repositories/subscription.ts +50 -0
  76. package/src/repositories/tax-category.ts +80 -6
  77. package/src/repositories/type.ts +133 -3
  78. package/src/repositories/zone.ts +77 -0
  79. package/src/server.ts +6 -1
  80. package/src/services/abstract.ts +16 -15
  81. package/src/services/cart-discount.ts +17 -0
  82. package/src/services/cart.test.ts +314 -3
  83. package/src/services/category.test.ts +37 -0
  84. package/src/services/category.ts +17 -0
  85. package/src/services/channel.ts +17 -0
  86. package/src/services/custom-object.test.ts +3 -3
  87. package/src/services/customer-group.ts +17 -0
  88. package/src/services/discount-code.ts +17 -0
  89. package/src/services/extension.ts +17 -0
  90. package/src/services/inventory-entry.test.ts +3 -3
  91. package/src/services/my-cart.test.ts +93 -0
  92. package/src/services/my-cart.ts +44 -0
  93. package/src/services/my-payment.test.ts +2 -2
  94. package/src/services/order.test.ts +4 -4
  95. package/src/services/payment.test.ts +2 -2
  96. package/src/services/product-projection.test.ts +44 -6
  97. package/src/services/product-type.test.ts +2 -2
  98. package/src/services/product.test.ts +6 -2
  99. package/src/services/project.ts +42 -0
  100. package/src/services/shipping-method.test.ts +3 -3
  101. package/src/services/state.test.ts +2 -2
  102. package/src/services/subscription.ts +17 -0
  103. package/src/services/tax-category.test.ts +3 -3
  104. package/src/services/zone.ts +17 -0
  105. package/src/storage.ts +77 -3
  106. package/src/types.ts +2 -1
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.5.13",
2
+ "version": "0.5.16",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -41,35 +41,35 @@
41
41
  }
42
42
  ],
43
43
  "devDependencies": {
44
- "@babel/preset-typescript": "^7.13.0",
45
- "@size-limit/preset-small-lib": "^4.10.2",
44
+ "@babel/preset-typescript": "^7.16.7",
45
+ "@size-limit/preset-small-lib": "^7.0.5",
46
46
  "@types/basic-auth": "^1.1.3",
47
47
  "@types/deep-equal": "^1.0.1",
48
- "@types/express": "^4.17.11",
49
- "@types/morgan": "^1.9.2",
48
+ "@types/express": "^4.17.13",
49
+ "@types/morgan": "^1.9.3",
50
50
  "@types/supertest": "^2.0.11",
51
- "@types/uuid": "^8.3.0",
52
- "esbuild-register": "^2.4.0",
53
- "got": "^11.8.2",
54
- "husky": "^6.0.0",
55
- "nodemon": "^2.0.7",
56
- "size-limit": "^4.10.2",
57
- "ts-node": "^9.1.1",
51
+ "@types/uuid": "^8.3.4",
52
+ "esbuild-register": "^3.3.1",
53
+ "got": "^11.8.3",
54
+ "husky": "^7.0.4",
55
+ "nodemon": "^2.0.15",
56
+ "size-limit": "^7.0.5",
57
+ "ts-node": "^10.4.0",
58
58
  "tsdx": "^0.14.1",
59
- "tslib": "^2.2.0",
60
- "typescript": "^4.2.4"
59
+ "tslib": "^2.3.1",
60
+ "typescript": "^4.5.4"
61
61
  },
62
62
  "dependencies": {
63
- "@commercetools/platform-sdk": "1.17.1",
64
- "ajv": "^8.1.0",
65
- "ajv-formats": "^2.0.2",
63
+ "@commercetools/platform-sdk": "2.4.1",
64
+ "ajv": "^8.8.2",
65
+ "ajv-formats": "^2.1.1",
66
66
  "basic-auth": "^2.0.1",
67
67
  "deep-equal": "^2.0.5",
68
- "express": "^4.17.1",
68
+ "express": "^4.17.2",
69
69
  "morgan": "^1.10.0",
70
- "nock": "^13.0.11",
70
+ "nock": "^13.2.1",
71
71
  "perplex": "^0.11.0",
72
72
  "pratt": "^0.7.0",
73
- "supertest": "^6.1.3"
73
+ "supertest": "^6.1.6"
74
74
  }
75
75
  }
package/src/ctMock.ts CHANGED
@@ -1,30 +1,42 @@
1
- import { ShoppingListService } from './services/shopping-list'
2
- import { ProductProjectionService } from './services/product-projection'
3
- import { ProductTypeService } from './services/product-type'
4
- import { ShippingMethodService } from './services/shipping-method'
5
- import { StateService } from './services/state'
6
- import { TaxCategoryService } from './services/tax-category'
7
- import { PaymentService } from './services/payment'
8
1
  import nock from 'nock'
9
2
  import express, { NextFunction, Request, Response } from 'express'
10
3
  import supertest from 'supertest'
11
4
  import morgan from 'morgan'
12
5
  import { AbstractStorage, InMemoryStorage } from './storage'
13
- import { TypeService } from './services/type'
14
- import { CustomObjectService } from './services/custom-object'
15
- import { CustomerService } from './services/customer'
16
- import { CartService } from './services/cart'
17
- import { InventoryEntryService } from './services/inventory-entry'
18
- import { OrderService } from './services/order'
19
6
  import { Services } from './types'
20
- import { StoreService } from './services/store'
21
7
  import { CommercetoolsError } from './exceptions'
22
8
  import { OAuth2Server } from './oauth/server'
23
- import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from './constants'
24
9
  import { ProjectAPI } from './projectAPI'
25
10
  import { copyHeaders } from './lib/proxy'
26
- import { ProductService } from './services/product'
11
+ import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from './constants'
12
+
13
+ // Services
14
+ import { CartDiscountService } from './services/cart-discount'
15
+ import { CartService } from './services/cart'
16
+ import { CategoryServices } from './services/category'
17
+ import { ChannelService } from './services/channel'
18
+ import { CustomerGroupService } from './services/customer-group'
19
+ import { CustomerService } from './services/customer'
20
+ import { CustomObjectService } from './services/custom-object'
21
+ import { DiscountCodeService } from './services/discount-code'
22
+ import { ExtensionServices } from './services/extension'
23
+ import { InventoryEntryService } from './services/inventory-entry'
24
+ import { MyCartService } from './services/my-cart'
27
25
  import { MyPaymentService } from './services/my-payment'
26
+ import { OrderService } from './services/order'
27
+ import { PaymentService } from './services/payment'
28
+ import { ProductProjectionService } from './services/product-projection'
29
+ import { ProductService } from './services/product'
30
+ import { ProductTypeService } from './services/product-type'
31
+ import { ProjectService } from './services/project'
32
+ import { ShippingMethodService } from './services/shipping-method'
33
+ import { ShoppingListService } from './services/shopping-list'
34
+ import { StateService } from './services/state'
35
+ import { StoreService } from './services/store'
36
+ import { SubscriptionService } from './services/subscription'
37
+ import { TaxCategoryService } from './services/tax-category'
38
+ import { TypeService } from './services/type'
39
+ import { ZoneService } from './services/zone'
28
40
 
29
41
  export type CommercetoolsMockOptions = {
30
42
  validateCredentials: boolean
@@ -57,10 +69,12 @@ export class CommercetoolsMock {
57
69
  api: nock.Scope | undefined
58
70
  } = { auth: undefined, api: undefined }
59
71
  private _services: Services
72
+ private _projectService?: ProjectService
60
73
 
61
74
  constructor(options: Partial<CommercetoolsMockOptions> = {}) {
62
75
  this.options = { ...DEFAULT_OPTIONS, ...options }
63
76
  this._services = {}
77
+ this._projectService = undefined
64
78
 
65
79
  this._storage = new InMemoryStorage()
66
80
  this._oauth2 = new OAuth2Server({
@@ -103,9 +117,10 @@ export class CommercetoolsMock {
103
117
 
104
118
  runServer(port: number = 3000, options?: AppOptions) {
105
119
  const app = this.createApp(options)
106
- app.listen(port, () => {
120
+ const server = app.listen(port, () => {
107
121
  console.log(`Mock server listening at http://localhost:${port}`)
108
122
  })
123
+ server.keepAliveTimeout = 60 * 1000
109
124
  }
110
125
 
111
126
  private createApp(options?: AppOptions): express.Express {
@@ -126,9 +141,17 @@ export class CommercetoolsMock {
126
141
  app.use('/:projectKey', projectRouter)
127
142
  }
128
143
 
144
+ this._projectService = new ProjectService(projectRouter, this._storage)
145
+
129
146
  this._services = {
147
+ category: new CategoryServices(projectRouter, this._storage),
130
148
  cart: new CartService(projectRouter, this._storage),
149
+ 'cart-discount': new CartDiscountService(projectRouter, this._storage),
131
150
  customer: new CustomerService(projectRouter, this._storage),
151
+ channel: new ChannelService(projectRouter, this._storage),
152
+ 'customer-group': new CustomerGroupService(projectRouter, this._storage),
153
+ 'discount-code': new DiscountCodeService(projectRouter, this._storage),
154
+ extension: new ExtensionServices(projectRouter, this._storage),
132
155
  'inventory-entry': new InventoryEntryService(
133
156
  projectRouter,
134
157
  this._storage
@@ -139,6 +162,7 @@ export class CommercetoolsMock {
139
162
  ),
140
163
  order: new OrderService(projectRouter, this._storage),
141
164
  payment: new PaymentService(projectRouter, this._storage),
165
+ 'my-cart': new MyCartService(projectRouter, this._storage),
142
166
  'my-payment': new MyPaymentService(projectRouter, this._storage),
143
167
  'shipping-method': new ShippingMethodService(
144
168
  projectRouter,
@@ -153,8 +177,10 @@ export class CommercetoolsMock {
153
177
  'shopping-list': new ShoppingListService(projectRouter, this._storage),
154
178
  state: new StateService(projectRouter, this._storage),
155
179
  store: new StoreService(projectRouter, this._storage),
180
+ subscription: new SubscriptionService(projectRouter, this._storage),
156
181
  'tax-category': new TaxCategoryService(projectRouter, this._storage),
157
182
  type: new TypeService(projectRouter, this._storage),
183
+ zone: new ZoneService(projectRouter, this._storage),
158
184
  }
159
185
 
160
186
  app.use((err: Error, req: Request, resp: Response, next: NextFunction) => {
@@ -165,6 +191,7 @@ export class CommercetoolsMock {
165
191
  errors: [err.info],
166
192
  })
167
193
  } else {
194
+ console.error(err)
168
195
  return resp.status(500).send({
169
196
  error: err.message,
170
197
  })
@@ -0,0 +1,22 @@
1
+ import { json } from 'express'
2
+
3
+ export const maskSecretValue = <T>(resource: T, path: string): T => {
4
+ const parts = path.split('.')
5
+ const clone = JSON.parse(JSON.stringify(resource))
6
+ let val = clone
7
+
8
+ const target = parts.pop()
9
+ for (let i = 0; i < parts.length; i++) {
10
+ const part = parts[i]
11
+ val = val[part]
12
+
13
+ if (val == undefined) {
14
+ return resource
15
+ }
16
+ }
17
+
18
+ if (val && target && val[target]) {
19
+ val[target] = '****'
20
+ }
21
+ return clone
22
+ }
@@ -1,4 +1,5 @@
1
1
  import auth from 'basic-auth'
2
+ import bodyParser from 'body-parser'
2
3
  import express, { NextFunction, Request, Response } from 'express'
3
4
  import {
4
5
  AccessDeniedError,
@@ -18,6 +19,7 @@ export class OAuth2Server {
18
19
 
19
20
  createRouter() {
20
21
  const router = express.Router()
22
+ router.use(bodyParser.urlencoded({ extended: true }))
21
23
  router.post('/token', this.tokenHandler.bind(this))
22
24
  return router
23
25
  }
@@ -81,7 +83,7 @@ export class OAuth2Server {
81
83
  )
82
84
  }
83
85
 
84
- const grantType = request.query.grant_type
86
+ const grantType = request.query.grant_type || request.body.grant_type
85
87
  if (!grantType) {
86
88
  return next(
87
89
  new CommercetoolsError<InvalidRequestError>(
@@ -4,6 +4,7 @@ import deepEqual from 'deep-equal'
4
4
  import {
5
5
  BaseResource,
6
6
  InvalidOperationError,
7
+ Project,
7
8
  UpdateAction,
8
9
  } from '@commercetools/platform-sdk'
9
10
  import { AbstractStorage } from '../storage'
@@ -19,20 +20,50 @@ export type GetParams = {
19
20
  expand?: string[]
20
21
  }
21
22
 
22
- export default abstract class AbstractRepository {
23
+ export abstract class AbstractRepository {
23
24
  protected _storage: AbstractStorage
24
-
25
- protected actions: {
26
- [key: string]: (projectKey: string, resource: any, actions: any) => void
27
- } = {}
25
+ protected actions: Partial<
26
+ Record<any, (projectKey: string, resource: any, action: any) => void>
27
+ > = {}
28
28
 
29
29
  constructor(storage: AbstractStorage) {
30
30
  this._storage = storage
31
- this._storage.assertStorage(this.getTypeId())
32
31
  }
33
32
 
34
- abstract getTypeId(): RepositoryTypes
33
+ abstract save(projectKey: string, resource: BaseResource | Project): void
34
+
35
+ processUpdateActions(
36
+ projectKey: string,
37
+ resource: BaseResource | Project,
38
+ actions: UpdateAction[]
39
+ ): BaseResource {
40
+ // Deep-copy
41
+ const modifiedResource = JSON.parse(JSON.stringify(resource))
42
+
43
+ actions.forEach(action => {
44
+ const updateFunc = this.actions[action.action]
45
+ if (!updateFunc) {
46
+ console.error(`No mock implemented for update action ${action.action}`)
47
+ return
48
+ }
49
+ updateFunc(projectKey, modifiedResource, action)
50
+ })
51
+
52
+ if (!deepEqual(modifiedResource, resource)) {
53
+ this.save(projectKey, modifiedResource)
54
+ }
55
+ return modifiedResource
56
+ }
57
+ }
58
+
59
+ export abstract class AbstractResourceRepository extends AbstractRepository {
35
60
  abstract create(projectKey: string, draft: any): BaseResource
61
+ abstract getTypeId(): RepositoryTypes
62
+
63
+ constructor(storage: AbstractStorage) {
64
+ super(storage)
65
+ this._storage.assertStorage(this.getTypeId())
66
+ }
36
67
 
37
68
  query(projectKey: string, params: QueryParams = {}) {
38
69
  return this._storage.query(projectKey, this.getTypeId(), {
@@ -66,8 +97,6 @@ export default abstract class AbstractRepository {
66
97
  }
67
98
 
68
99
  save(projectKey: string, resource: BaseResource) {
69
- const typeId = this.getTypeId()
70
-
71
100
  const current = this.get(projectKey, resource.id)
72
101
 
73
102
  if (current) {
@@ -86,29 +115,6 @@ export default abstract class AbstractRepository {
86
115
 
87
116
  // @ts-ignore
88
117
  resource.version += 1
89
- this._storage.add(projectKey, typeId, resource as any)
90
- }
91
-
92
- processUpdateActions(
93
- projectKey: string,
94
- resource: BaseResource,
95
- actions: UpdateAction[]
96
- ): BaseResource {
97
- // Deep-copy
98
- const modifiedResource = JSON.parse(JSON.stringify(resource))
99
-
100
- actions.forEach(action => {
101
- const updateFunc = this.actions[action.action]
102
- if (!updateFunc) {
103
- console.error(`No mock implemented for update action ${action.action}`)
104
- return
105
- }
106
- updateFunc(projectKey, modifiedResource, action)
107
- })
108
-
109
- if (!deepEqual(modifiedResource, resource)) {
110
- this.save(projectKey, modifiedResource)
111
- }
112
- return modifiedResource
118
+ this._storage.add(projectKey, this.getTypeId(), resource as any)
113
119
  }
114
120
  }
@@ -0,0 +1,140 @@
1
+ import {
2
+ CartDiscount,
3
+ CartDiscountChangeIsActiveAction,
4
+ CartDiscountChangeSortOrderAction,
5
+ CartDiscountDraft,
6
+ CartDiscountSetDescriptionAction,
7
+ CartDiscountSetKeyAction,
8
+ CartDiscountSetValidFromAction,
9
+ CartDiscountSetValidFromAndUntilAction,
10
+ CartDiscountSetValidUntilAction,
11
+ CartDiscountUpdateAction,
12
+ CartDiscountValueAbsolute,
13
+ CartDiscountValueDraft,
14
+ CartDiscountValueFixed,
15
+ CartDiscountValueGiftLineItem,
16
+ CartDiscountValueRelative,
17
+ ReferenceTypeId,
18
+ } from '@commercetools/platform-sdk'
19
+ import { Writable } from 'types'
20
+ import { getBaseResourceProperties } from '../helpers'
21
+ import { AbstractResourceRepository } from './abstract'
22
+ import { createTypedMoney } from './helpers'
23
+
24
+ export class CartDiscountRepository extends AbstractResourceRepository {
25
+ getTypeId(): ReferenceTypeId {
26
+ return 'cart-discount'
27
+ }
28
+
29
+ create(projectKey: string, draft: CartDiscountDraft): CartDiscount {
30
+ const resource: CartDiscount = {
31
+ ...getBaseResourceProperties(),
32
+ key: draft.key,
33
+ description: draft.description,
34
+ cartPredicate: draft.cartPredicate,
35
+ isActive: draft.isActive || false,
36
+ name: draft.name,
37
+ references: [],
38
+ target: draft.target,
39
+ requiresDiscountCode: draft.requiresDiscountCode || false,
40
+ sortOrder: draft.sortOrder,
41
+ stackingMode: draft.stackingMode || 'Stacking',
42
+ validFrom: draft.validFrom,
43
+ validUntil: draft.validUntil,
44
+ value: this.transformValueDraft(draft.value),
45
+ }
46
+ this.save(projectKey, resource)
47
+ return resource
48
+ }
49
+
50
+ private transformValueDraft(value: CartDiscountValueDraft) {
51
+ switch (value.type) {
52
+ case 'absolute': {
53
+ return {
54
+ type: 'absolute',
55
+ money: value.money.map(createTypedMoney),
56
+ } as CartDiscountValueAbsolute
57
+ }
58
+ case 'fixed': {
59
+ return {
60
+ type: 'fixed',
61
+ money: value.money.map(createTypedMoney),
62
+ } as CartDiscountValueFixed
63
+ }
64
+ case 'giftLineItem': {
65
+ return {
66
+ ...value,
67
+ } as CartDiscountValueGiftLineItem
68
+ }
69
+ case 'relative': {
70
+ return {
71
+ ...value,
72
+ } as CartDiscountValueRelative
73
+ }
74
+ }
75
+
76
+ return value
77
+ }
78
+
79
+ actions: Partial<
80
+ Record<
81
+ CartDiscountUpdateAction['action'],
82
+ (
83
+ projectKey: string,
84
+ resource: Writable<CartDiscount>,
85
+ action: any
86
+ ) => void
87
+ >
88
+ > = {
89
+ setKey: (
90
+ projectKey: string,
91
+ resource: Writable<CartDiscount>,
92
+ { key }: CartDiscountSetKeyAction
93
+ ) => {
94
+ resource.key = key
95
+ },
96
+ setDescription: (
97
+ projectKey: string,
98
+ resource: Writable<CartDiscount>,
99
+ { description }: CartDiscountSetDescriptionAction
100
+ ) => {
101
+ resource.description = description
102
+ },
103
+ setValidFrom: (
104
+ projectKey: string,
105
+ resource: Writable<CartDiscount>,
106
+ { validFrom }: CartDiscountSetValidFromAction
107
+ ) => {
108
+ resource.validFrom = validFrom
109
+ },
110
+ setValidUntil: (
111
+ projectKey: string,
112
+ resource: Writable<CartDiscount>,
113
+ { validUntil }: CartDiscountSetValidUntilAction
114
+ ) => {
115
+ resource.validUntil = validUntil
116
+ },
117
+ setValidFromAndUntil: (
118
+ projectKey: string,
119
+ resource: Writable<CartDiscount>,
120
+ { validFrom, validUntil }: CartDiscountSetValidFromAndUntilAction
121
+ ) => {
122
+ resource.validFrom = validFrom
123
+ resource.validUntil = validUntil
124
+ },
125
+ changeSortOrder: (
126
+ projectKey: string,
127
+ resource: Writable<CartDiscount>,
128
+ { sortOrder }: CartDiscountChangeSortOrderAction
129
+ ) => {
130
+ resource.sortOrder = sortOrder
131
+ },
132
+ changeIsActive: (
133
+ projectKey: string,
134
+ resource: Writable<CartDiscount>,
135
+ { isActive }: CartDiscountChangeIsActiveAction
136
+ ) => {
137
+ resource.isActive = isActive
138
+ },
139
+ }
140
+ }