@labdigital/commercetools-mock 2.17.1 → 2.18.1

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 (180) hide show
  1. package/dist/index.cjs +4351 -4099
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +266 -413
  4. package/dist/index.d.ts +266 -413
  5. package/dist/index.js +4351 -4099
  6. package/dist/index.js.map +1 -1
  7. package/package.json +47 -47
  8. package/src/constants.ts +2 -2
  9. package/src/ctMock.test.ts +11 -11
  10. package/src/ctMock.ts +141 -127
  11. package/src/deprecation.ts +8 -0
  12. package/src/exceptions.ts +17 -15
  13. package/src/helpers.ts +32 -32
  14. package/src/index.test.ts +128 -128
  15. package/src/index.ts +3 -3
  16. package/src/lib/expandParser.ts +13 -13
  17. package/src/lib/haversine.test.ts +9 -9
  18. package/src/lib/haversine.ts +11 -11
  19. package/src/lib/masking.ts +11 -11
  20. package/src/lib/parser.ts +2 -2
  21. package/src/lib/password.ts +23 -3
  22. package/src/lib/predicateParser.test.ts +185 -183
  23. package/src/lib/predicateParser.ts +234 -234
  24. package/src/lib/projectionSearchFilter.test.ts +103 -101
  25. package/src/lib/projectionSearchFilter.ts +152 -150
  26. package/src/lib/proxy.ts +5 -5
  27. package/src/oauth/errors.ts +4 -4
  28. package/src/oauth/helpers.ts +6 -6
  29. package/src/oauth/server.test.ts +86 -86
  30. package/src/oauth/server.ts +158 -144
  31. package/src/oauth/store.ts +44 -43
  32. package/src/priceSelector.test.ts +35 -35
  33. package/src/priceSelector.ts +30 -30
  34. package/src/product-projection-search.ts +136 -134
  35. package/src/projectAPI.test.ts +7 -7
  36. package/src/projectAPI.ts +24 -22
  37. package/src/repositories/abstract.ts +168 -116
  38. package/src/repositories/associate-role.ts +90 -77
  39. package/src/repositories/attribute-group.ts +51 -40
  40. package/src/repositories/business-unit.ts +168 -148
  41. package/src/repositories/cart/actions.ts +489 -0
  42. package/src/repositories/cart/helpers.ts +30 -0
  43. package/src/repositories/cart/index.ts +180 -0
  44. package/src/repositories/cart-discount/actions.ts +148 -0
  45. package/src/repositories/cart-discount/index.ts +86 -0
  46. package/src/repositories/category/actions.ts +231 -0
  47. package/src/repositories/category/index.ts +52 -0
  48. package/src/repositories/channel.ts +88 -90
  49. package/src/repositories/custom-object.ts +46 -45
  50. package/src/repositories/customer/actions.ts +165 -0
  51. package/src/repositories/customer/index.ts +79 -0
  52. package/src/repositories/customer-group.ts +66 -55
  53. package/src/repositories/discount-code/actions.ts +149 -0
  54. package/src/repositories/discount-code/index.ts +50 -0
  55. package/src/repositories/errors.ts +10 -10
  56. package/src/repositories/extension.ts +64 -62
  57. package/src/repositories/helpers.ts +117 -118
  58. package/src/repositories/index.ts +80 -79
  59. package/src/repositories/inventory-entry/actions.ts +84 -0
  60. package/src/repositories/inventory-entry/index.ts +44 -0
  61. package/src/repositories/my-customer.ts +114 -0
  62. package/src/repositories/my-order.ts +8 -8
  63. package/src/repositories/order/actions.ts +281 -0
  64. package/src/repositories/{order.test.ts → order/index.test.ts} +77 -77
  65. package/src/repositories/order/index.ts +260 -0
  66. package/src/repositories/order-edit.ts +10 -23
  67. package/src/repositories/payment/actions.ts +305 -0
  68. package/src/repositories/payment/helpers.ts +17 -0
  69. package/src/repositories/payment/index.ts +56 -0
  70. package/src/repositories/product/actions.ts +943 -0
  71. package/src/repositories/product/helpers.ts +98 -0
  72. package/src/repositories/product/index.ts +130 -0
  73. package/src/repositories/product-discount.ts +127 -117
  74. package/src/repositories/product-projection.ts +56 -62
  75. package/src/repositories/product-selection.ts +31 -28
  76. package/src/repositories/product-type.ts +136 -134
  77. package/src/repositories/project.ts +133 -118
  78. package/src/repositories/quote-request.ts +7 -19
  79. package/src/repositories/quote.ts +7 -22
  80. package/src/repositories/review.ts +13 -26
  81. package/src/repositories/shipping-method/actions.ts +198 -0
  82. package/src/repositories/shipping-method/helpers.ts +10 -0
  83. package/src/repositories/shipping-method/index.ts +138 -0
  84. package/src/repositories/shopping-list/actions.ts +295 -0
  85. package/src/repositories/shopping-list/index.ts +122 -0
  86. package/src/repositories/staged-quote.ts +7 -20
  87. package/src/repositories/standalone-price.ts +57 -44
  88. package/src/repositories/state.ts +113 -68
  89. package/src/repositories/store.ts +106 -94
  90. package/src/repositories/subscription.ts +46 -22
  91. package/src/repositories/tax-category/actions.ts +94 -0
  92. package/src/repositories/tax-category/helpers.ts +8 -0
  93. package/src/repositories/tax-category/index.ts +25 -0
  94. package/src/repositories/type/actions.ts +162 -0
  95. package/src/repositories/type/index.ts +24 -0
  96. package/src/repositories/zone.ts +62 -58
  97. package/src/schemas/update-request.ts +12 -0
  98. package/src/server.ts +9 -9
  99. package/src/services/abstract.ts +85 -72
  100. package/src/services/associate-roles.test.ts +27 -27
  101. package/src/services/associate-roles.ts +7 -7
  102. package/src/services/attribute-group.ts +7 -7
  103. package/src/services/business-units.test.ts +28 -28
  104. package/src/services/business-units.ts +7 -7
  105. package/src/services/cart-discount.test.ts +199 -199
  106. package/src/services/cart-discount.ts +7 -7
  107. package/src/services/cart.test.ts +261 -261
  108. package/src/services/cart.ts +22 -21
  109. package/src/services/category.test.ts +121 -121
  110. package/src/services/category.ts +7 -7
  111. package/src/services/channel.ts +7 -7
  112. package/src/services/custom-object.test.ts +130 -130
  113. package/src/services/custom-object.ts +34 -31
  114. package/src/services/customer-group.ts +7 -7
  115. package/src/services/customer.test.ts +205 -205
  116. package/src/services/customer.ts +23 -36
  117. package/src/services/discount-code.ts +7 -7
  118. package/src/services/extension.ts +7 -7
  119. package/src/services/index.ts +85 -81
  120. package/src/services/inventory-entry.test.ts +106 -106
  121. package/src/services/inventory-entry.ts +7 -7
  122. package/src/services/my-cart.test.ts +56 -56
  123. package/src/services/my-cart.ts +20 -20
  124. package/src/services/my-customer.test.ts +155 -104
  125. package/src/services/my-customer.ts +66 -75
  126. package/src/services/my-order.ts +16 -16
  127. package/src/services/my-payment.test.ts +40 -40
  128. package/src/services/my-payment.ts +7 -7
  129. package/src/services/my-shopping-list.ts +7 -7
  130. package/src/services/order.test.ts +243 -243
  131. package/src/services/order.ts +23 -18
  132. package/src/services/payment.test.ts +40 -40
  133. package/src/services/payment.ts +7 -7
  134. package/src/services/product-discount.ts +7 -7
  135. package/src/services/product-projection.test.ts +190 -190
  136. package/src/services/product-projection.ts +34 -32
  137. package/src/services/product-selection.test.ts +19 -19
  138. package/src/services/product-selection.ts +7 -7
  139. package/src/services/product-type.test.ts +38 -38
  140. package/src/services/product-type.ts +7 -7
  141. package/src/services/product.test.ts +658 -656
  142. package/src/services/product.ts +7 -7
  143. package/src/services/project.test.ts +29 -24
  144. package/src/services/project.ts +22 -17
  145. package/src/services/reviews.ts +7 -7
  146. package/src/services/shipping-method.test.ts +78 -78
  147. package/src/services/shipping-method.ts +16 -16
  148. package/src/services/shopping-list.test.ts +170 -170
  149. package/src/services/shopping-list.ts +7 -7
  150. package/src/services/standalone-price.test.ts +112 -112
  151. package/src/services/standalone-price.ts +7 -7
  152. package/src/services/state.test.ts +30 -30
  153. package/src/services/state.ts +7 -7
  154. package/src/services/store.test.ts +40 -40
  155. package/src/services/store.ts +7 -7
  156. package/src/services/subscription.ts +7 -7
  157. package/src/services/tax-category.test.ts +43 -43
  158. package/src/services/tax-category.ts +7 -7
  159. package/src/services/type.ts +7 -7
  160. package/src/services/zone.ts +7 -7
  161. package/src/shippingCalculator.test.ts +43 -43
  162. package/src/shippingCalculator.ts +23 -23
  163. package/src/storage/abstract.ts +36 -34
  164. package/src/storage/in-memory.ts +237 -233
  165. package/src/storage/index.ts +2 -2
  166. package/src/types.ts +91 -91
  167. package/src/validate.ts +18 -0
  168. package/src/repositories/cart-discount.ts +0 -219
  169. package/src/repositories/cart.ts +0 -659
  170. package/src/repositories/category.ts +0 -256
  171. package/src/repositories/customer.ts +0 -228
  172. package/src/repositories/discount-code.ts +0 -181
  173. package/src/repositories/inventory-entry.ts +0 -109
  174. package/src/repositories/order.ts +0 -514
  175. package/src/repositories/payment.ts +0 -342
  176. package/src/repositories/product.ts +0 -1106
  177. package/src/repositories/shipping-method.ts +0 -312
  178. package/src/repositories/shopping-list.ts +0 -392
  179. package/src/repositories/tax-category.ts +0 -111
  180. package/src/repositories/type.ts +0 -172
