@labdigital/commercetools-mock 2.17.0 → 2.18.0
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.
- package/dist/index.cjs +4219 -3989
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +268 -415
- package/dist/index.d.ts +268 -415
- package/dist/index.js +4219 -3989
- package/dist/index.js.map +1 -1
- package/package.json +44 -46
- package/src/constants.ts +2 -2
- package/src/ctMock.test.ts +11 -11
- package/src/ctMock.ts +141 -127
- package/src/deprecation.ts +8 -0
- package/src/exceptions.ts +17 -15
- package/src/helpers.ts +32 -32
- package/src/index.test.ts +128 -128
- package/src/index.ts +3 -3
- package/src/lib/expandParser.ts +13 -13
- package/src/lib/haversine.test.ts +9 -9
- package/src/lib/haversine.ts +11 -11
- package/src/lib/masking.ts +11 -11
- package/src/lib/parser.ts +2 -2
- package/src/lib/password.ts +23 -3
- package/src/lib/predicateParser.test.ts +185 -183
- package/src/lib/predicateParser.ts +234 -234
- package/src/lib/projectionSearchFilter.test.ts +103 -101
- package/src/lib/projectionSearchFilter.ts +152 -150
- package/src/lib/proxy.ts +5 -5
- package/src/oauth/errors.ts +4 -4
- package/src/oauth/helpers.ts +6 -6
- package/src/oauth/server.test.ts +110 -67
- package/src/oauth/server.ts +161 -141
- package/src/oauth/store.ts +49 -44
- package/src/priceSelector.test.ts +35 -35
- package/src/priceSelector.ts +30 -30
- package/src/product-projection-search.ts +136 -134
- package/src/projectAPI.test.ts +7 -7
- package/src/projectAPI.ts +24 -22
- package/src/repositories/abstract.ts +168 -116
- package/src/repositories/associate-role.ts +90 -77
- package/src/repositories/attribute-group.ts +51 -40
- package/src/repositories/business-unit.ts +168 -148
- package/src/repositories/cart/actions.ts +489 -0
- package/src/repositories/cart/helpers.ts +30 -0
- package/src/repositories/cart/index.ts +180 -0
- package/src/repositories/cart-discount/actions.ts +148 -0
- package/src/repositories/cart-discount/index.ts +86 -0
- package/src/repositories/category/actions.ts +231 -0
- package/src/repositories/category/index.ts +52 -0
- package/src/repositories/channel.ts +88 -90
- package/src/repositories/custom-object.ts +46 -45
- package/src/repositories/customer/actions.ts +165 -0
- package/src/repositories/customer/index.ts +79 -0
- package/src/repositories/customer-group.ts +66 -55
- package/src/repositories/discount-code/actions.ts +149 -0
- package/src/repositories/discount-code/index.ts +50 -0
- package/src/repositories/errors.ts +10 -10
- package/src/repositories/extension.ts +64 -62
- package/src/repositories/helpers.ts +117 -118
- package/src/repositories/index.ts +80 -79
- package/src/repositories/inventory-entry/actions.ts +84 -0
- package/src/repositories/inventory-entry/index.ts +44 -0
- package/src/repositories/my-customer.ts +114 -0
- package/src/repositories/my-order.ts +8 -8
- package/src/repositories/order/actions.ts +281 -0
- package/src/repositories/{order.test.ts → order/index.test.ts} +77 -77
- package/src/repositories/order/index.ts +260 -0
- package/src/repositories/order-edit.ts +10 -23
- package/src/repositories/payment/actions.ts +305 -0
- package/src/repositories/payment/helpers.ts +17 -0
- package/src/repositories/payment/index.ts +56 -0
- package/src/repositories/product/actions.ts +943 -0
- package/src/repositories/product/helpers.ts +98 -0
- package/src/repositories/product/index.ts +130 -0
- package/src/repositories/product-discount.ts +127 -117
- package/src/repositories/product-projection.ts +56 -62
- package/src/repositories/product-selection.ts +31 -28
- package/src/repositories/product-type.ts +136 -134
- package/src/repositories/project.ts +133 -118
- package/src/repositories/quote-request.ts +7 -19
- package/src/repositories/quote.ts +7 -22
- package/src/repositories/review.ts +13 -26
- package/src/repositories/shipping-method/actions.ts +198 -0
- package/src/repositories/shipping-method/helpers.ts +10 -0
- package/src/repositories/shipping-method/index.ts +138 -0
- package/src/repositories/shopping-list/actions.ts +295 -0
- package/src/repositories/shopping-list/index.ts +122 -0
- package/src/repositories/staged-quote.ts +7 -20
- package/src/repositories/standalone-price.ts +57 -44
- package/src/repositories/state.ts +113 -68
- package/src/repositories/store.ts +106 -94
- package/src/repositories/subscription.ts +46 -22
- package/src/repositories/tax-category/actions.ts +94 -0
- package/src/repositories/tax-category/helpers.ts +8 -0
- package/src/repositories/tax-category/index.ts +25 -0
- package/src/repositories/type/actions.ts +162 -0
- package/src/repositories/type/index.ts +24 -0
- package/src/repositories/zone.ts +62 -58
- package/src/server.ts +9 -9
- package/src/services/abstract.ts +75 -72
- package/src/services/associate-roles.test.ts +27 -27
- package/src/services/associate-roles.ts +7 -7
- package/src/services/attribute-group.ts +7 -7
- package/src/services/business-units.test.ts +28 -28
- package/src/services/business-units.ts +7 -7
- package/src/services/cart-discount.test.ts +199 -199
- package/src/services/cart-discount.ts +7 -7
- package/src/services/cart.test.ts +261 -261
- package/src/services/cart.ts +22 -21
- package/src/services/category.test.ts +121 -121
- package/src/services/category.ts +7 -7
- package/src/services/channel.ts +7 -7
- package/src/services/custom-object.test.ts +130 -130
- package/src/services/custom-object.ts +34 -31
- package/src/services/customer-group.ts +7 -7
- package/src/services/customer.test.ts +205 -205
- package/src/services/customer.ts +31 -29
- package/src/services/discount-code.ts +7 -7
- package/src/services/extension.ts +7 -7
- package/src/services/index.ts +85 -81
- package/src/services/inventory-entry.test.ts +106 -106
- package/src/services/inventory-entry.ts +7 -7
- package/src/services/my-cart.test.ts +56 -56
- package/src/services/my-cart.ts +20 -20
- package/src/services/my-customer.test.ts +155 -104
- package/src/services/my-customer.ts +61 -75
- package/src/services/my-order.ts +16 -16
- package/src/services/my-payment.test.ts +40 -40
- package/src/services/my-payment.ts +7 -7
- package/src/services/my-shopping-list.ts +7 -7
- package/src/services/order.test.ts +243 -243
- package/src/services/order.ts +23 -18
- package/src/services/payment.test.ts +40 -40
- package/src/services/payment.ts +7 -7
- package/src/services/product-discount.ts +7 -7
- package/src/services/product-projection.test.ts +190 -190
- package/src/services/product-projection.ts +34 -32
- package/src/services/product-selection.test.ts +19 -19
- package/src/services/product-selection.ts +7 -7
- package/src/services/product-type.test.ts +38 -38
- package/src/services/product-type.ts +7 -7
- package/src/services/product.test.ts +658 -656
- package/src/services/product.ts +7 -7
- package/src/services/project.test.ts +24 -24
- package/src/services/project.ts +17 -17
- package/src/services/reviews.ts +7 -7
- package/src/services/shipping-method.test.ts +78 -78
- package/src/services/shipping-method.ts +16 -16
- package/src/services/shopping-list.test.ts +170 -170
- package/src/services/shopping-list.ts +7 -7
- package/src/services/standalone-price.test.ts +112 -112
- package/src/services/standalone-price.ts +7 -7
- package/src/services/state.test.ts +30 -30
- package/src/services/state.ts +7 -7
- package/src/services/store.test.ts +40 -40
- package/src/services/store.ts +7 -7
- package/src/services/subscription.ts +7 -7
- package/src/services/tax-category.test.ts +43 -43
- package/src/services/tax-category.ts +7 -7
- package/src/services/type.ts +7 -7
- package/src/services/zone.ts +7 -7
- package/src/shippingCalculator.test.ts +43 -43
- package/src/shippingCalculator.ts +23 -23
- package/src/storage/abstract.ts +36 -34
- package/src/storage/in-memory.ts +237 -233
- package/src/storage/index.ts +2 -2
- package/src/types.ts +91 -91
- package/src/repositories/cart-discount.ts +0 -219
- package/src/repositories/cart.ts +0 -659
- package/src/repositories/category.ts +0 -256
- package/src/repositories/customer.ts +0 -228
- package/src/repositories/discount-code.ts +0 -181
- package/src/repositories/inventory-entry.ts +0 -109
- package/src/repositories/order.ts +0 -514
- package/src/repositories/payment.ts +0 -342
- package/src/repositories/product.ts +0 -1106
- package/src/repositories/shipping-method.ts +0 -312
- package/src/repositories/shopping-list.ts +0 -392
- package/src/repositories/tax-category.ts +0 -111
- package/src/repositories/type.ts +0 -172
package/package.json
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@labdigital/commercetools-mock",
|
|
3
|
-
"
|
|
4
|
-
"version": "2.17.0",
|
|
3
|
+
"version": "2.18.0",
|
|
5
4
|
"license": "MIT",
|
|
6
|
-
"
|
|
7
|
-
"module": "dist/index.js",
|
|
5
|
+
"author": "Michael van Tellingen",
|
|
8
6
|
"type": "module",
|
|
9
|
-
"typings": "dist/index.d.ts",
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"src"
|
|
13
|
-
],
|
|
14
7
|
"exports": {
|
|
15
8
|
".": {
|
|
16
9
|
"require": "./dist/index.cjs",
|
|
@@ -18,72 +11,77 @@
|
|
|
18
11
|
"types": "./dist/index.d.ts"
|
|
19
12
|
}
|
|
20
13
|
},
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
"prettier": {
|
|
30
|
-
"printWidth": 80,
|
|
31
|
-
"semi": false,
|
|
32
|
-
"singleQuote": true,
|
|
33
|
-
"trailingComma": "es5"
|
|
34
|
-
},
|
|
14
|
+
"main": "dist/index.cjs",
|
|
15
|
+
"module": "dist/index.js",
|
|
16
|
+
"typings": "dist/index.d.ts",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"src"
|
|
20
|
+
],
|
|
35
21
|
"dependencies": {
|
|
36
22
|
"basic-auth": "^2.0.1",
|
|
37
23
|
"body-parser": "^1.20.2",
|
|
38
24
|
"deep-equal": "^2.2.3",
|
|
39
25
|
"express": "^4.18.2",
|
|
40
|
-
"light-my-request": "^5.11.
|
|
26
|
+
"light-my-request": "^5.11.1",
|
|
41
27
|
"lodash.isequal": "^4.5.0",
|
|
42
28
|
"morgan": "^1.10.0",
|
|
43
|
-
"msw": "^2.1
|
|
29
|
+
"msw": "^2.2.1",
|
|
44
30
|
"uuid": "^9.0.1"
|
|
45
31
|
},
|
|
46
32
|
"devDependencies": {
|
|
47
33
|
"@changesets/changelog-github": "^0.5.0",
|
|
48
34
|
"@changesets/cli": "^2.27.1",
|
|
49
|
-
"@commercetools/platform-sdk": "7.
|
|
50
|
-
"@
|
|
35
|
+
"@commercetools/platform-sdk": "7.3.0",
|
|
36
|
+
"@stylistic/eslint-plugin": "^1.6.2",
|
|
37
|
+
"@types/basic-auth": "^1.1.8",
|
|
51
38
|
"@types/body-parser": "^1.19.5",
|
|
52
39
|
"@types/deep-equal": "^1.0.4",
|
|
53
40
|
"@types/express": "^4.17.21",
|
|
54
|
-
"@types/express-serve-static-core": "^4.17.
|
|
41
|
+
"@types/express-serve-static-core": "^4.17.43",
|
|
55
42
|
"@types/lodash.isequal": "^4.5.8",
|
|
56
43
|
"@types/morgan": "^1.9.9",
|
|
57
|
-
"@types/node": "^20.11.
|
|
44
|
+
"@types/node": "^20.11.20",
|
|
58
45
|
"@types/qs": "^6.9.11",
|
|
59
46
|
"@types/supertest": "^6.0.2",
|
|
60
|
-
"@types/uuid": "^9.0.
|
|
61
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
62
|
-
"@typescript-eslint/parser": "^
|
|
63
|
-
"@vitest/coverage-v8": "^1.
|
|
64
|
-
"esbuild": "^0.
|
|
65
|
-
"eslint": "^8.
|
|
66
|
-
"eslint-plugin-
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
47
|
+
"@types/uuid": "^9.0.8",
|
|
48
|
+
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
|
49
|
+
"@typescript-eslint/parser": "^7.0.2",
|
|
50
|
+
"@vitest/coverage-v8": "^1.3.1",
|
|
51
|
+
"esbuild": "^0.20.1",
|
|
52
|
+
"eslint": "^8.57.0",
|
|
53
|
+
"eslint-plugin-sort-class-members": "^1.20.0",
|
|
54
|
+
"eslint-plugin-unused-imports": "^3.1.0",
|
|
55
|
+
"got": "^14.2.0",
|
|
56
|
+
"husky": "^9.0.11",
|
|
57
|
+
"prettier": "^3.2.5",
|
|
58
|
+
"prettier-plugin-organize-imports": "^3.2.4",
|
|
59
|
+
"prettier-plugin-packagejson": "^2.4.12",
|
|
70
60
|
"supertest": "^6.3.4",
|
|
71
61
|
"timekeeper": "^2.3.1",
|
|
72
62
|
"ts-node": "^10.9.2",
|
|
73
63
|
"tslib": "^2.6.2",
|
|
74
|
-
"tsup": "^8.0.
|
|
64
|
+
"tsup": "^8.0.2",
|
|
75
65
|
"typescript": "^5.3.3",
|
|
76
|
-
"vitest": "^1.
|
|
66
|
+
"vitest": "^1.3.1"
|
|
67
|
+
},
|
|
68
|
+
"packageManager": "pnpm@8.6.5",
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=18",
|
|
71
|
+
"pnpm": ">=8.6.5"
|
|
72
|
+
},
|
|
73
|
+
"publishConfig": {
|
|
74
|
+
"access": "public"
|
|
77
75
|
},
|
|
78
76
|
"scripts": {
|
|
79
|
-
"start": "tsup src/server.ts --watch --onSuccess 'node dist/server.js'",
|
|
80
77
|
"build": "tsup",
|
|
81
78
|
"build:server": "esbuild src/server.ts --bundle --outfile=dist/server.js --platform=node",
|
|
82
|
-
"publish:ci": "pnpm build && pnpm changeset publish",
|
|
83
|
-
"test": "vitest run",
|
|
84
|
-
"test:ci": "vitest run --coverage",
|
|
85
79
|
"check": "pnpm lint && tsc",
|
|
86
80
|
"format": "eslint src --fix ; prettier --write .",
|
|
87
|
-
"lint": "eslint src && prettier --check ."
|
|
81
|
+
"lint": "eslint src && prettier --check .",
|
|
82
|
+
"publish:ci": "pnpm build && pnpm changeset publish",
|
|
83
|
+
"start": "tsup src/server.ts --watch --onSuccess 'node dist/server'",
|
|
84
|
+
"test": "vitest run",
|
|
85
|
+
"test:ci": "vitest run --coverage"
|
|
88
86
|
}
|
|
89
87
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const DEFAULT_API_HOSTNAME =
|
|
2
|
-
export const DEFAULT_AUTH_HOSTNAME =
|
|
1
|
+
export const DEFAULT_API_HOSTNAME = "https://api.*.commercetools.com";
|
|
2
|
+
export const DEFAULT_AUTH_HOSTNAME = "https://auth.*.commercetools.com";
|
package/src/ctMock.test.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { test } from "vitest";
|
|
2
|
+
import { CommercetoolsMock } from "./index";
|
|
3
3
|
|
|
4
|
-
test(
|
|
4
|
+
test("ctMock.authServer", async () => {
|
|
5
5
|
const ctMock = new CommercetoolsMock({
|
|
6
6
|
enableAuthentication: false,
|
|
7
7
|
validateCredentials: false,
|
|
8
|
-
apiHost:
|
|
9
|
-
})
|
|
8
|
+
apiHost: "http://api.localhost",
|
|
9
|
+
});
|
|
10
10
|
|
|
11
11
|
ctMock.authStore().addToken({
|
|
12
|
-
token_type:
|
|
13
|
-
access_token:
|
|
12
|
+
token_type: "Bearer",
|
|
13
|
+
access_token: "foobar",
|
|
14
14
|
expires_in: 172800,
|
|
15
|
-
scope:
|
|
16
|
-
refresh_token:
|
|
17
|
-
})
|
|
18
|
-
})
|
|
15
|
+
scope: "my-project",
|
|
16
|
+
refresh_token: "foobar",
|
|
17
|
+
});
|
|
18
|
+
});
|
package/src/ctMock.ts
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
import express, { NextFunction, Request, Response } from
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { OAuth2Server } from
|
|
10
|
-
import { ProjectAPI } from
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
1
|
+
import express, { NextFunction, Request, Response } from "express";
|
|
2
|
+
import inject from "light-my-request";
|
|
3
|
+
import morgan from "morgan";
|
|
4
|
+
import { http, HttpResponse } from "msw";
|
|
5
|
+
import { setupServer, SetupServer } from "msw/node";
|
|
6
|
+
import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from "./constants";
|
|
7
|
+
import { CommercetoolsError } from "./exceptions";
|
|
8
|
+
import { copyHeaders } from "./lib/proxy";
|
|
9
|
+
import { OAuth2Server } from "./oauth/server";
|
|
10
|
+
import { ProjectAPI } from "./projectAPI";
|
|
11
|
+
import { AbstractStorage, InMemoryStorage } from "./storage";
|
|
12
|
+
import { Services } from "./types";
|
|
13
13
|
|
|
14
14
|
// Services
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { ProjectRepository } from
|
|
19
|
-
import {
|
|
15
|
+
import { warnDeprecation } from "./deprecation";
|
|
16
|
+
import { mapHeaderType } from "./helpers";
|
|
17
|
+
import { createRepositories, RepositoryMap } from "./repositories";
|
|
18
|
+
import { ProjectRepository } from "./repositories/project";
|
|
19
|
+
import { createServices } from "./services";
|
|
20
|
+
import { ProjectService } from "./services/project";
|
|
20
21
|
|
|
21
22
|
export type CommercetoolsMockOptions = {
|
|
22
|
-
validateCredentials: boolean
|
|
23
|
-
enableAuthentication: boolean
|
|
24
|
-
defaultProjectKey: string | undefined
|
|
25
|
-
apiHost: RegExp | string
|
|
26
|
-
authHost: RegExp | string
|
|
27
|
-
silent: boolean
|
|
28
|
-
}
|
|
23
|
+
validateCredentials: boolean;
|
|
24
|
+
enableAuthentication: boolean;
|
|
25
|
+
defaultProjectKey: string | undefined;
|
|
26
|
+
apiHost: RegExp | string;
|
|
27
|
+
authHost: RegExp | string;
|
|
28
|
+
silent: boolean;
|
|
29
|
+
};
|
|
29
30
|
|
|
30
|
-
type AppOptions = { silent?: boolean }
|
|
31
|
+
type AppOptions = { silent?: boolean };
|
|
31
32
|
|
|
32
33
|
const DEFAULT_OPTIONS: CommercetoolsMockOptions = {
|
|
33
34
|
enableAuthentication: false,
|
|
@@ -36,111 +37,124 @@ const DEFAULT_OPTIONS: CommercetoolsMockOptions = {
|
|
|
36
37
|
apiHost: DEFAULT_API_HOSTNAME,
|
|
37
38
|
authHost: DEFAULT_AUTH_HOSTNAME,
|
|
38
39
|
silent: false,
|
|
39
|
-
}
|
|
40
|
+
};
|
|
40
41
|
|
|
41
|
-
const _globalListeners: SetupServer[] = []
|
|
42
|
+
const _globalListeners: SetupServer[] = [];
|
|
42
43
|
|
|
43
44
|
export class CommercetoolsMock {
|
|
44
|
-
public app: express.Express
|
|
45
|
-
|
|
45
|
+
public app: express.Express;
|
|
46
|
+
|
|
47
|
+
public options: CommercetoolsMockOptions;
|
|
48
|
+
|
|
49
|
+
private _storage: AbstractStorage;
|
|
50
|
+
|
|
51
|
+
private _oauth2: OAuth2Server;
|
|
46
52
|
|
|
47
|
-
private
|
|
48
|
-
|
|
49
|
-
private
|
|
50
|
-
|
|
51
|
-
private _repositories: RepositoryMap | null
|
|
52
|
-
|
|
53
|
+
private _mswServer: SetupServer | undefined = undefined;
|
|
54
|
+
|
|
55
|
+
private _services: Services | null;
|
|
56
|
+
|
|
57
|
+
private _repositories: RepositoryMap | null;
|
|
58
|
+
|
|
59
|
+
private _projectService?: ProjectService;
|
|
53
60
|
|
|
54
61
|
constructor(options: Partial<CommercetoolsMockOptions> = {}) {
|
|
55
|
-
this.options = { ...DEFAULT_OPTIONS, ...options }
|
|
56
|
-
this._services = null
|
|
57
|
-
this._repositories = null
|
|
58
|
-
this._projectService = undefined
|
|
62
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
63
|
+
this._services = null;
|
|
64
|
+
this._repositories = null;
|
|
65
|
+
this._projectService = undefined;
|
|
59
66
|
|
|
60
|
-
this._storage = new InMemoryStorage()
|
|
67
|
+
this._storage = new InMemoryStorage();
|
|
61
68
|
this._oauth2 = new OAuth2Server({
|
|
62
69
|
enabled: this.options.enableAuthentication,
|
|
63
70
|
validate: this.options.validateCredentials,
|
|
64
|
-
})
|
|
71
|
+
});
|
|
65
72
|
|
|
66
|
-
this.app = this.createApp({ silent: this.options.silent })
|
|
73
|
+
this.app = this.createApp({ silent: this.options.silent });
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
start() {
|
|
77
|
+
warnDeprecation(
|
|
78
|
+
"The start method is deprecated, use .registerHandlers() to bind to an msw server instead",
|
|
79
|
+
);
|
|
80
|
+
|
|
70
81
|
// Order is important here when the hostnames match
|
|
71
|
-
this.clear()
|
|
72
|
-
this.startServer()
|
|
82
|
+
this.clear();
|
|
83
|
+
this.startServer();
|
|
73
84
|
}
|
|
74
85
|
|
|
75
86
|
stop() {
|
|
76
|
-
|
|
77
|
-
|
|
87
|
+
warnDeprecation(
|
|
88
|
+
"The stop method is deprecated, use .registerHandlers() to bind to an msw server instead",
|
|
89
|
+
);
|
|
90
|
+
this._mswServer?.close();
|
|
91
|
+
this._mswServer = undefined;
|
|
78
92
|
}
|
|
79
93
|
|
|
80
94
|
clear() {
|
|
81
|
-
this._storage.clear()
|
|
95
|
+
this._storage.clear();
|
|
82
96
|
}
|
|
83
97
|
|
|
84
98
|
project(projectKey?: string) {
|
|
85
99
|
if (!projectKey && !this.options.defaultProjectKey) {
|
|
86
|
-
throw new Error(
|
|
100
|
+
throw new Error("No projectKey passed and no default set");
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
if (this._repositories === null) {
|
|
90
|
-
throw new Error(
|
|
104
|
+
throw new Error("repositories not initialized yet");
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
return new ProjectAPI(
|
|
94
108
|
projectKey || this.options.defaultProjectKey!,
|
|
95
109
|
this._repositories,
|
|
96
|
-
this._storage
|
|
97
|
-
)
|
|
110
|
+
this._storage,
|
|
111
|
+
);
|
|
98
112
|
}
|
|
99
113
|
|
|
100
114
|
authStore() {
|
|
101
|
-
return this._oauth2.store
|
|
115
|
+
return this._oauth2.store;
|
|
102
116
|
}
|
|
103
117
|
|
|
104
118
|
runServer(port = 3000, options?: AppOptions) {
|
|
105
119
|
const server = this.app.listen(port, () => {
|
|
106
|
-
console.info(`Mock server listening at http://localhost:${port}`)
|
|
107
|
-
})
|
|
108
|
-
server.keepAliveTimeout = 60 * 1000
|
|
120
|
+
console.info(`Mock server listening at http://localhost:${port}`);
|
|
121
|
+
});
|
|
122
|
+
server.keepAliveTimeout = 60 * 1000;
|
|
109
123
|
}
|
|
110
124
|
|
|
111
125
|
private createApp(options?: AppOptions): express.Express {
|
|
112
|
-
this._repositories = createRepositories(this._storage)
|
|
113
|
-
this._oauth2.setCustomerRepository(this._repositories.customer)
|
|
126
|
+
this._repositories = createRepositories(this._storage);
|
|
127
|
+
this._oauth2.setCustomerRepository(this._repositories.customer);
|
|
114
128
|
|
|
115
|
-
const app = express()
|
|
129
|
+
const app = express();
|
|
116
130
|
|
|
117
|
-
const projectRouter = express.Router({ mergeParams: true })
|
|
118
|
-
projectRouter.use(express.json())
|
|
131
|
+
const projectRouter = express.Router({ mergeParams: true });
|
|
132
|
+
projectRouter.use(express.json());
|
|
119
133
|
|
|
120
134
|
if (!options?.silent) {
|
|
121
|
-
app.use(morgan(
|
|
135
|
+
app.use(morgan("tiny"));
|
|
122
136
|
}
|
|
123
|
-
app.use(
|
|
137
|
+
app.use("/oauth", this._oauth2.createRouter());
|
|
124
138
|
|
|
125
139
|
// Only enable auth middleware if we have enabled this
|
|
126
140
|
if (this.options.enableAuthentication) {
|
|
127
|
-
app.use(
|
|
141
|
+
app.use("/:projectKey", this._oauth2.createMiddleware(), projectRouter);
|
|
128
142
|
app.use(
|
|
129
|
-
|
|
143
|
+
"/:projectKey/in-store/key=:storeKey",
|
|
130
144
|
this._oauth2.createMiddleware(),
|
|
131
|
-
projectRouter
|
|
132
|
-
)
|
|
145
|
+
projectRouter,
|
|
146
|
+
);
|
|
133
147
|
} else {
|
|
134
|
-
app.use(
|
|
135
|
-
app.use(
|
|
148
|
+
app.use("/:projectKey", projectRouter);
|
|
149
|
+
app.use("/:projectKey/in-store/key=:storeKey", projectRouter);
|
|
136
150
|
}
|
|
137
151
|
|
|
138
152
|
// Register the rest api services in the router
|
|
139
|
-
this._services = createServices(projectRouter, this._repositories)
|
|
153
|
+
this._services = createServices(projectRouter, this._repositories);
|
|
140
154
|
this._projectService = new ProjectService(
|
|
141
155
|
projectRouter,
|
|
142
|
-
this._repositories.project as ProjectRepository
|
|
143
|
-
)
|
|
156
|
+
this._repositories.project as ProjectRepository,
|
|
157
|
+
);
|
|
144
158
|
|
|
145
159
|
app.use((err: Error, req: Request, resp: Response, next: NextFunction) => {
|
|
146
160
|
if (err instanceof CommercetoolsError) {
|
|
@@ -149,153 +163,153 @@ export class CommercetoolsMock {
|
|
|
149
163
|
statusCode: err.statusCode,
|
|
150
164
|
message: err.message,
|
|
151
165
|
errors: err.errors,
|
|
152
|
-
})
|
|
166
|
+
});
|
|
153
167
|
}
|
|
154
168
|
|
|
155
169
|
return resp.status(err.statusCode).send({
|
|
156
170
|
statusCode: err.statusCode,
|
|
157
171
|
message: err.message,
|
|
158
172
|
errors: [err.info],
|
|
159
|
-
})
|
|
173
|
+
});
|
|
160
174
|
} else {
|
|
161
|
-
console.error(err)
|
|
175
|
+
console.error(err);
|
|
162
176
|
return resp.status(500).send({
|
|
163
177
|
error: err.message,
|
|
164
|
-
})
|
|
178
|
+
});
|
|
165
179
|
}
|
|
166
|
-
})
|
|
180
|
+
});
|
|
167
181
|
|
|
168
|
-
return app
|
|
182
|
+
return app;
|
|
169
183
|
}
|
|
170
184
|
|
|
171
185
|
// registerHandlers is an alternative way to work with commercetools-mock, it
|
|
172
186
|
// allows you to manage msw server yourself and register the handlers needed
|
|
173
187
|
// for commercetools-mock to work.
|
|
174
188
|
public registerHandlers(server: SetupServer) {
|
|
175
|
-
const app = this.app
|
|
189
|
+
const app = this.app;
|
|
176
190
|
server.use(
|
|
177
191
|
http.post(`${this.options.authHost}/oauth/*`, async ({ request }) => {
|
|
178
|
-
const body = await request.text()
|
|
179
|
-
const url = new URL(request.url)
|
|
180
|
-
const headers = copyHeaders(request.headers)
|
|
192
|
+
const body = await request.text();
|
|
193
|
+
const url = new URL(request.url);
|
|
194
|
+
const headers = copyHeaders(request.headers);
|
|
181
195
|
|
|
182
196
|
const res = await inject(app)
|
|
183
|
-
.post(url.pathname +
|
|
197
|
+
.post(url.pathname + "?" + url.searchParams.toString())
|
|
184
198
|
.body(body)
|
|
185
199
|
.headers(headers)
|
|
186
|
-
.end()
|
|
200
|
+
.end();
|
|
187
201
|
return new HttpResponse(res.body, {
|
|
188
202
|
status: res.statusCode,
|
|
189
203
|
headers: mapHeaderType(res.headers),
|
|
190
|
-
})
|
|
204
|
+
});
|
|
191
205
|
}),
|
|
192
206
|
http.head(`${this.options.apiHost}/*`, async ({ request }) => {
|
|
193
|
-
const body = await request.text()
|
|
194
|
-
const url = new URL(request.url)
|
|
195
|
-
const headers = copyHeaders(request.headers)
|
|
207
|
+
const body = await request.text();
|
|
208
|
+
const url = new URL(request.url);
|
|
209
|
+
const headers = copyHeaders(request.headers);
|
|
196
210
|
|
|
197
211
|
const res = await inject(app)
|
|
198
|
-
.get(url.pathname +
|
|
212
|
+
.get(url.pathname + "?" + url.searchParams.toString())
|
|
199
213
|
.body(body)
|
|
200
214
|
.headers(headers)
|
|
201
|
-
.end()
|
|
215
|
+
.end();
|
|
202
216
|
|
|
203
217
|
if (res.statusCode === 200) {
|
|
204
|
-
const parsedBody = JSON.parse(res.body)
|
|
218
|
+
const parsedBody = JSON.parse(res.body);
|
|
205
219
|
// Check if we have a count property (e.g. for query-lookups)
|
|
206
220
|
// or if we have a result object (e.g. for single lookups)
|
|
207
221
|
const resultCount =
|
|
208
|
-
|
|
222
|
+
"count" in parsedBody
|
|
209
223
|
? parsedBody.count
|
|
210
|
-
: Object.keys(parsedBody).length
|
|
224
|
+
: Object.keys(parsedBody).length;
|
|
211
225
|
|
|
212
226
|
return new HttpResponse(null, {
|
|
213
227
|
status: resultCount > 0 ? 200 : 404,
|
|
214
228
|
headers: mapHeaderType(res.headers),
|
|
215
|
-
})
|
|
229
|
+
});
|
|
216
230
|
}
|
|
217
231
|
|
|
218
232
|
return new HttpResponse(null, {
|
|
219
233
|
status: res.statusCode,
|
|
220
234
|
headers: mapHeaderType(res.headers),
|
|
221
|
-
})
|
|
235
|
+
});
|
|
222
236
|
}),
|
|
223
237
|
http.get(`${this.options.apiHost}/*`, async ({ request }) => {
|
|
224
|
-
const body = await request.text()
|
|
225
|
-
const url = new URL(request.url)
|
|
226
|
-
const headers = copyHeaders(request.headers)
|
|
238
|
+
const body = await request.text();
|
|
239
|
+
const url = new URL(request.url);
|
|
240
|
+
const headers = copyHeaders(request.headers);
|
|
227
241
|
|
|
228
242
|
const res = await inject(app)
|
|
229
|
-
.get(url.pathname +
|
|
243
|
+
.get(url.pathname + "?" + url.searchParams.toString())
|
|
230
244
|
.body(body)
|
|
231
245
|
.headers(headers)
|
|
232
|
-
.end()
|
|
246
|
+
.end();
|
|
233
247
|
return new HttpResponse(res.body, {
|
|
234
248
|
status: res.statusCode,
|
|
235
249
|
headers: mapHeaderType(res.headers),
|
|
236
|
-
})
|
|
250
|
+
});
|
|
237
251
|
}),
|
|
238
252
|
http.post(`${this.options.apiHost}/*`, async ({ request }) => {
|
|
239
|
-
const body = await request.text()
|
|
240
|
-
const url = new URL(request.url)
|
|
241
|
-
const headers = copyHeaders(request.headers)
|
|
253
|
+
const body = await request.text();
|
|
254
|
+
const url = new URL(request.url);
|
|
255
|
+
const headers = copyHeaders(request.headers);
|
|
242
256
|
|
|
243
257
|
const res = await inject(app)
|
|
244
|
-
.post(url.pathname +
|
|
258
|
+
.post(url.pathname + "?" + url.searchParams.toString())
|
|
245
259
|
.body(body)
|
|
246
260
|
.headers(headers)
|
|
247
|
-
.end()
|
|
261
|
+
.end();
|
|
248
262
|
return new HttpResponse(res.body, {
|
|
249
263
|
status: res.statusCode,
|
|
250
264
|
headers: mapHeaderType(res.headers),
|
|
251
|
-
})
|
|
265
|
+
});
|
|
252
266
|
}),
|
|
253
267
|
http.delete(`${this.options.apiHost}/*`, async ({ request }) => {
|
|
254
|
-
const body = await request.text()
|
|
255
|
-
const url = new URL(request.url)
|
|
256
|
-
const headers = copyHeaders(request.headers)
|
|
268
|
+
const body = await request.text();
|
|
269
|
+
const url = new URL(request.url);
|
|
270
|
+
const headers = copyHeaders(request.headers);
|
|
257
271
|
|
|
258
272
|
const res = await inject(app)
|
|
259
|
-
.delete(url.pathname +
|
|
273
|
+
.delete(url.pathname + "?" + url.searchParams.toString())
|
|
260
274
|
.body(body)
|
|
261
275
|
.headers(headers)
|
|
262
|
-
.end()
|
|
276
|
+
.end();
|
|
263
277
|
return new HttpResponse(res.body, {
|
|
264
278
|
status: res.statusCode,
|
|
265
279
|
headers: mapHeaderType(res.headers),
|
|
266
|
-
})
|
|
267
|
-
})
|
|
268
|
-
)
|
|
280
|
+
});
|
|
281
|
+
}),
|
|
282
|
+
);
|
|
269
283
|
}
|
|
270
284
|
|
|
271
285
|
public mswServer() {
|
|
272
|
-
return this._mswServer
|
|
286
|
+
return this._mswServer;
|
|
273
287
|
}
|
|
274
288
|
|
|
275
289
|
private startServer() {
|
|
276
290
|
// Check if there are any other servers running
|
|
277
291
|
if (_globalListeners.length > 0) {
|
|
278
292
|
if (this._mswServer !== undefined) {
|
|
279
|
-
throw new Error(
|
|
293
|
+
throw new Error("Server already started");
|
|
280
294
|
} else {
|
|
281
|
-
console.warn("Server wasn't stopped properly, clearing")
|
|
282
|
-
_globalListeners.forEach((listener) => listener.close())
|
|
295
|
+
console.warn("Server wasn't stopped properly, clearing");
|
|
296
|
+
_globalListeners.forEach((listener) => listener.close());
|
|
283
297
|
}
|
|
284
298
|
}
|
|
285
299
|
|
|
286
|
-
const server = setupServer()
|
|
287
|
-
this.registerHandlers(server)
|
|
300
|
+
const server = setupServer();
|
|
301
|
+
this.registerHandlers(server);
|
|
288
302
|
server.listen({
|
|
289
303
|
// We need to allow requests done by supertest
|
|
290
304
|
onUnhandledRequest: (request, print) => {
|
|
291
|
-
const url = new URL(request.url)
|
|
292
|
-
if (url.hostname ===
|
|
293
|
-
return
|
|
305
|
+
const url = new URL(request.url);
|
|
306
|
+
if (url.hostname === "127.0.0.1") {
|
|
307
|
+
return;
|
|
294
308
|
}
|
|
295
|
-
print.error()
|
|
309
|
+
print.error();
|
|
296
310
|
},
|
|
297
|
-
})
|
|
298
|
-
_globalListeners.push(server)
|
|
299
|
-
this._mswServer = server
|
|
311
|
+
});
|
|
312
|
+
_globalListeners.push(server);
|
|
313
|
+
this._mswServer = server;
|
|
300
314
|
}
|
|
301
315
|
}
|
package/src/exceptions.ts
CHANGED
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
export abstract class BaseError {
|
|
2
|
-
abstract message: string
|
|
3
|
-
|
|
2
|
+
abstract message: string;
|
|
3
|
+
|
|
4
|
+
abstract errors?: BaseError[];
|
|
4
5
|
}
|
|
5
6
|
|
|
6
7
|
export class CommercetoolsError<T extends BaseError> extends Error {
|
|
7
|
-
info: T
|
|
8
|
-
|
|
8
|
+
info: T;
|
|
9
|
+
|
|
10
|
+
statusCode: number;
|
|
9
11
|
|
|
10
|
-
errors: BaseError[]
|
|
12
|
+
errors: BaseError[];
|
|
11
13
|
|
|
12
14
|
constructor(info: T, statusCode = 400) {
|
|
13
|
-
super(info.message)
|
|
14
|
-
this.info = info
|
|
15
|
-
this.statusCode = statusCode || 500
|
|
16
|
-
this.errors = info.errors ?? []
|
|
15
|
+
super(info.message);
|
|
16
|
+
this.info = info;
|
|
17
|
+
this.statusCode = statusCode || 500;
|
|
18
|
+
this.errors = info.errors ?? [];
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
export interface InvalidRequestError {
|
|
21
|
-
readonly code:
|
|
22
|
-
readonly message: string
|
|
23
|
+
readonly code: "invalid_request";
|
|
24
|
+
readonly message: string;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export interface AuthError {
|
|
26
|
-
readonly statusCode: number
|
|
27
|
-
readonly message: string
|
|
28
|
-
readonly error: string
|
|
29
|
-
readonly error_description: string
|
|
28
|
+
readonly statusCode: number;
|
|
29
|
+
readonly message: string;
|
|
30
|
+
readonly error: string;
|
|
31
|
+
readonly error_description: string;
|
|
30
32
|
}
|