@labdigital/commercetools-mock 0.9.1 → 0.10.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.
- package/README.md +8 -0
- package/dist/index.d.ts +354 -188
- package/dist/index.global.js +2346 -2209
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +1968 -1829
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2171 -2032
- package/dist/index.mjs.map +1 -1
- package/package.json +30 -21
- package/src/constants.ts +4 -2
- package/src/ctMock.ts +27 -86
- package/src/helpers.ts +10 -11
- package/src/index.test.ts +1 -1
- package/src/lib/haversine.ts +2 -2
- package/src/lib/masking.ts +3 -1
- package/src/lib/predicateParser.ts +93 -92
- package/src/lib/projectionSearchFilter.test.ts +28 -36
- package/src/lib/projectionSearchFilter.ts +88 -103
- package/src/oauth/store.ts +3 -3
- package/src/priceSelector.test.ts +16 -35
- package/src/priceSelector.ts +6 -9
- package/src/product-projection-search.ts +49 -57
- package/src/projectAPI.test.ts +7 -0
- package/src/projectAPI.ts +17 -22
- package/src/repositories/abstract.ts +102 -51
- package/src/repositories/cart-discount.ts +4 -5
- package/src/repositories/cart.ts +56 -46
- package/src/repositories/category.ts +23 -26
- package/src/repositories/channel.ts +5 -6
- package/src/repositories/custom-object.ts +41 -32
- package/src/repositories/customer-group.ts +4 -5
- package/src/repositories/customer.ts +42 -5
- package/src/repositories/discount-code.ts +5 -6
- package/src/repositories/errors.ts +10 -14
- package/src/repositories/extension.ts +16 -15
- package/src/repositories/helpers.ts +10 -15
- package/src/repositories/index.ts +75 -0
- package/src/repositories/inventory-entry.ts +5 -6
- package/src/repositories/my-order.ts +2 -2
- package/src/repositories/order-edit.ts +39 -0
- package/src/repositories/order.test.ts +16 -11
- package/src/repositories/order.ts +21 -14
- package/src/repositories/payment.ts +9 -10
- package/src/repositories/product-discount.ts +5 -25
- package/src/repositories/product-projection.ts +12 -5
- package/src/repositories/product-selection.ts +40 -0
- package/src/repositories/product-type.ts +38 -60
- package/src/repositories/product.ts +128 -85
- package/src/repositories/project.ts +16 -33
- package/src/repositories/quote-request.ts +28 -0
- package/src/repositories/quote.ts +28 -0
- package/src/repositories/review.ts +34 -0
- package/src/repositories/shipping-method.ts +25 -28
- package/src/repositories/shopping-list.ts +6 -6
- package/src/repositories/staged-quote.ts +29 -0
- package/src/repositories/standalone-price.ts +36 -0
- package/src/repositories/state.ts +16 -17
- package/src/repositories/store.ts +13 -29
- package/src/repositories/subscription.ts +4 -5
- package/src/repositories/tax-category.ts +9 -26
- package/src/repositories/type.ts +24 -27
- package/src/repositories/zone.ts +9 -11
- package/src/server.ts +5 -0
- package/src/services/abstract.ts +43 -12
- package/src/services/cart-discount.ts +3 -4
- package/src/services/cart.test.ts +9 -11
- package/src/services/cart.ts +42 -38
- package/src/services/category.test.ts +1 -2
- package/src/services/category.ts +3 -4
- package/src/services/channel.ts +3 -4
- package/src/services/custom-object.test.ts +6 -6
- package/src/services/custom-object.ts +4 -5
- package/src/services/customer-group.ts +3 -4
- package/src/services/customer.test.ts +136 -0
- package/src/services/customer.ts +5 -6
- package/src/services/discount-code.ts +3 -4
- package/src/services/extension.ts +3 -4
- package/src/services/index.ts +74 -0
- package/src/services/inventory-entry.test.ts +9 -13
- package/src/services/inventory-entry.ts +3 -4
- package/src/services/my-cart.test.ts +2 -0
- package/src/services/my-cart.ts +4 -5
- package/src/services/my-customer.ts +3 -4
- package/src/services/my-order.ts +4 -5
- package/src/services/my-payment.ts +3 -4
- package/src/services/order.test.ts +28 -26
- package/src/services/order.ts +4 -5
- package/src/services/payment.ts +3 -4
- package/src/services/product-discount.ts +3 -20
- package/src/services/product-projection.test.ts +76 -8
- package/src/services/product-projection.ts +4 -5
- package/src/services/product-type.ts +3 -20
- package/src/services/product.test.ts +200 -90
- package/src/services/product.ts +3 -4
- package/src/services/project.ts +5 -6
- package/src/services/shipping-method.ts +3 -4
- package/src/services/shopping-list.ts +3 -4
- package/src/services/state.ts +3 -4
- package/src/services/store.test.ts +11 -2
- package/src/services/store.ts +4 -21
- package/src/services/subscription.ts +3 -4
- package/src/services/tax-category.ts +3 -20
- package/src/services/type.ts +3 -4
- package/src/services/zone.ts +3 -4
- package/src/storage/abstract.ts +82 -0
- package/src/{storage.ts → storage/in-memory.ts} +79 -147
- package/src/storage/index.ts +2 -0
- package/src/types.ts +52 -83
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"name": "@labdigital/commercetools-mock",
|
|
3
|
+
"author": "Michael van Tellingen",
|
|
4
|
+
"version": "0.10.1",
|
|
3
5
|
"license": "MIT",
|
|
4
6
|
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/commercetools--mock.esm.js",
|
|
5
8
|
"typings": "dist/index.d.ts",
|
|
6
9
|
"files": [
|
|
7
10
|
"dist",
|
|
@@ -14,21 +17,35 @@
|
|
|
14
17
|
}
|
|
15
18
|
},
|
|
16
19
|
"engines": {
|
|
17
|
-
"node": ">=14"
|
|
20
|
+
"node": ">=14",
|
|
21
|
+
"pnpm": ">=7.13.2"
|
|
18
22
|
},
|
|
23
|
+
"packageManager": "pnpm@7.13.2",
|
|
19
24
|
"prettier": {
|
|
20
25
|
"printWidth": 80,
|
|
21
26
|
"semi": false,
|
|
22
27
|
"singleQuote": true,
|
|
23
28
|
"trailingComma": "es5"
|
|
24
29
|
},
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@types/lodash": "^4.14.182",
|
|
32
|
+
"basic-auth": "^2.0.1",
|
|
33
|
+
"body-parser": "^1.20.0",
|
|
34
|
+
"deep-equal": "^2.0.5",
|
|
35
|
+
"express": "^4.17.2",
|
|
36
|
+
"lodash": "^4.17.21",
|
|
37
|
+
"morgan": "^1.10.0",
|
|
38
|
+
"nock": "^13.2.1",
|
|
39
|
+
"perplex": "^0.11.0",
|
|
40
|
+
"pratt": "^0.7.0",
|
|
41
|
+
"supertest": "^6.1.6",
|
|
42
|
+
"type-fest": "^3.1.0",
|
|
43
|
+
"uuid": "^8.3.2"
|
|
44
|
+
},
|
|
28
45
|
"devDependencies": {
|
|
29
46
|
"@babel/preset-env": "^7.18.9",
|
|
30
47
|
"@babel/preset-typescript": "^7.18.6",
|
|
31
|
-
"@commercetools/platform-sdk": "
|
|
48
|
+
"@commercetools/platform-sdk": "4.0.0",
|
|
32
49
|
"@types/basic-auth": "^1.1.3",
|
|
33
50
|
"@types/body-parser": "^1.19.2",
|
|
34
51
|
"@types/deep-equal": "^1.0.1",
|
|
@@ -40,13 +57,17 @@
|
|
|
40
57
|
"@types/qs": "^6.9.7",
|
|
41
58
|
"@types/supertest": "^2.0.11",
|
|
42
59
|
"@types/uuid": "^8.3.4",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
|
61
|
+
"@typescript-eslint/parser": "^5.39.0",
|
|
43
62
|
"esbuild": "^0.14.50",
|
|
44
63
|
"esbuild-register": "^3.3.1",
|
|
45
64
|
"eslint": "^8.20.0",
|
|
65
|
+
"eslint-plugin-unused-imports": "^2.0.0",
|
|
46
66
|
"got": "^11.8.3",
|
|
47
67
|
"husky": "^7.0.4",
|
|
48
68
|
"jest": "^28.1.3",
|
|
49
69
|
"nodemon": "^2.0.15",
|
|
70
|
+
"prettier": "^2.7.1",
|
|
50
71
|
"timekeeper": "^2.2.0",
|
|
51
72
|
"ts-node": "^10.4.0",
|
|
52
73
|
"tsc": "^2.0.4",
|
|
@@ -54,27 +75,15 @@
|
|
|
54
75
|
"tsup": "^6.2.0",
|
|
55
76
|
"typescript": "^4.7.4"
|
|
56
77
|
},
|
|
57
|
-
"dependencies": {
|
|
58
|
-
"@types/lodash": "^4.14.182",
|
|
59
|
-
"basic-auth": "^2.0.1",
|
|
60
|
-
"body-parser": "^1.20.0",
|
|
61
|
-
"deep-equal": "^2.0.5",
|
|
62
|
-
"express": "^4.17.2",
|
|
63
|
-
"lodash": "^4.17.21",
|
|
64
|
-
"morgan": "^1.10.0",
|
|
65
|
-
"nock": "^13.2.1",
|
|
66
|
-
"perplex": "^0.11.0",
|
|
67
|
-
"pratt": "^0.7.0",
|
|
68
|
-
"supertest": "^6.1.6",
|
|
69
|
-
"uuid": "^8.3.2"
|
|
70
|
-
},
|
|
71
78
|
"peerDependencies": {
|
|
72
79
|
"@commercetools/platform-sdk": "^2.4.1"
|
|
73
80
|
},
|
|
74
81
|
"scripts": {
|
|
75
82
|
"start": "nodemon --watch src --exec 'node -r esbuild-register' src/server.ts",
|
|
76
83
|
"build": "tsup",
|
|
84
|
+
"build:server": "esbuild src/server.ts --bundle --outfile=dist/server.js --platform=node",
|
|
85
|
+
"check": "eslint src && tsc",
|
|
77
86
|
"test": "jest test --coverage",
|
|
78
|
-
"lint": "eslint"
|
|
87
|
+
"lint": "eslint src"
|
|
79
88
|
}
|
|
80
89
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export const DEFAULT_API_HOSTNAME =
|
|
2
|
-
|
|
1
|
+
export const DEFAULT_API_HOSTNAME =
|
|
2
|
+
/^https:\/\/api\..*?\.commercetools.com:443$/
|
|
3
|
+
export const DEFAULT_AUTH_HOSTNAME =
|
|
4
|
+
/^https:\/\/auth\..*?\.commercetools.com:443$/
|
package/src/ctMock.ts
CHANGED
|
@@ -11,35 +11,10 @@ import { copyHeaders } from './lib/proxy'
|
|
|
11
11
|
import { DEFAULT_API_HOSTNAME, DEFAULT_AUTH_HOSTNAME } from './constants'
|
|
12
12
|
|
|
13
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'
|
|
25
|
-
import { MyPaymentService } from './services/my-payment'
|
|
26
|
-
import { OrderService } from './services/order'
|
|
27
|
-
import { PaymentService } from './services/payment'
|
|
28
|
-
import { ProductDiscountService } from './services/product-discount'
|
|
29
|
-
import { ProductProjectionService } from './services/product-projection'
|
|
30
|
-
import { ProductService } from './services/product'
|
|
31
|
-
import { ProductTypeService } from './services/product-type'
|
|
32
14
|
import { ProjectService } from './services/project'
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import { StoreService } from './services/store'
|
|
37
|
-
import { SubscriptionService } from './services/subscription'
|
|
38
|
-
import { TaxCategoryService } from './services/tax-category'
|
|
39
|
-
import { TypeService } from './services/type'
|
|
40
|
-
import { ZoneService } from './services/zone'
|
|
41
|
-
import { MyCustomerService } from './services/my-customer'
|
|
42
|
-
import { MyOrderService } from './services/my-order'
|
|
15
|
+
import { createRepositories, RepositoryMap } from './repositories'
|
|
16
|
+
import { createServices } from './services'
|
|
17
|
+
import { ProjectRepository } from 'repositories/project'
|
|
43
18
|
|
|
44
19
|
export type CommercetoolsMockOptions = {
|
|
45
20
|
validateCredentials: boolean
|
|
@@ -71,12 +46,14 @@ export class CommercetoolsMock {
|
|
|
71
46
|
auth: nock.Scope | undefined
|
|
72
47
|
api: nock.Scope | undefined
|
|
73
48
|
} = { auth: undefined, api: undefined }
|
|
74
|
-
private _services: Services
|
|
49
|
+
private _services: Services | null
|
|
50
|
+
private _repositories: RepositoryMap | null
|
|
75
51
|
private _projectService?: ProjectService
|
|
76
52
|
|
|
77
53
|
constructor(options: Partial<CommercetoolsMockOptions> = {}) {
|
|
78
54
|
this.options = { ...DEFAULT_OPTIONS, ...options }
|
|
79
|
-
this._services =
|
|
55
|
+
this._services = null
|
|
56
|
+
this._repositories = null
|
|
80
57
|
this._projectService = undefined
|
|
81
58
|
|
|
82
59
|
this._storage = new InMemoryStorage()
|
|
@@ -111,22 +88,27 @@ export class CommercetoolsMock {
|
|
|
111
88
|
throw new Error('No projectKey passed and no default set')
|
|
112
89
|
}
|
|
113
90
|
|
|
91
|
+
if (this._repositories === null) {
|
|
92
|
+
throw new Error('repositories not initialized yet')
|
|
93
|
+
}
|
|
94
|
+
|
|
114
95
|
return new ProjectAPI(
|
|
115
96
|
projectKey || this.options.defaultProjectKey!,
|
|
116
|
-
this.
|
|
97
|
+
this._repositories,
|
|
117
98
|
this._storage
|
|
118
99
|
)
|
|
119
100
|
}
|
|
120
101
|
|
|
121
|
-
runServer(port
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
console.log(`Mock server listening at http://localhost:${port}`)
|
|
102
|
+
runServer(port = 3000, options?: AppOptions) {
|
|
103
|
+
const server = this.app.listen(port, () => {
|
|
104
|
+
console.info(`Mock server listening at http://localhost:${port}`)
|
|
125
105
|
})
|
|
126
106
|
server.keepAliveTimeout = 60 * 1000
|
|
127
107
|
}
|
|
128
108
|
|
|
129
109
|
private createApp(options?: AppOptions): express.Express {
|
|
110
|
+
this._repositories = createRepositories(this._storage)
|
|
111
|
+
|
|
130
112
|
const app = express()
|
|
131
113
|
|
|
132
114
|
const projectRouter = express.Router({ mergeParams: true })
|
|
@@ -150,53 +132,12 @@ export class CommercetoolsMock {
|
|
|
150
132
|
app.use('/:projectKey/in-store/key=:storeKey', projectRouter)
|
|
151
133
|
}
|
|
152
134
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
customer: new CustomerService(projectRouter, this._storage),
|
|
160
|
-
channel: new ChannelService(projectRouter, this._storage),
|
|
161
|
-
'customer-group': new CustomerGroupService(projectRouter, this._storage),
|
|
162
|
-
'discount-code': new DiscountCodeService(projectRouter, this._storage),
|
|
163
|
-
extension: new ExtensionServices(projectRouter, this._storage),
|
|
164
|
-
'inventory-entry': new InventoryEntryService(
|
|
165
|
-
projectRouter,
|
|
166
|
-
this._storage
|
|
167
|
-
),
|
|
168
|
-
'key-value-document': new CustomObjectService(
|
|
169
|
-
projectRouter,
|
|
170
|
-
this._storage
|
|
171
|
-
),
|
|
172
|
-
order: new OrderService(projectRouter, this._storage),
|
|
173
|
-
payment: new PaymentService(projectRouter, this._storage),
|
|
174
|
-
'my-cart': new MyCartService(projectRouter, this._storage),
|
|
175
|
-
'my-order': new MyOrderService(projectRouter, this._storage),
|
|
176
|
-
'my-customer': new MyCustomerService(projectRouter, this._storage),
|
|
177
|
-
'my-payment': new MyPaymentService(projectRouter, this._storage),
|
|
178
|
-
'shipping-method': new ShippingMethodService(
|
|
179
|
-
projectRouter,
|
|
180
|
-
this._storage
|
|
181
|
-
),
|
|
182
|
-
'product-type': new ProductTypeService(projectRouter, this._storage),
|
|
183
|
-
product: new ProductService(projectRouter, this._storage),
|
|
184
|
-
'product-discount': new ProductDiscountService(
|
|
185
|
-
projectRouter,
|
|
186
|
-
this._storage
|
|
187
|
-
),
|
|
188
|
-
'product-projection': new ProductProjectionService(
|
|
189
|
-
projectRouter,
|
|
190
|
-
this._storage
|
|
191
|
-
),
|
|
192
|
-
'shopping-list': new ShoppingListService(projectRouter, this._storage),
|
|
193
|
-
state: new StateService(projectRouter, this._storage),
|
|
194
|
-
store: new StoreService(projectRouter, this._storage),
|
|
195
|
-
subscription: new SubscriptionService(projectRouter, this._storage),
|
|
196
|
-
'tax-category': new TaxCategoryService(projectRouter, this._storage),
|
|
197
|
-
type: new TypeService(projectRouter, this._storage),
|
|
198
|
-
zone: new ZoneService(projectRouter, this._storage),
|
|
199
|
-
}
|
|
135
|
+
// Register the rest api services in the router
|
|
136
|
+
this._services = createServices(projectRouter, this._repositories)
|
|
137
|
+
this._projectService = new ProjectService(
|
|
138
|
+
projectRouter,
|
|
139
|
+
this._repositories.project as ProjectRepository
|
|
140
|
+
)
|
|
200
141
|
|
|
201
142
|
app.use((err: Error, req: Request, resp: Response, next: NextFunction) => {
|
|
202
143
|
if (err instanceof CommercetoolsError) {
|
|
@@ -222,14 +163,14 @@ export class CommercetoolsMock {
|
|
|
222
163
|
this._nockScopes.api = nock(this.options.apiHost)
|
|
223
164
|
.persist()
|
|
224
165
|
.get(/.*/)
|
|
225
|
-
.reply(async function(uri) {
|
|
166
|
+
.reply(async function (uri) {
|
|
226
167
|
const response = await supertest(app)
|
|
227
168
|
.get(uri)
|
|
228
169
|
.set(copyHeaders(this.req.headers))
|
|
229
170
|
return [response.status, response.body]
|
|
230
171
|
})
|
|
231
172
|
.post(/.*/)
|
|
232
|
-
.reply(async function(uri, body) {
|
|
173
|
+
.reply(async function (uri, body) {
|
|
233
174
|
const response = await supertest(app)
|
|
234
175
|
.post(uri)
|
|
235
176
|
.set(copyHeaders(this.req.headers))
|
|
@@ -237,7 +178,7 @@ export class CommercetoolsMock {
|
|
|
237
178
|
return [response.status, response.body]
|
|
238
179
|
})
|
|
239
180
|
.delete(/.*/)
|
|
240
|
-
.reply(async function(uri, body) {
|
|
181
|
+
.reply(async function (uri, body) {
|
|
241
182
|
const response = await supertest(app)
|
|
242
183
|
.delete(uri)
|
|
243
184
|
.set(copyHeaders(this.req.headers))
|
|
@@ -252,7 +193,7 @@ export class CommercetoolsMock {
|
|
|
252
193
|
this._nockScopes.auth = nock(this.options.authHost)
|
|
253
194
|
.persist()
|
|
254
195
|
.post(/^\/oauth\/.*/)
|
|
255
|
-
.reply(async function(uri, body) {
|
|
196
|
+
.reply(async function (uri, body) {
|
|
256
197
|
const response = await supertest(app)
|
|
257
198
|
.post(uri + '?' + body)
|
|
258
199
|
.set(copyHeaders(this.req.headers))
|
package/src/helpers.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { v4 as uuidv4 } from 'uuid'
|
|
2
1
|
import { ParsedQs } from 'qs'
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export const getBaseResourceProperties = () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid'
|
|
3
|
+
|
|
4
|
+
export const getBaseResourceProperties = () => ({
|
|
5
|
+
id: uuidv4(),
|
|
6
|
+
createdAt: new Date().toISOString(),
|
|
7
|
+
lastModifiedAt: new Date().toISOString(),
|
|
8
|
+
version: 0,
|
|
9
|
+
})
|
|
13
10
|
|
|
14
11
|
/**
|
|
15
12
|
* Do a nested lookup by using a path. For example `foo.bar.value` will
|
|
@@ -47,3 +44,5 @@ export const QueryParamsAsArray = (
|
|
|
47
44
|
}
|
|
48
45
|
return [input] as string[]
|
|
49
46
|
}
|
|
47
|
+
|
|
48
|
+
export const cloneObject = <T>(o: T): T => JSON.parse(JSON.stringify(o))
|
package/src/index.test.ts
CHANGED
|
@@ -158,7 +158,7 @@ test('Options.authHost: is set', async () => {
|
|
|
158
158
|
})
|
|
159
159
|
ctMock.start()
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
const response = await got.post<{ access_token: string }>(
|
|
162
162
|
'http://auth.localhost/oauth/token',
|
|
163
163
|
{
|
|
164
164
|
searchParams: {
|
package/src/lib/haversine.ts
CHANGED
|
@@ -13,12 +13,12 @@ export const haversineDistance = (src: Location, dst: Location) => {
|
|
|
13
13
|
const dLat = toRadian(dst.latitude - src.latitude)
|
|
14
14
|
const dLon = toRadian(dst.longitude - src.longitude)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
const a =
|
|
17
17
|
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
18
18
|
Math.cos(toRadian(src.latitude)) *
|
|
19
19
|
Math.cos(toRadian(dst.latitude)) *
|
|
20
20
|
Math.sin(dLon / 2) *
|
|
21
21
|
Math.sin(dLon / 2)
|
|
22
|
-
|
|
22
|
+
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
|
|
23
23
|
return RADIUS_OF_EARTH_IN_KM * c * 1000
|
|
24
24
|
}
|
package/src/lib/masking.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { cloneObject } from '../helpers'
|
|
2
|
+
|
|
1
3
|
export const maskSecretValue = <T>(resource: T, path: string): T => {
|
|
2
4
|
const parts = path.split('.')
|
|
3
|
-
const clone =
|
|
5
|
+
const clone = cloneObject(resource) as any
|
|
4
6
|
let val = clone
|
|
5
7
|
|
|
6
8
|
const target = parts.pop()
|
|
@@ -31,7 +31,7 @@ export const matchesPredicate = (
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (Array.isArray(predicate)) {
|
|
34
|
-
return predicate.every(item => {
|
|
34
|
+
return predicate.every((item) => {
|
|
35
35
|
const func = generateMatchFunc(item)
|
|
36
36
|
return func(target, variables || {})
|
|
37
37
|
})
|
|
@@ -45,22 +45,21 @@ export const parseQueryExpression = (
|
|
|
45
45
|
predicate: string | string[]
|
|
46
46
|
): MatchFunc => {
|
|
47
47
|
if (Array.isArray(predicate)) {
|
|
48
|
-
const callbacks = predicate.map(item => generateMatchFunc(item))
|
|
49
|
-
return (target: any, variables: VariableMap) =>
|
|
50
|
-
|
|
51
|
-
}
|
|
48
|
+
const callbacks = predicate.map((item) => generateMatchFunc(item))
|
|
49
|
+
return (target: any, variables: VariableMap) =>
|
|
50
|
+
callbacks.every((callback) => callback(target, variables))
|
|
52
51
|
} else {
|
|
53
52
|
return generateMatchFunc(predicate)
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
type
|
|
56
|
+
type TypeSymbol = {
|
|
58
57
|
type: 'var' | 'boolean' | 'string' | 'float' | 'int' | 'identifier'
|
|
59
58
|
value: any
|
|
60
59
|
pos?: ITokenPosition
|
|
61
60
|
}
|
|
62
61
|
|
|
63
|
-
const validateSymbol = (val:
|
|
62
|
+
const validateSymbol = (val: TypeSymbol) => {
|
|
64
63
|
if (!val.type) {
|
|
65
64
|
throw new PredicateError('Internal error')
|
|
66
65
|
}
|
|
@@ -76,7 +75,7 @@ const validateSymbol = (val: Symbol) => {
|
|
|
76
75
|
}
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
const resolveSymbol = (val:
|
|
78
|
+
const resolveSymbol = (val: TypeSymbol, vars: VariableMap): any => {
|
|
80
79
|
if (val.type === 'var') {
|
|
81
80
|
if (!(val.value in vars)) {
|
|
82
81
|
throw new PredicateError(`Missing parameter value for ${val.value}`)
|
|
@@ -87,7 +86,7 @@ const resolveSymbol = (val: Symbol, vars: VariableMap): any => {
|
|
|
87
86
|
return val.value
|
|
88
87
|
}
|
|
89
88
|
|
|
90
|
-
const resolveValue = (obj: any, val:
|
|
89
|
+
const resolveValue = (obj: any, val: TypeSymbol): any => {
|
|
91
90
|
if (val.type !== 'identifier') {
|
|
92
91
|
throw new PredicateError('Internal error')
|
|
93
92
|
}
|
|
@@ -95,8 +94,8 @@ const resolveValue = (obj: any, val: Symbol): any => {
|
|
|
95
94
|
if (!(val.value in obj)) {
|
|
96
95
|
if (Array.isArray(obj)) {
|
|
97
96
|
return Object.values(obj)
|
|
98
|
-
.filter(v => val.value in v)
|
|
99
|
-
.map(v => v[val.value])
|
|
97
|
+
.filter((v) => val.value in v)
|
|
98
|
+
.map((v) => v[val.value])
|
|
100
99
|
}
|
|
101
100
|
throw new PredicateError(`The field '${val.value}' does not exist.`)
|
|
102
101
|
}
|
|
@@ -104,8 +103,8 @@ const resolveValue = (obj: any, val: Symbol): any => {
|
|
|
104
103
|
return obj[val.value]
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
const getLexer = (value: string) =>
|
|
108
|
-
|
|
106
|
+
const getLexer = (value: string) =>
|
|
107
|
+
new perplex(value)
|
|
109
108
|
|
|
110
109
|
.token('AND', /and(?![-_a-z0-9]+)/i)
|
|
111
110
|
.token('OR', /or(?![-_a-z0-9]+)/i)
|
|
@@ -140,7 +139,6 @@ const getLexer = (value: string) => {
|
|
|
140
139
|
.token('=', '=')
|
|
141
140
|
.token('"', '"')
|
|
142
141
|
.token('WS', /\s+/, true) // skip
|
|
143
|
-
}
|
|
144
142
|
|
|
145
143
|
/**
|
|
146
144
|
* This function converts a query expression in to a callable which returns a
|
|
@@ -153,74 +151,82 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
153
151
|
const lexer = getLexer(predicate)
|
|
154
152
|
const parser = new Parser(lexer)
|
|
155
153
|
.builder()
|
|
156
|
-
.nud(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
154
|
+
.nud(
|
|
155
|
+
'IDENTIFIER',
|
|
156
|
+
100,
|
|
157
|
+
(t) =>
|
|
158
|
+
({
|
|
159
|
+
type: 'identifier',
|
|
160
|
+
value: t.token.match,
|
|
161
|
+
pos: t.token.strpos(),
|
|
162
|
+
} as TypeSymbol)
|
|
163
|
+
)
|
|
164
|
+
.nud(
|
|
165
|
+
'BOOLEAN',
|
|
166
|
+
1,
|
|
167
|
+
(t) =>
|
|
168
|
+
({
|
|
169
|
+
type: 'boolean',
|
|
170
|
+
value: t.token.match === 'true' ? true : false,
|
|
171
|
+
pos: t.token.strpos(),
|
|
172
|
+
} as TypeSymbol)
|
|
173
|
+
)
|
|
174
|
+
.nud(
|
|
175
|
+
'VARIABLE',
|
|
176
|
+
100,
|
|
177
|
+
(t) =>
|
|
178
|
+
({
|
|
179
|
+
type: 'var',
|
|
180
|
+
// @ts-ignore
|
|
181
|
+
value: t.token.groups[1],
|
|
182
|
+
pos: t.token.strpos(),
|
|
183
|
+
} as TypeSymbol)
|
|
184
|
+
)
|
|
185
|
+
.nud(
|
|
186
|
+
'STRING',
|
|
187
|
+
100,
|
|
188
|
+
(t) =>
|
|
189
|
+
({
|
|
190
|
+
type: 'string',
|
|
191
|
+
// @ts-ignore
|
|
192
|
+
value: t.token.groups[1],
|
|
193
|
+
pos: t.token.strpos(),
|
|
194
|
+
} as TypeSymbol)
|
|
195
|
+
)
|
|
196
|
+
.nud(
|
|
197
|
+
'INT',
|
|
198
|
+
1,
|
|
199
|
+
(t) =>
|
|
200
|
+
({
|
|
201
|
+
type: 'int',
|
|
202
|
+
value: parseInt(t.token.match, 10),
|
|
203
|
+
pos: t.token.strpos(),
|
|
204
|
+
} as TypeSymbol)
|
|
205
|
+
)
|
|
206
|
+
.nud(
|
|
207
|
+
'FLOAT',
|
|
208
|
+
1,
|
|
209
|
+
(t) =>
|
|
210
|
+
({
|
|
211
|
+
type: 'float',
|
|
212
|
+
value: parseFloat(t.token.match),
|
|
213
|
+
pos: t.token.strpos(),
|
|
214
|
+
} as TypeSymbol)
|
|
215
|
+
)
|
|
200
216
|
.nud('NOT', 100, ({ bp }) => {
|
|
201
217
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
202
|
-
return (obj: any) =>
|
|
203
|
-
return !expr(obj)
|
|
204
|
-
}
|
|
205
|
-
})
|
|
206
|
-
.nud('EMPTY', 10, ({ bp }) => {
|
|
207
|
-
return 'empty'
|
|
208
|
-
})
|
|
209
|
-
.nud('DEFINED', 10, ({ bp }) => {
|
|
210
|
-
return 'defined'
|
|
218
|
+
return (obj: any) => !expr(obj)
|
|
211
219
|
})
|
|
220
|
+
.nud('EMPTY', 10, ({ bp }) => 'empty')
|
|
221
|
+
.nud('DEFINED', 10, ({ bp }) => 'defined')
|
|
212
222
|
|
|
213
223
|
.led('AND', 5, ({ left, bp }) => {
|
|
214
224
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
215
|
-
return (obj: any) =>
|
|
216
|
-
return left(obj) && expr(obj)
|
|
217
|
-
}
|
|
225
|
+
return (obj: any) => left(obj) && expr(obj)
|
|
218
226
|
})
|
|
219
227
|
.led('OR', 5, ({ left, token, bp }) => {
|
|
220
228
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
221
|
-
return (obj: any, vars: object) =>
|
|
222
|
-
return left(obj, vars) || expr(obj, vars)
|
|
223
|
-
}
|
|
229
|
+
return (obj: any, vars: object) => left(obj, vars) || expr(obj, vars)
|
|
224
230
|
})
|
|
225
231
|
.led('COMMA', 1, ({ left, token, bp }) => {
|
|
226
232
|
const expr: any = parser.parse({ terminals: [bp - 1] })
|
|
@@ -230,7 +236,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
230
236
|
return [left, expr]
|
|
231
237
|
}
|
|
232
238
|
})
|
|
233
|
-
.nud('(', 100, t => {
|
|
239
|
+
.nud('(', 100, (t) => {
|
|
234
240
|
const expr: any = parser.parse({ terminals: [')'] })
|
|
235
241
|
return expr
|
|
236
242
|
})
|
|
@@ -254,7 +260,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
254
260
|
const resolvedValue = resolveValue(obj, left)
|
|
255
261
|
const resolvedSymbol = resolveSymbol(expr, vars)
|
|
256
262
|
if (Array.isArray(resolvedValue)) {
|
|
257
|
-
return !!resolvedValue.some(elem => elem === resolvedSymbol)
|
|
263
|
+
return !!resolvedValue.some((elem) => elem === resolvedSymbol)
|
|
258
264
|
}
|
|
259
265
|
return resolvedValue === resolvedSymbol
|
|
260
266
|
}
|
|
@@ -262,41 +268,36 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
262
268
|
.led('!=', 20, ({ left, bp }) => {
|
|
263
269
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
264
270
|
validateSymbol(expr)
|
|
265
|
-
return (obj: any, vars: VariableMap) =>
|
|
266
|
-
|
|
267
|
-
}
|
|
271
|
+
return (obj: any, vars: VariableMap) =>
|
|
272
|
+
resolveValue(obj, left) !== resolveSymbol(expr, vars)
|
|
268
273
|
})
|
|
269
274
|
.led('>', 20, ({ left, bp }) => {
|
|
270
275
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
271
276
|
validateSymbol(expr)
|
|
272
277
|
|
|
273
|
-
return (obj: any, vars: object) =>
|
|
274
|
-
|
|
275
|
-
}
|
|
278
|
+
return (obj: any, vars: object) =>
|
|
279
|
+
resolveValue(obj, left) > resolveSymbol(expr, vars)
|
|
276
280
|
})
|
|
277
281
|
.led('>=', 20, ({ left, bp }) => {
|
|
278
282
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
279
283
|
validateSymbol(expr)
|
|
280
284
|
|
|
281
|
-
return (obj: any, vars: object) =>
|
|
282
|
-
|
|
283
|
-
}
|
|
285
|
+
return (obj: any, vars: object) =>
|
|
286
|
+
resolveValue(obj, left) >= resolveSymbol(expr, vars)
|
|
284
287
|
})
|
|
285
288
|
.led('<', 20, ({ left, bp }) => {
|
|
286
289
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
287
290
|
validateSymbol(expr)
|
|
288
291
|
|
|
289
|
-
return (obj: any, vars: object) =>
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
+
return (obj: any, vars: object) =>
|
|
293
|
+
resolveValue(obj, left) < resolveSymbol(expr, vars)
|
|
292
294
|
})
|
|
293
295
|
.led('<=', 20, ({ left, bp }) => {
|
|
294
296
|
const expr = parser.parse({ terminals: [bp - 1] })
|
|
295
297
|
validateSymbol(expr)
|
|
296
298
|
|
|
297
|
-
return (obj: any, vars: object) =>
|
|
298
|
-
|
|
299
|
-
}
|
|
299
|
+
return (obj: any, vars: object) =>
|
|
300
|
+
resolveValue(obj, left) <= resolveSymbol(expr, vars)
|
|
300
301
|
})
|
|
301
302
|
.led('IS', 20, ({ left, bp }) => {
|
|
302
303
|
let invert = false
|
|
@@ -350,7 +351,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
350
351
|
symbols = [expr]
|
|
351
352
|
}
|
|
352
353
|
|
|
353
|
-
const inValues = symbols.map((item:
|
|
354
|
+
const inValues = symbols.map((item: TypeSymbol) =>
|
|
354
355
|
resolveSymbol(item, vars)
|
|
355
356
|
)
|
|
356
357
|
return inValues.includes(resolveValue(obj, left))
|
|
@@ -419,7 +420,7 @@ const generateMatchFunc = (predicate: string): MatchFunc => {
|
|
|
419
420
|
)
|
|
420
421
|
}
|
|
421
422
|
|
|
422
|
-
const array = expr.map((item:
|
|
423
|
+
const array = expr.map((item: TypeSymbol) => resolveSymbol(item, vars))
|
|
423
424
|
if (keyword.type === 'ALL') {
|
|
424
425
|
return array.every((item: any) => value.includes(item))
|
|
425
426
|
} else {
|