@@ -0,0 +1,162 @@
1
+ import type {
2
+ FieldDefinition,
3
+ InvalidOperationError,
4
+ Type,
5
+ TypeAddEnumValueAction,
6
+ TypeAddFieldDefinitionAction,
7
+ TypeChangeEnumValueLabelAction,
8
+ TypeChangeFieldDefinitionOrderAction,
9
+ TypeChangeNameAction,
10
+ TypeRemoveFieldDefinitionAction,
11
+ TypeSetDescriptionAction,
12
+ TypeUpdateAction,
13
+ } from "@commercetools/platform-sdk";
14
+ import isEqual from "lodash.isequal";
15
+ import { CommercetoolsError } from "~src/exceptions";
16
+ import type { Writable } from "~src/types";
17
+ import { AbstractUpdateHandler, RepositoryContext } from "../abstract";
18
+
19
+ type TypeUpdateHandlerMethod<T> = (
20
+ context: RepositoryContext,
21
+ resource: Writable<Type>,
22
+ action: T,
23
+ ) => void;
24
+
25
+ type TypeUpdateActions = Partial<{
26
+ [P in TypeUpdateAction as P["action"]]: TypeUpdateHandlerMethod<P>;
27
+ }>;
28
+
29
+ export class TypeUpdateHandler
30
+ extends AbstractUpdateHandler
31
+ implements TypeUpdateActions
32
+ {
33
+ addEnumValue(
34
+ context: RepositoryContext,
35
+ resource: Writable<Type>,
36
+ { fieldName, value }: TypeAddEnumValueAction,
37
+ ) {
38
+ resource.fieldDefinitions.forEach((field) => {
39
+ if (field.name === fieldName) {
40
+ // TODO, should be done better i suppose
41
+ if (field.type.name === "Enum") {
42
+ field.type.values.push(value);
43
+ } else if (
44
+ field.type.name === "Set" &&
45
+ field.type.elementType.name === "Enum"
46
+ ) {
47
+ field.type.elementType.values.push(value);
48
+ } else {
49
+ throw new Error("Type is not a Enum (or Set of Enum)");
50
+ }
51
+ }
52
+ });
53
+ }
54
+
55
+ addFieldDefinition(
56
+ context: RepositoryContext,
57
+ resource: Writable<Type>,
58
+ { fieldDefinition }: TypeAddFieldDefinitionAction,
59
+ ) {
60
+ resource.fieldDefinitions.push(fieldDefinition);
61
+ }
62
+
63
+ changeEnumValueLabel(
64
+ context: RepositoryContext,
65
+ resource: Writable<Type>,
66
+ { fieldName, value }: TypeChangeEnumValueLabelAction,
67
+ ) {
68
+ resource.fieldDefinitions.forEach((field) => {
69
+ if (field.name === fieldName) {
70
+ // TODO, should be done better i suppose
71
+ if (field.type.name === "Enum") {
72
+ field.type.values.forEach((v) => {
73
+ if (v.key === value.key) {
74
+ v.label = value.label;
75
+ }
76
+ });
77
+ } else if (
78
+ field.type.name === "Set" &&
79
+ field.type.elementType.name === "Enum"
80
+ ) {
81
+ field.type.elementType.values.forEach((v) => {
82
+ if (v.key === value.key) {
83
+ v.label = value.label;
84
+ }
85
+ });
86
+ } else {
87
+ throw new Error("Type is not a Enum (or Set of Enum)");
88
+ }
89
+ }
90
+ });
91
+ }
92
+
93
+ changeFieldDefinitionOrder(
94
+ context: RepositoryContext,
95
+ resource: Writable<Type>,
96
+ { fieldNames }: TypeChangeFieldDefinitionOrderAction,
97
+ ) {
98
+ const fields = new Map(
99
+ resource.fieldDefinitions.map((item) => [item.name, item]),
100
+ );
101
+ const result: FieldDefinition[] = [];
102
+ let current = resource.fieldDefinitions;
103
+
104
+ fieldNames.forEach((fieldName) => {
105
+ const field = fields.get(fieldName);
106
+ if (field === undefined) {
107
+ throw new Error("New field");
108
+ }
109
+ result.push(field);
110
+
111
+ // Remove from current items
112
+ current = current.filter((f) => f.name !== fieldName);
113
+ });
114
+
115
+ if (
116
+ isEqual(
117
+ fieldNames,
118
+ resource.fieldDefinitions.map((item) => item.name),
119
+ )
120
+ ) {
121
+ throw new CommercetoolsError<InvalidOperationError>({
122
+ code: "InvalidOperation",
123
+ message: "'fieldDefinitions' has no changes.",
124
+ action: {
125
+ action: "changeFieldDefinitionOrder",
126
+ fieldNames: fieldNames,
127
+ },
128
+ });
129
+ }
130
+
131
+ resource.fieldDefinitions = result;
132
+ // Add fields which were not specified in the order as last items. Not
133
+ // sure if this follows commercetools
134
+ resource.fieldDefinitions.push(...current);
135
+ }
136
+
137
+ changeName(
138
+ context: RepositoryContext,
139
+ resource: Writable<Type>,
140
+ { name }: TypeChangeNameAction,
141
+ ) {
142
+ resource.name = name;
143
+ }
144
+
145
+ removeFieldDefinition(
146
+ context: RepositoryContext,
147
+ resource: Writable<Type>,
148
+ { fieldName }: TypeRemoveFieldDefinitionAction,
149
+ ) {
150
+ resource.fieldDefinitions = resource.fieldDefinitions.filter(
151
+ (f) => f.name !== fieldName,
152
+ );
153
+ }
154
+
155
+ setDescription(
156
+ context: RepositoryContext,
157
+ resource: Writable<Type>,
158
+ { description }: TypeSetDescriptionAction,
159
+ ) {
160
+ resource.description = description;
161
+ }
162
+ }
@@ -0,0 +1,24 @@
1
+ import type { Type, TypeDraft } from "@commercetools/platform-sdk";
2
+ import { getBaseResourceProperties } from "~src/helpers";
3
+ import { AbstractStorage } from "~src/storage/abstract";
4
+ import { AbstractResourceRepository, RepositoryContext } from "../abstract";
5
+ import { TypeUpdateHandler } from "./actions";
6
+
7
+ export class TypeRepository extends AbstractResourceRepository<"type"> {
8
+ constructor(storage: AbstractStorage) {
9
+ super("type", storage);
10
+ this.actions = new TypeUpdateHandler(storage);
11
+ }
12
+
13
+ create(context: RepositoryContext, draft: TypeDraft): Type {
14
+ const resource: Type = {
15
+ ...getBaseResourceProperties(),
16
+ key: draft.key,
17
+ name: draft.name,
18
+ resourceTypeIds: draft.resourceTypeIds,
19
+ fieldDefinitions: draft.fieldDefinitions || [],
20
+ description: draft.description,
21
+ };
22
+ return this.saveNew(context, resource);
23
+ }
24
+ }
@@ -7,14 +7,21 @@ import type {
7
7
  ZoneSetDescriptionAction,
8
8
  ZoneSetKeyAction,
9
9
  ZoneUpdateAction,
10
- } from '@commercetools/platform-sdk'
11
- import { getBaseResourceProperties } from '../helpers.js'
12
- import type { Writable } from '../types.js'
13
- import { AbstractResourceRepository, RepositoryContext } from './abstract.js'
10
+ } from "@commercetools/platform-sdk";
11
+ import { getBaseResourceProperties } from "../helpers";
12
+ import { AbstractStorage } from "../storage/abstract";
13
+ import type { Writable } from "../types";
14
+ import {
15
+ AbstractResourceRepository,
16
+ AbstractUpdateHandler,
17
+ RepositoryContext,
18
+ UpdateHandlerInterface,
19
+ } from "./abstract";
14
20
 
15
- export class ZoneRepository extends AbstractResourceRepository<'zone'> {
16
- getTypeId() {
17
- return 'zone' as const
21
+ export class ZoneRepository extends AbstractResourceRepository<"zone"> {
22
+ constructor(storage: AbstractStorage) {
23
+ super("zone", storage);
24
+ this.actions = new ZoneUpdateHandler(storage);
18
25
  }
19
26
 
20
27
  create(context: RepositoryContext, draft: ZoneDraft): Zone {
@@ -24,58 +31,55 @@ export class ZoneRepository extends AbstractResourceRepository<'zone'> {
24
31
  locations: draft.locations || [],
25
32
  name: draft.name,
26
33
  description: draft.description,
27
- }
28
- this.saveNew(context, resource)
29
- return resource
34
+ };
35
+ return this.saveNew(context, resource);
36
+ }
37
+ }
38
+
39
+ class ZoneUpdateHandler
40
+ extends AbstractUpdateHandler
41
+ implements Partial<UpdateHandlerInterface<Zone, ZoneUpdateAction>>
42
+ {
43
+ addLocation(
44
+ context: RepositoryContext,
45
+ resource: Writable<Zone>,
46
+ { location }: ZoneAddLocationAction,
47
+ ) {
48
+ resource.locations.push(location);
49
+ }
50
+
51
+ changeName(
52
+ context: RepositoryContext,
53
+ resource: Writable<Zone>,
54
+ { name }: ZoneChangeNameAction,
55
+ ) {
56
+ resource.name = name;
57
+ }
58
+
59
+ removeLocation(
60
+ context: RepositoryContext,
61
+ resource: Writable<Zone>,
62
+ { location }: ZoneRemoveLocationAction,
63
+ ) {
64
+ resource.locations = resource.locations.filter(
65
+ (loc) =>
66
+ !(loc.country === location.country && loc.state === location.state),
67
+ );
68
+ }
69
+
70
+ setDescription(
71
+ context: RepositoryContext,
72
+ resource: Writable<Zone>,
73
+ { description }: ZoneSetDescriptionAction,
74
+ ) {
75
+ resource.description = description;
30
76
  }
31
77
 
32
- actions: Partial<
33
- Record<
34
- ZoneUpdateAction['action'],
35
- (
36
- context: RepositoryContext,
37
- resource: Writable<Zone>,
38
- action: any
39
- ) => void
40
- >
41
- > = {
42
- addLocation: (
43
- context: RepositoryContext,
44
- resource: Writable<Zone>,
45
- { location }: ZoneAddLocationAction
46
- ) => {
47
- resource.locations.push(location)
48
- },
49
- removeLocation: (
50
- context: RepositoryContext,
51
- resource: Writable<Zone>,
52
- { location }: ZoneRemoveLocationAction
53
- ) => {
54
- resource.locations = resource.locations.filter(
55
- (loc) =>
56
- !(loc.country === location.country && loc.state === location.state)
57
- )
58
- },
59
- changeName: (
60
- context: RepositoryContext,
61
- resource: Writable<Zone>,
62
- { name }: ZoneChangeNameAction
63
- ) => {
64
- resource.name = name
65
- },
66
- setDescription: (
67
- context: RepositoryContext,
68
- resource: Writable<Zone>,
69
- { description }: ZoneSetDescriptionAction
70
- ) => {
71
- resource.description = description
72
- },
73
- setKey: (
74
- context: RepositoryContext,
75
- resource: Writable<Zone>,
76
- { key }: ZoneSetKeyAction
77
- ) => {
78
- resource.key = key
79
- },
78
+ setKey(
79
+ context: RepositoryContext,
80
+ resource: Writable<Zone>,
81
+ { key }: ZoneSetKeyAction,
82
+ ) {
83
+ resource.key = key;
80
84
  }
81
85
  }
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+
3
+ const UpdateActionSchema = z
4
+ .object({
5
+ action: z.string(),
6
+ })
7
+ .passthrough();
8
+
9
+ export const updateRequestSchema = z.object({
10
+ version: z.number(),
11
+ actions: z.array(UpdateActionSchema),
12
+ });
package/src/server.ts CHANGED
@@ -1,14 +1,14 @@
1
- import { CommercetoolsMock } from './index.js'
1
+ import { CommercetoolsMock } from "./index";
2
2
 
3
- process.on('SIGINT', function () {
4
- console.info('Stopping server...')
5
- process.exit()
6
- })
3
+ process.on("SIGINT", function () {
4
+ console.info("Stopping server...");
5
+ process.exit();
6
+ });
7
7
 
8
- const instance = new CommercetoolsMock()
8
+ const instance = new CommercetoolsMock();
9
9
 
10
- let port = 3000
10
+ let port = 3000;
11
11
 
12
- if (process.env.HTTP_SERVER_PORT) port = parseInt(process.env.HTTP_SERVER_PORT)
12
+ if (process.env.HTTP_SERVER_PORT) port = parseInt(process.env.HTTP_SERVER_PORT);
13
13
 
14
- instance.runServer(port)
14
+ instance.runServer(port);
@@ -1,95 +1,100 @@
1
- import type { Update } from '@commercetools/platform-sdk'
2
- import { type Request, type Response, Router } from 'express'
3
- import { ParsedQs } from 'qs'
4
- import { AbstractResourceRepository } from '../repositories/abstract.js'
5
- import { getRepositoryContext } from '../repositories/helpers.js'
6
- import { queryParamsArray } from '../helpers.js'
1
+ import type { Update } from "@commercetools/platform-sdk";
2
+ import { Router, type Request, type Response } from "express";
3
+ import { ParsedQs } from "qs";
4
+ import { updateRequestSchema } from "~src/schemas/update-request";
5
+ import { validateData } from "~src/validate";
6
+ import { queryParamsArray } from "../helpers";
7
+ import { AbstractResourceRepository } from "../repositories/abstract";
8
+ import { getRepositoryContext } from "../repositories/helpers";
7
9
 
8
10
  export default abstract class AbstractService {
9
- protected abstract getBasePath(): string
10
- public abstract repository: AbstractResourceRepository<any>
11
+ public abstract repository: AbstractResourceRepository<any>;
11
12
 
12
- createStatusCode = 201
13
+ createStatusCode = 201;
13
14
 
14
15
  constructor(parent: Router) {
15
- this.registerRoutes(parent)
16
+ this.registerRoutes(parent);
16
17
  }
17
18
 
19
+ protected abstract getBasePath(): string;
20
+
18
21
  extraRoutes(router: Router) {}
19
22
 
20
23
  registerRoutes(parent: Router) {
21
- const basePath = this.getBasePath()
22
- const router = Router({ mergeParams: true })
24
+ const basePath = this.getBasePath();
25
+ const router = Router({ mergeParams: true });
23
26
 
24
27
  // Bind this first since the `/:id` routes are currently a bit to greedy
25
- this.extraRoutes(router)
28
+ this.extraRoutes(router);
26
29
 
27
- router.get('/', this.get.bind(this))
28
- router.get('/key=:key', this.getWithKey.bind(this)) // same thing goes for the key routes
29
- router.get('/:id', this.getWithId.bind(this))
30
+ router.get("/", this.get.bind(this));
31
+ router.get("/key=:key", this.getWithKey.bind(this)); // same thing goes for the key routes
32
+ router.get("/:id", this.getWithId.bind(this));
30
33
 
31
- router.delete('/key=:key', this.deleteWithKey.bind(this))
32
- router.delete('/:id', this.deleteWithId.bind(this))
34
+ router.delete("/key=:key", this.deleteWithKey.bind(this));
35
+ router.delete("/:id", this.deleteWithId.bind(this));
33
36
 
34
- router.post('/', this.post.bind(this))
35
- router.post('/key=:key', this.postWithKey.bind(this))
36
- router.post('/:id', this.postWithId.bind(this))
37
+ router.post("/", this.post.bind(this));
38
+ router.post("/key=:key", this.postWithKey.bind(this));
39
+ router.post("/:id", this.postWithId.bind(this));
37
40
 
38
- parent.use(`/${basePath}`, router)
41
+ parent.use(`/${basePath}`, router);
39
42
  }
40
43
 
41
44
  get(request: Request, response: Response) {
42
- const limit = this._parseParam(request.query.limit)
43
- const offset = this._parseParam(request.query.offset)
45
+ const limit = this._parseParam(request.query.limit);
46
+ const offset = this._parseParam(request.query.offset);
44
47
 
45
48
  const result = this.repository.query(getRepositoryContext(request), {
46
49
  expand: this._parseParam(request.query.expand),
47
50
  where: this._parseParam(request.query.where),
48
51
  limit: limit !== undefined ? Number(limit) : undefined,
49
52
  offset: offset !== undefined ? Number(offset) : undefined,
50
- })
51
- return response.status(200).send(result)
53
+ });
54
+ return response.status(200).send(result);
52
55
  }
53
56
 
54
57
  getWithId(request: Request, response: Response) {
55
- const result = this._expandWithId(request, request.params['id'])
58
+ const result = this._expandWithId(request, request.params["id"]);
56
59
  if (!result) {
57
- return response.status(404).send()
60
+ return response.status(404).send();
58
61
  }
59
- return response.status(200).send(result)
62
+ return response.status(200).send(result);
60
63
  }
61
64
 
62
65
  getWithKey(request: Request, response: Response) {
63
66
  const result = this.repository.getByKey(
64
67
  getRepositoryContext(request),
65
- request.params['key'],
66
- { expand: this._parseParam(request.query.expand) }
67
- )
68
- if (!result) return response.status(404).send()
69
- return response.status(200).send(result)
68
+ request.params["key"],
69
+ {
70
+ expand: this._parseParam(request.query.expand),
71
+ },
72
+ );
73
+ if (!result) return response.status(404).send();
74
+ return response.status(200).send(result);
70
75
  }
71
76
 
72
77
  deleteWithId(request: Request, response: Response) {
73
78
  const result = this.repository.delete(
74
79
  getRepositoryContext(request),
75
- request.params['id'],
80
+ request.params["id"],
76
81
  {
77
82
  expand: this._parseParam(request.query.expand),
78
- }
79
- )
83
+ },
84
+ );
80
85
  if (!result) {
81
- return response.status(404).send('Not found')
86
+ return response.status(404).send("Not found");
82
87
  }
83
- return response.status(200).send(result)
88
+ return response.status(200).send(result);
84
89
  }
85
90
 
86
91
  deleteWithKey(request: Request, response: Response) {
87
92
  const resource = this.repository.getByKey(
88
93
  getRepositoryContext(request),
89
- request.params['key']
90
- )
94
+ request.params["key"],
95
+ );
91
96
  if (!resource) {
92
- return response.status(404).send('Not found')
97
+ return response.status(404).send("Not found");
93
98
  }
94
99
 
95
100
  const result = this.repository.delete(
@@ -97,63 +102,71 @@ export default abstract class AbstractService {
97
102
  resource.id,
98
103
  {
99
104
  expand: this._parseParam(request.query.expand),
100
- }
101
- )
105
+ },
106
+ );
102
107
  if (!result) {
103
- return response.status(404).send('Not found')
108
+ return response.status(404).send("Not found");
104
109
  }
105
- return response.status(200).send(result)
110
+ return response.status(200).send(result);
106
111
  }
107
112
 
108
113
  post(request: Request, response: Response) {
109
- const draft = request.body
114
+ const draft = request.body;
110
115
  const resource = this.repository.create(
111
116
  getRepositoryContext(request),
112
- draft
113
- )
114
- const result = this._expandWithId(request, resource.id)
115
- return response.status(this.createStatusCode).send(result)
117
+ draft,
118
+ );
119
+ const result = this._expandWithId(request, resource.id);
120
+ return response.status(this.createStatusCode).send(result);
116
121
  }
117
122
 
118
123
  postWithId(request: Request, response: Response) {
119
- const updateRequest: Update = request.body
124
+ const updateRequest = validateData<Update>(
125
+ request.body,
126
+ updateRequestSchema,
127
+ );
120
128
  const resource = this.repository.get(
121
129
  getRepositoryContext(request),
122
- request.params['id']
123
- )
130
+ request.params["id"],
131
+ );
124
132
  if (!resource) {
125
- return response.status(404).send('Not found')
133
+ return response.status(404).send("Not found");
126
134
  }
127
135
 
128
136
  const updatedResource = this.repository.processUpdateActions(
129
137
  getRepositoryContext(request),
130
138
  resource,
131
139
  updateRequest.version,
132
- updateRequest.actions
133
- )
140
+ updateRequest.actions,
141
+ );
134
142
 
135
- const result = this._expandWithId(request, updatedResource.id)
136
- return response.status(200).send(result)
143
+ const result = this._expandWithId(request, updatedResource.id);
144
+ return response.status(200).send(result);
137
145
  }
138
146
 
139
147
  postWithKey(request: Request, response: Response) {
140
- const updateRequest: Update = request.body
148
+ const updateRequest = validateData<Update>(
149
+ request.body,
150
+ updateRequestSchema,
151
+ );
152
+
141
153
  const resource = this.repository.getByKey(
142
154
  getRepositoryContext(request),
143
- request.params['key']
144
- )
155
+ request.params["key"],
156
+ );
145
157
  if (!resource) {
146
- return response.status(404).send('Not found')
158
+ return response.status(404).send("Not found");
147
159
  }
160
+
148
161
  const updatedResource = this.repository.processUpdateActions(
149
162
  getRepositoryContext(request),
150
163
  resource,
151
164
  updateRequest.version,
152
- updateRequest.actions
153
- )
165
+ updateRequest.actions,
166
+ );
154
167
 
155
- const result = this._expandWithId(request, updatedResource.id)
156
- return response.status(200).send(result)
168
+ const result = this._expandWithId(request, updatedResource.id);
169
+ return response.status(200).send(result);
157
170
  }
158
171
 
159
172
  protected _expandWithId(request: Request, resourceId: string) {
@@ -162,15 +175,15 @@ export default abstract class AbstractService {
162
175
  resourceId,
163
176
  {
164
177
  expand: this._parseParam(request.query.expand),
165
- }
166
- )
167
- return result
178
+ },
179
+ );
180
+ return result;
168
181
  }
169
182
 
170
183
  // No idea what i'm doing
171
184
  protected _parseParam(
172
- value: string | ParsedQs | string[] | ParsedQs[] | undefined
185
+ value: string | ParsedQs | string[] | ParsedQs[] | undefined,
173
186
  ): string[] | undefined {
174
- return queryParamsArray(value)
187
+ return queryParamsArray(value);
175
188
  }
176
189
  }