@unchainedshop/utils 2.5.12 → 2.6.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/lib/build-obfuscated-fields-filter.d.ts +2 -0
- package/lib/build-obfuscated-fields-filter.js +37 -0
- package/lib/build-obfuscated-fields-filter.js.map +1 -0
- package/lib/locale-helpers.d.ts +3 -3
- package/lib/locale-helpers.js.map +1 -1
- package/lib/utils-index.d.ts +1 -8
- package/lib/utils-index.js +62 -11
- package/lib/utils-index.js.map +1 -1
- package/package.json +5 -6
- package/src/build-obfuscated-fields-filter.ts +42 -0
- package/src/locale-helpers.ts +5 -1
- package/src/utils-index.test.ts +0 -83
- package/src/utils-index.ts +63 -13
- package/lib/db/build-db-indexes.d.ts +0 -2
- package/lib/db/build-db-indexes.js +0 -34
- package/lib/db/build-db-indexes.js.map +0 -1
- package/lib/db/build-sort-option.d.ts +0 -4
- package/lib/db/build-sort-option.js +0 -13
- package/lib/db/build-sort-option.js.map +0 -1
- package/lib/db/check-id.d.ts +0 -4
- package/lib/db/check-id.js +0 -6
- package/lib/db/check-id.js.map +0 -1
- package/lib/db/generate-db-filter-by-id.d.ts +0 -4
- package/lib/db/generate-db-filter-by-id.js +0 -5
- package/lib/db/generate-db-filter-by-id.js.map +0 -1
- package/lib/db/generate-db-mutations.d.ts +0 -9
- package/lib/db/generate-db-mutations.js +0 -73
- package/lib/db/generate-db-mutations.js.map +0 -1
- package/lib/db/generate-db-object-id.d.ts +0 -7
- package/lib/db/generate-db-object-id.js +0 -26
- package/lib/db/generate-db-object-id.js.map +0 -1
- package/lib/find-localized-text.d.ts +0 -4
- package/lib/find-localized-text.js +0 -45
- package/lib/find-localized-text.js.map +0 -1
- package/lib/find-preserving-ids.d.ts +0 -2
- package/lib/find-preserving-ids.js +0 -33
- package/lib/find-preserving-ids.js.map +0 -1
- package/src/db/build-db-indexes.ts +0 -48
- package/src/db/build-sort-option.ts +0 -17
- package/src/db/check-id.ts +0 -13
- package/src/db/generate-db-filter-by-id.ts +0 -9
- package/src/db/generate-db-mutations.ts +0 -93
- package/src/db/generate-db-object-id.ts +0 -25
- package/src/find-localized-text.ts +0 -62
- package/src/find-preserving-ids.ts +0 -44
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const defaultObfuscatedFields = [
|
|
2
|
+
'password',
|
|
3
|
+
'plainPassword',
|
|
4
|
+
'newPlainPassword',
|
|
5
|
+
'oldPlainPassword',
|
|
6
|
+
'authorization',
|
|
7
|
+
'secret',
|
|
8
|
+
'accesskey',
|
|
9
|
+
'accesstoken',
|
|
10
|
+
'token',
|
|
11
|
+
];
|
|
12
|
+
const buildObfuscatedFieldsFilter = (blacklistedVariables = []) => {
|
|
13
|
+
const sensitiveFields = blacklistedVariables || defaultObfuscatedFields;
|
|
14
|
+
const obfuscateSensitiveFields = (data) => {
|
|
15
|
+
if (!data)
|
|
16
|
+
return data;
|
|
17
|
+
if (Array.isArray(data)) {
|
|
18
|
+
return data.map((item) => obfuscateSensitiveFields(item));
|
|
19
|
+
}
|
|
20
|
+
if (typeof data === 'object') {
|
|
21
|
+
const temp = data;
|
|
22
|
+
Object.keys(temp).forEach((key) => {
|
|
23
|
+
if (sensitiveFields.includes(key)) {
|
|
24
|
+
temp[key] = '******';
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
temp[key] = obfuscateSensitiveFields(temp[key]);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return temp; // Return the modified copy
|
|
31
|
+
}
|
|
32
|
+
return data; // Return unchanged data for non-objects
|
|
33
|
+
};
|
|
34
|
+
return obfuscateSensitiveFields;
|
|
35
|
+
};
|
|
36
|
+
export default buildObfuscatedFieldsFilter;
|
|
37
|
+
//# sourceMappingURL=build-obfuscated-fields-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-obfuscated-fields-filter.js","sourceRoot":"","sources":["../src/build-obfuscated-fields-filter.ts"],"names":[],"mappings":"AAAA,MAAM,uBAAuB,GAAG;IAC9B,UAAU;IACV,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,eAAe;IACf,QAAQ;IACR,WAAW;IACX,aAAa;IACb,OAAO;CACR,CAAC;AAEF,MAAM,2BAA2B,GAAG,CAAC,uBAAiC,EAAE,EAAE,EAAE;IAC1E,MAAM,eAAe,GAAG,oBAAoB,IAAI,uBAAuB,CAAC;IAExE,MAAM,wBAAwB,GAAG,CAAC,IAAI,EAAE,EAAE;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QAEvB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAChC,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAClC,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;gBACvB,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,GAAG,CAAC,GAAG,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,IAAI,CAAC,CAAC,2BAA2B;QAC1C,CAAC;QAED,OAAO,IAAI,CAAC,CAAC,wCAAwC;IACvD,CAAC,CAAC;IAEF,OAAO,wBAAwB,CAAC;AAClC,CAAC,CAAC;AAEF,eAAe,2BAA2B,CAAC"}
|
package/lib/locale-helpers.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare const systemLocale:
|
|
3
|
-
export declare const resolveBestSupported: (acceptLanguage:
|
|
1
|
+
import type { Locale as LocaleType, Locales as LocalesType } from 'locale';
|
|
2
|
+
export declare const systemLocale: LocaleType;
|
|
3
|
+
export declare const resolveBestSupported: (acceptLanguage: string, supportedLocales: LocalesType) => LocaleType;
|
|
4
4
|
export declare const resolveBestCountry: (localeCountry: any, shopCountry: any, countries: any) => any;
|
|
5
5
|
export declare const resolveUserRemoteAddress: (req: any) => {
|
|
6
6
|
remoteAddress: any;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale-helpers.js","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"locale-helpers.js","sourceRoot":"","sources":["../src/locale-helpers.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,QAAQ,CAAC;AAE/B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;AAEtC,MAAM,EAAE,cAAc,GAAG,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAExE,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,GAAG,cAAc,IAAI,iBAAiB,EAAE,CAAC,CAAC;AAEjF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,cAAsB,EACtB,gBAA6B,EACjB,EAAE;IACd,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,YAAY,CAAC;IACrC,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE;IAC1E,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE;YACjE,IAAI,WAAW,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpC,OAAO,OAAO,CAAC,OAAO,CAAC;YACzB,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,eAAe,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,aAAa,IAAI,YAAY,CAAC,OAAO,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,GAAG,EAAE,EAAE;IAC9C,MAAM,aAAa,GACjB,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC;QACxB,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC;QAC9B,GAAG,CAAC,UAAU,CAAC,aAAa;QAC5B,GAAG,CAAC,MAAM,CAAC,aAAa;QACxB,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC;IAEtC,MAAM,UAAU,GACd,GAAG,CAAC,UAAU,EAAE,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,IAAI,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC;IAE7F,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC;AACvC,CAAC,CAAC"}
|
package/lib/utils-index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * as calculation from './calculation.js';
|
|
2
|
-
export { default as findLocalizedText } from './find-localized-text.js';
|
|
3
2
|
export * from './locale-helpers.js';
|
|
4
3
|
export { default as objectInvert } from './object-invert.js';
|
|
5
4
|
export { default as findUnusedSlug } from './find-unused-slug.js';
|
|
@@ -7,13 +6,7 @@ export { default as slugify } from './slugify.js';
|
|
|
7
6
|
export { default as pipePromises } from './pipe-promises.js';
|
|
8
7
|
export { default as generateRandomHash } from './generate-random-hash.js';
|
|
9
8
|
export { default as randomValueHex } from './random-value-hex.js';
|
|
10
|
-
export { default as
|
|
11
|
-
export { checkId } from './db/check-id.js';
|
|
12
|
-
export { generateDbObjectId } from './db/generate-db-object-id.js';
|
|
13
|
-
export { generateDbFilterById } from './db/generate-db-filter-by-id.js';
|
|
14
|
-
export { generateDbMutations } from './db/generate-db-mutations.js';
|
|
15
|
-
export { buildDbIndexes } from './db/build-db-indexes.js';
|
|
16
|
-
export { findPreservingIds } from './find-preserving-ids.js';
|
|
9
|
+
export { default as buildObfuscatedFieldsFilter } from './build-obfuscated-fields-filter.js';
|
|
17
10
|
export { Schemas } from './schemas/index.js';
|
|
18
11
|
export { BaseAdapter } from './director/BaseAdapter.js';
|
|
19
12
|
export { BaseDirector } from './director/BaseDirector.js';
|
package/lib/utils-index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export * as calculation from './calculation.js';
|
|
2
|
-
export { default as findLocalizedText } from './find-localized-text.js';
|
|
3
2
|
export * from './locale-helpers.js';
|
|
4
3
|
export { default as objectInvert } from './object-invert.js';
|
|
5
4
|
export { default as findUnusedSlug } from './find-unused-slug.js';
|
|
@@ -7,16 +6,7 @@ export { default as slugify } from './slugify.js';
|
|
|
7
6
|
export { default as pipePromises } from './pipe-promises.js';
|
|
8
7
|
export { default as generateRandomHash } from './generate-random-hash.js';
|
|
9
8
|
export { default as randomValueHex } from './random-value-hex.js';
|
|
10
|
-
export { default as
|
|
11
|
-
/*
|
|
12
|
-
* Db utils
|
|
13
|
-
*/
|
|
14
|
-
export { checkId } from './db/check-id.js';
|
|
15
|
-
export { generateDbObjectId } from './db/generate-db-object-id.js';
|
|
16
|
-
export { generateDbFilterById } from './db/generate-db-filter-by-id.js';
|
|
17
|
-
export { generateDbMutations } from './db/generate-db-mutations.js';
|
|
18
|
-
export { buildDbIndexes } from './db/build-db-indexes.js';
|
|
19
|
-
export { findPreservingIds } from './find-preserving-ids.js';
|
|
9
|
+
export { default as buildObfuscatedFieldsFilter } from './build-obfuscated-fields-filter.js';
|
|
20
10
|
/*
|
|
21
11
|
* Schemas
|
|
22
12
|
*/
|
|
@@ -31,4 +21,65 @@ export { BasePricingDirector } from './director/BasePricingDirector.js';
|
|
|
31
21
|
export { BasePricingSheet } from './director/BasePricingSheet.js';
|
|
32
22
|
export { BaseDiscountAdapter } from './director/BaseDiscountAdapter.js';
|
|
33
23
|
export { BaseDiscountDirector } from './director/BaseDiscountDirector.js';
|
|
24
|
+
/*
|
|
25
|
+
|
|
26
|
+
function resolveBestCountry(
|
|
27
|
+
contextCountry: string,
|
|
28
|
+
headerCountry: string | string[],
|
|
29
|
+
countries: Array<Country>,
|
|
30
|
+
): string;
|
|
31
|
+
function resolveUserRemoteAddress(req: IncomingMessage): {
|
|
32
|
+
remoteAddress: string;
|
|
33
|
+
remotePort: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
function objectInvert(obj: Record<string, string>): Record<string, string>;
|
|
37
|
+
|
|
38
|
+
const systemLocale: Locale;
|
|
39
|
+
|
|
40
|
+
const Schemas: {
|
|
41
|
+
timestampFields: TimestampFields;
|
|
42
|
+
User: SimpleSchema;
|
|
43
|
+
Address: SimpleSchema;
|
|
44
|
+
Contact: SimpleSchema;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// Director
|
|
48
|
+
const BaseAdapter: IBaseAdapter;
|
|
49
|
+
const BaseDirector: <Adapter extends IBaseAdapter>(
|
|
50
|
+
directorName: string,
|
|
51
|
+
options?: {
|
|
52
|
+
adapterSortKey?: string;
|
|
53
|
+
adapterKeyField?: string;
|
|
54
|
+
},
|
|
55
|
+
) => IBaseDirector<Adapter>;
|
|
56
|
+
|
|
57
|
+
const BaseDiscountAdapter: Omit<IDiscountAdapter, 'key' | 'label' | 'version'>;
|
|
58
|
+
const BaseDiscountDirector: (directorName: string) => IDiscountDirector;
|
|
59
|
+
|
|
60
|
+
const BasePricingAdapter: <
|
|
61
|
+
AdapterContext extends BasePricingAdapterContext,
|
|
62
|
+
Calculation extends PricingCalculation,
|
|
63
|
+
>() => IPricingAdapter<AdapterContext, Calculation, IPricingSheet<Calculation>>;
|
|
64
|
+
|
|
65
|
+
const BasePricingDirector: <
|
|
66
|
+
PricingContext extends BasePricingContext,
|
|
67
|
+
AdapterPricingContext extends BasePricingAdapterContext,
|
|
68
|
+
Calculation extends PricingCalculation,
|
|
69
|
+
Adapter extends IPricingAdapter<AdapterPricingContext, Calculation, IPricingSheet<Calculation>>,
|
|
70
|
+
>(
|
|
71
|
+
directorName: string,
|
|
72
|
+
) => IPricingDirector<
|
|
73
|
+
PricingContext,
|
|
74
|
+
Calculation,
|
|
75
|
+
AdapterPricingContext,
|
|
76
|
+
IPricingSheet<Calculation>,
|
|
77
|
+
Adapter
|
|
78
|
+
>;
|
|
79
|
+
|
|
80
|
+
const BasePricingSheet: <Calculation extends PricingCalculation>(
|
|
81
|
+
params: PricingSheetParams<Calculation>,
|
|
82
|
+
) => IBasePricingSheet<Calculation>;
|
|
83
|
+
|
|
84
|
+
*/
|
|
34
85
|
//# sourceMappingURL=utils-index.js.map
|
package/lib/utils-index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils-index.js","sourceRoot":"","sources":["../src/utils-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAEhD,
|
|
1
|
+
{"version":3,"file":"utils-index.js","sourceRoot":"","sources":["../src/utils-index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAEhD,cAAc,qBAAqB,CAAC;AACpC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAE7F;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"main": "lib/utils-index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/utils-index.js",
|
|
@@ -30,17 +30,16 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@unchainedshop/logger": "^2.
|
|
33
|
+
"@unchainedshop/logger": "^2.6.1",
|
|
34
34
|
"abort-controller": "3.0.0",
|
|
35
35
|
"hashids": "^2.3.0",
|
|
36
36
|
"locale": "0.1.0",
|
|
37
|
-
"lru-cache": "^10.0.0",
|
|
38
37
|
"simpl-schema": "=3.2.0"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
|
-
"@types/node": "^20.10
|
|
42
|
-
"@unchainedshop/types": "^2.
|
|
40
|
+
"@types/node": "^20.11.10",
|
|
41
|
+
"@unchainedshop/types": "^2.6.1",
|
|
43
42
|
"jest": "^29.7.0",
|
|
44
|
-
"typescript": "^5.3.
|
|
43
|
+
"typescript": "^5.3.3"
|
|
45
44
|
}
|
|
46
45
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const defaultObfuscatedFields = [
|
|
2
|
+
'password',
|
|
3
|
+
'plainPassword',
|
|
4
|
+
'newPlainPassword',
|
|
5
|
+
'oldPlainPassword',
|
|
6
|
+
'authorization',
|
|
7
|
+
'secret',
|
|
8
|
+
'accesskey',
|
|
9
|
+
'accesstoken',
|
|
10
|
+
'token',
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
const buildObfuscatedFieldsFilter = (blacklistedVariables: string[] = []) => {
|
|
14
|
+
const sensitiveFields = blacklistedVariables || defaultObfuscatedFields;
|
|
15
|
+
|
|
16
|
+
const obfuscateSensitiveFields = (data) => {
|
|
17
|
+
if (!data) return data;
|
|
18
|
+
|
|
19
|
+
if (Array.isArray(data)) {
|
|
20
|
+
return data.map((item) => obfuscateSensitiveFields(item));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (typeof data === 'object') {
|
|
24
|
+
const temp = data;
|
|
25
|
+
Object.keys(temp).forEach((key) => {
|
|
26
|
+
if (sensitiveFields.includes(key)) {
|
|
27
|
+
temp[key] = '******';
|
|
28
|
+
} else {
|
|
29
|
+
temp[key] = obfuscateSensitiveFields(temp[key]);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return temp; // Return the modified copy
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return data; // Return unchanged data for non-objects
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return obfuscateSensitiveFields;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default buildObfuscatedFieldsFilter;
|
package/src/locale-helpers.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Locale as LocaleType, Locales as LocalesType } from 'locale';
|
|
1
2
|
import localePkg from 'locale';
|
|
2
3
|
|
|
3
4
|
const { Locales, Locale } = localePkg;
|
|
@@ -6,7 +7,10 @@ const { UNCHAINED_LANG = 'de', UNCHAINED_COUNTRY = 'CH' } = process.env;
|
|
|
6
7
|
|
|
7
8
|
export const systemLocale = new Locale(`${UNCHAINED_LANG}-${UNCHAINED_COUNTRY}`);
|
|
8
9
|
|
|
9
|
-
export const resolveBestSupported = (
|
|
10
|
+
export const resolveBestSupported = (
|
|
11
|
+
acceptLanguage: string,
|
|
12
|
+
supportedLocales: LocalesType,
|
|
13
|
+
): LocaleType => {
|
|
10
14
|
const acceptLocale = new Locales(acceptLanguage);
|
|
11
15
|
const bestLocale = acceptLocale.best(supportedLocales);
|
|
12
16
|
if (!bestLocale) return systemLocale;
|
package/src/utils-index.test.ts
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { SortDirection } from '@unchainedshop/types/api.js';
|
|
3
1
|
import {
|
|
4
|
-
buildSortOptions,
|
|
5
|
-
checkId,
|
|
6
|
-
findLocalizedText,
|
|
7
|
-
findPreservingIds,
|
|
8
|
-
findUnusedSlug,
|
|
9
|
-
generateDbFilterById,
|
|
10
|
-
generateDbMutations,
|
|
11
|
-
generateDbObjectId,
|
|
12
|
-
generateRandomHash,
|
|
13
|
-
objectInvert,
|
|
14
|
-
pipePromises,
|
|
15
2
|
resolveBestCountry,
|
|
16
3
|
resolveBestSupported,
|
|
17
4
|
resolveUserRemoteAddress,
|
|
@@ -28,76 +15,6 @@ describe('Utils', () => {
|
|
|
28
15
|
expect(resolveBestSupported).toBeInstanceOf(Function)
|
|
29
16
|
expect(resolveUserRemoteAddress).toBeInstanceOf(Function)
|
|
30
17
|
});
|
|
31
|
-
it('functions', () => {
|
|
32
|
-
|
|
33
|
-
expect(findLocalizedText).toBeInstanceOf(Function)
|
|
34
|
-
expect(objectInvert).toBeInstanceOf(Function)
|
|
35
|
-
expect(findPreservingIds).toBeInstanceOf(Function)
|
|
36
|
-
expect(findUnusedSlug).toBeInstanceOf(Function)
|
|
37
|
-
expect(slugify).toBeInstanceOf(Function)
|
|
38
|
-
expect(pipePromises).toBeInstanceOf(Function)
|
|
39
|
-
expect(generateDbFilterById).toBeInstanceOf(Function)
|
|
40
|
-
expect(generateRandomHash).toBeInstanceOf(Function)
|
|
41
|
-
expect(generateDbMutations).toBeInstanceOf(Function)
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe('buildSortOptions', () => {
|
|
45
|
-
it('should return the correct db sort format', () => {
|
|
46
|
-
const sort = [ { key: 'name', value: SortDirection.ASC }, { key: 'age', value: SortDirection.DESC }, ];
|
|
47
|
-
expect(buildSortOptions(sort)).toEqual({ name: 1, age: -1 });
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe('checkId', () => {
|
|
53
|
-
it('with a string value', () => {
|
|
54
|
-
const value = '12345';
|
|
55
|
-
const error = { message: 'Invalid id' };
|
|
56
|
-
|
|
57
|
-
expect(() => checkId(value, error)).not.toThrow();
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('with a non-string value', () => {
|
|
61
|
-
const value: any = 12345;
|
|
62
|
-
const error = { message: 'Invalid id' };
|
|
63
|
-
|
|
64
|
-
expect(() => checkId(value, error)).toThrow('Invalid id');
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('with a different error object', () => {
|
|
68
|
-
const value:any = 12345;
|
|
69
|
-
const error = { message: 'Invalid id', path: 'name' };
|
|
70
|
-
|
|
71
|
-
expect(() => checkId(value, error)).toThrow('Invalid id');
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('without an error object', () => {
|
|
75
|
-
const value: any = 12345;
|
|
76
|
-
|
|
77
|
-
expect(() => checkId(value)).toThrow();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
});
|
|
81
|
-
describe('generateDbObjectId', () => {
|
|
82
|
-
it('generateDbObjectId with default digits', () => {
|
|
83
|
-
const result = generateDbObjectId();
|
|
84
|
-
expect(typeof result).toBe('string');
|
|
85
|
-
expect(result.length).toBe(24);
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('generateDbObjectId with odd digits', () => {
|
|
89
|
-
const result = generateDbObjectId(23);
|
|
90
|
-
expect(typeof result).toBe('string');
|
|
91
|
-
expect(result.length).toBe(23);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('generateDbObjectId with even digits', () => {
|
|
95
|
-
const result = generateDbObjectId(24);
|
|
96
|
-
expect(typeof result).toBe('string');
|
|
97
|
-
expect(result.length).toBe(24);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
})
|
|
101
18
|
|
|
102
19
|
describe('generateHashId', () => {
|
|
103
20
|
it('should create a random hash ', () => {
|
package/src/utils-index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export * as calculation from './calculation.js';
|
|
2
2
|
|
|
3
|
-
export { default as findLocalizedText } from './find-localized-text.js';
|
|
4
3
|
export * from './locale-helpers.js';
|
|
5
4
|
export { default as objectInvert } from './object-invert.js';
|
|
6
5
|
export { default as findUnusedSlug } from './find-unused-slug.js';
|
|
@@ -8,18 +7,7 @@ export { default as slugify } from './slugify.js';
|
|
|
8
7
|
export { default as pipePromises } from './pipe-promises.js';
|
|
9
8
|
export { default as generateRandomHash } from './generate-random-hash.js';
|
|
10
9
|
export { default as randomValueHex } from './random-value-hex.js';
|
|
11
|
-
export { default as
|
|
12
|
-
|
|
13
|
-
/*
|
|
14
|
-
* Db utils
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
export { checkId } from './db/check-id.js';
|
|
18
|
-
export { generateDbObjectId } from './db/generate-db-object-id.js';
|
|
19
|
-
export { generateDbFilterById } from './db/generate-db-filter-by-id.js';
|
|
20
|
-
export { generateDbMutations } from './db/generate-db-mutations.js';
|
|
21
|
-
export { buildDbIndexes } from './db/build-db-indexes.js';
|
|
22
|
-
export { findPreservingIds } from './find-preserving-ids.js';
|
|
10
|
+
export { default as buildObfuscatedFieldsFilter } from './build-obfuscated-fields-filter.js';
|
|
23
11
|
|
|
24
12
|
/*
|
|
25
13
|
* Schemas
|
|
@@ -38,3 +26,65 @@ export { BasePricingDirector } from './director/BasePricingDirector.js';
|
|
|
38
26
|
export { BasePricingSheet } from './director/BasePricingSheet.js';
|
|
39
27
|
export { BaseDiscountAdapter } from './director/BaseDiscountAdapter.js';
|
|
40
28
|
export { BaseDiscountDirector } from './director/BaseDiscountDirector.js';
|
|
29
|
+
|
|
30
|
+
/*
|
|
31
|
+
|
|
32
|
+
function resolveBestCountry(
|
|
33
|
+
contextCountry: string,
|
|
34
|
+
headerCountry: string | string[],
|
|
35
|
+
countries: Array<Country>,
|
|
36
|
+
): string;
|
|
37
|
+
function resolveUserRemoteAddress(req: IncomingMessage): {
|
|
38
|
+
remoteAddress: string;
|
|
39
|
+
remotePort: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function objectInvert(obj: Record<string, string>): Record<string, string>;
|
|
43
|
+
|
|
44
|
+
const systemLocale: Locale;
|
|
45
|
+
|
|
46
|
+
const Schemas: {
|
|
47
|
+
timestampFields: TimestampFields;
|
|
48
|
+
User: SimpleSchema;
|
|
49
|
+
Address: SimpleSchema;
|
|
50
|
+
Contact: SimpleSchema;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// Director
|
|
54
|
+
const BaseAdapter: IBaseAdapter;
|
|
55
|
+
const BaseDirector: <Adapter extends IBaseAdapter>(
|
|
56
|
+
directorName: string,
|
|
57
|
+
options?: {
|
|
58
|
+
adapterSortKey?: string;
|
|
59
|
+
adapterKeyField?: string;
|
|
60
|
+
},
|
|
61
|
+
) => IBaseDirector<Adapter>;
|
|
62
|
+
|
|
63
|
+
const BaseDiscountAdapter: Omit<IDiscountAdapter, 'key' | 'label' | 'version'>;
|
|
64
|
+
const BaseDiscountDirector: (directorName: string) => IDiscountDirector;
|
|
65
|
+
|
|
66
|
+
const BasePricingAdapter: <
|
|
67
|
+
AdapterContext extends BasePricingAdapterContext,
|
|
68
|
+
Calculation extends PricingCalculation,
|
|
69
|
+
>() => IPricingAdapter<AdapterContext, Calculation, IPricingSheet<Calculation>>;
|
|
70
|
+
|
|
71
|
+
const BasePricingDirector: <
|
|
72
|
+
PricingContext extends BasePricingContext,
|
|
73
|
+
AdapterPricingContext extends BasePricingAdapterContext,
|
|
74
|
+
Calculation extends PricingCalculation,
|
|
75
|
+
Adapter extends IPricingAdapter<AdapterPricingContext, Calculation, IPricingSheet<Calculation>>,
|
|
76
|
+
>(
|
|
77
|
+
directorName: string,
|
|
78
|
+
) => IPricingDirector<
|
|
79
|
+
PricingContext,
|
|
80
|
+
Calculation,
|
|
81
|
+
AdapterPricingContext,
|
|
82
|
+
IPricingSheet<Calculation>,
|
|
83
|
+
Adapter
|
|
84
|
+
>;
|
|
85
|
+
|
|
86
|
+
const BasePricingSheet: <Calculation extends PricingCalculation>(
|
|
87
|
+
params: PricingSheetParams<Calculation>,
|
|
88
|
+
) => IBasePricingSheet<Calculation>;
|
|
89
|
+
|
|
90
|
+
*/
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { log, LogLevel } from '@unchainedshop/logger';
|
|
2
|
-
const buildIndexes = (collection, indexes) => Promise.all(indexes.map(async ({ index, options }) => {
|
|
3
|
-
try {
|
|
4
|
-
await collection.createIndex(index, options);
|
|
5
|
-
return false;
|
|
6
|
-
}
|
|
7
|
-
catch (e) {
|
|
8
|
-
log(e, { level: LogLevel.Error });
|
|
9
|
-
return e;
|
|
10
|
-
}
|
|
11
|
-
}));
|
|
12
|
-
export const buildDbIndexes = async (collection, indexes) => {
|
|
13
|
-
let success = true;
|
|
14
|
-
const buildErrors = (await buildIndexes(collection, indexes)).filter(Boolean);
|
|
15
|
-
if (buildErrors.length) {
|
|
16
|
-
// try {
|
|
17
|
-
// const dropError = await collection.dropIndexes();
|
|
18
|
-
// } catch (e) {
|
|
19
|
-
// /* */
|
|
20
|
-
// }
|
|
21
|
-
// if (!dropError) {
|
|
22
|
-
const rebuildErrors = (await buildIndexes(collection, indexes)).filter(Boolean);
|
|
23
|
-
if (rebuildErrors.length) {
|
|
24
|
-
log(`Error building some indexes for ${collection.collectionName}`, {
|
|
25
|
-
level: LogLevel.Error,
|
|
26
|
-
...rebuildErrors,
|
|
27
|
-
});
|
|
28
|
-
success = false;
|
|
29
|
-
}
|
|
30
|
-
// }
|
|
31
|
-
}
|
|
32
|
-
return success;
|
|
33
|
-
};
|
|
34
|
-
//# sourceMappingURL=build-db-indexes.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-db-indexes.js","sourceRoot":"","sources":["../../src/db/build-db-indexes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,YAAY,GAAG,CACnB,UAAyB,EACzB,OAAmB,EACY,EAAE,CACjC,OAAO,CAAC,GAAG,CACT,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;IACvC,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC7C,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QAClC,OAAO,CAAU,CAAC;IACpB,CAAC;AACH,CAAC,CAAC,CACH,CAAC;AAEJ,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,UAAyB,EACzB,OAAmB,EACnB,EAAE;IACF,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,MAAM,WAAW,GAAG,CAAC,MAAM,YAAY,CAAI,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjF,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;QACvB,QAAQ;QACR,sDAAsD;QACtD,gBAAgB;QAChB,UAAU;QACV,IAAI;QAEJ,oBAAoB;QACpB,MAAM,aAAa,GAAG,CAAC,MAAM,YAAY,CAAI,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnF,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;YACzB,GAAG,CAAC,mCAAmC,UAAU,CAAC,cAAc,EAAE,EAAE;gBAClE,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,GAAG,aAAa;aACjB,CAAC,CAAC;YACH,OAAO,GAAG,KAAK,CAAC;QAClB,CAAC;QACD,IAAI;IACN,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const SORT_DIRECTIONS = {
|
|
2
|
-
ASC: 1,
|
|
3
|
-
DESC: -1,
|
|
4
|
-
};
|
|
5
|
-
const buildSortOptions = (sort = []) => {
|
|
6
|
-
const sortBy = {};
|
|
7
|
-
sort?.forEach(({ key, value }) => {
|
|
8
|
-
sortBy[key] = SORT_DIRECTIONS[value];
|
|
9
|
-
});
|
|
10
|
-
return sortBy;
|
|
11
|
-
};
|
|
12
|
-
export default buildSortOptions;
|
|
13
|
-
//# sourceMappingURL=build-sort-option.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-sort-option.js","sourceRoot":"","sources":["../../src/db/build-sort-option.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG;IACtB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,OAA0B,EAAE,EAAQ,EAAE;IAC9D,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QAC/B,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
package/lib/db/check-id.d.ts
DELETED
package/lib/db/check-id.js
DELETED
package/lib/db/check-id.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"check-id.js","sourceRoot":"","sources":["../../src/db/check-id.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,KAAa,EACb,KAKa,EACP,EAAE;IACR,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,KAAK,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-db-filter-by-id.js","sourceRoot":"","sources":["../../src/db/generate-db-filter-by-id.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,EAAW,EACX,QAAmB,EAAE,EACV,EAAE;IACb,MAAM,GAAG,GAAG,EAAE,IAAI,IAAI,CAAC,CAAC,kDAAkD;IAC1E,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;AAC3B,CAAC,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import SimpleSchema from 'simpl-schema';
|
|
2
|
-
import { Collection, _ID, TimestampFields } from '@unchainedshop/types/common.js';
|
|
3
|
-
import { ModuleCreateMutation, ModuleMutations } from '@unchainedshop/types/core.js';
|
|
4
|
-
export declare const generateDbMutations: <T extends TimestampFields & {
|
|
5
|
-
_id?: _ID;
|
|
6
|
-
}>(collection: Collection<T>, schema: SimpleSchema, options?: {
|
|
7
|
-
hasCreateOnly?: boolean;
|
|
8
|
-
permanentlyDeleteByDefault?: boolean;
|
|
9
|
-
}) => ModuleMutations<T> | ModuleCreateMutation<T>;
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { checkId } from './check-id.js';
|
|
2
|
-
import { generateDbObjectId } from './generate-db-object-id.js';
|
|
3
|
-
import { generateDbFilterById } from './generate-db-filter-by-id.js';
|
|
4
|
-
export const generateDbMutations = (collection, schema, options) => {
|
|
5
|
-
if (!collection)
|
|
6
|
-
throw new Error('Collection is missing');
|
|
7
|
-
if (!schema)
|
|
8
|
-
throw new Error('Schema is missing');
|
|
9
|
-
const { hasCreateOnly, permanentlyDeleteByDefault } = options || {
|
|
10
|
-
hasCreateOnly: false,
|
|
11
|
-
permanentlyDeleteByDefault: false,
|
|
12
|
-
};
|
|
13
|
-
const deletePermanently = async (_id) => {
|
|
14
|
-
checkId(_id);
|
|
15
|
-
const filter = generateDbFilterById(_id);
|
|
16
|
-
const result = await collection.deleteOne(filter);
|
|
17
|
-
return result.deletedCount;
|
|
18
|
-
};
|
|
19
|
-
return {
|
|
20
|
-
create: async (doc) => {
|
|
21
|
-
const values = schema.clean(doc);
|
|
22
|
-
values.created = new Date();
|
|
23
|
-
schema.validate(values);
|
|
24
|
-
values._id = doc._id || generateDbObjectId();
|
|
25
|
-
const result = await collection.insertOne(values);
|
|
26
|
-
return result.insertedId;
|
|
27
|
-
},
|
|
28
|
-
update: hasCreateOnly
|
|
29
|
-
? undefined
|
|
30
|
-
: async (_id, doc) => {
|
|
31
|
-
checkId(_id);
|
|
32
|
-
let modifier;
|
|
33
|
-
if (doc?.$set) {
|
|
34
|
-
const values = schema.clean(doc, { isModifier: true });
|
|
35
|
-
modifier = {
|
|
36
|
-
...values,
|
|
37
|
-
$set: {
|
|
38
|
-
...(values.$set || {}),
|
|
39
|
-
updated: new Date(),
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
const values = schema.clean(doc);
|
|
45
|
-
modifier = {
|
|
46
|
-
$set: {
|
|
47
|
-
...values,
|
|
48
|
-
updated: new Date(),
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
schema.validate(modifier, { modifier: true });
|
|
53
|
-
const filter = generateDbFilterById(_id, { deleted: null });
|
|
54
|
-
await collection.updateOne(filter, modifier);
|
|
55
|
-
return _id;
|
|
56
|
-
},
|
|
57
|
-
deletePermanently: hasCreateOnly ? undefined : deletePermanently,
|
|
58
|
-
delete: hasCreateOnly
|
|
59
|
-
? undefined
|
|
60
|
-
: async (_id) => {
|
|
61
|
-
if (permanentlyDeleteByDefault) {
|
|
62
|
-
return deletePermanently(_id);
|
|
63
|
-
}
|
|
64
|
-
checkId(_id);
|
|
65
|
-
const filter = generateDbFilterById(_id, { deleted: null });
|
|
66
|
-
const modifier = { $set: { deleted: new Date() } };
|
|
67
|
-
const values = schema.clean(modifier, { isModifier: true });
|
|
68
|
-
const result = await collection.updateOne(filter, values);
|
|
69
|
-
return result.modifiedCount;
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
//# sourceMappingURL=generate-db-mutations.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-db-mutations.js","sourceRoot":"","sources":["../../src/db/generate-db-mutations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
// Source: https://github.com/meteor/meteor/blob/devel/packages/random/NodeRandomGenerator.js
|
|
3
|
-
/**
|
|
4
|
-
* @name Random.hexString
|
|
5
|
-
* @summary Return a random string of `n` hexadecimal digits.
|
|
6
|
-
* @locus Anywhere
|
|
7
|
-
* @param {Number} n Length of the string
|
|
8
|
-
*/
|
|
9
|
-
export const generateDbObjectId = (digits = 24) => {
|
|
10
|
-
const numBytes = Math.ceil(digits / 2);
|
|
11
|
-
let bytes;
|
|
12
|
-
// Try to get cryptographically strong randomness. Fall back to
|
|
13
|
-
// non-cryptographically strong if not available.
|
|
14
|
-
try {
|
|
15
|
-
bytes = crypto.randomBytes(numBytes);
|
|
16
|
-
}
|
|
17
|
-
catch (e) {
|
|
18
|
-
// XXX should re-throw any error except insufficient entropy
|
|
19
|
-
bytes = crypto.pseudoRandomBytes(numBytes);
|
|
20
|
-
}
|
|
21
|
-
const result = bytes.toString('hex');
|
|
22
|
-
// If the number of digits is odd, we'll have generated an extra 4 bits
|
|
23
|
-
// of randomness, so we need to trim the last digit.
|
|
24
|
-
return result.substring(0, digits);
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=generate-db-object-id.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate-db-object-id.js","sourceRoot":"","sources":["../../src/db/generate-db-object-id.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,6FAA6F;AAC7F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,GAAG,EAAE,EAAU,EAAE;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,KAAK,CAAC;IACV,+DAA+D;IAC/D,iDAAiD;IACjD,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,4DAA4D;QAC5D,KAAK,GAAG,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrC,uEAAuE;IACvE,oDAAoD;IACpD,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import 'abort-controller/polyfill.js';
|
|
2
|
-
import { Collection, Filter, Locale, Document } from '@unchainedshop/types/common.js';
|
|
3
|
-
declare const findLocalizedText: <T extends Document>(collection: Collection<T>, selector: Filter<T>, locale: Locale) => Promise<T>;
|
|
4
|
-
export default findLocalizedText;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import 'abort-controller/polyfill.js';
|
|
2
|
-
import { LRUCache } from 'lru-cache';
|
|
3
|
-
import { systemLocale } from './locale-helpers.js';
|
|
4
|
-
const { NODE_ENV } = process.env;
|
|
5
|
-
const ttl = NODE_ENV === 'production' ? 1000 * 10 : 0; // 10 seconds or 0 seconds
|
|
6
|
-
const textCache = new LRUCache({ max: 50000, ttl });
|
|
7
|
-
const extendSelectorWithLocale = (selector, locale) => {
|
|
8
|
-
const localeSelector = {
|
|
9
|
-
locale: { $in: [locale.normalized, locale.language] },
|
|
10
|
-
};
|
|
11
|
-
return { ...localeSelector, ...selector };
|
|
12
|
-
};
|
|
13
|
-
const findLocalizedText = async (collection, selector, locale) => {
|
|
14
|
-
const cacheKey = JSON.stringify({
|
|
15
|
-
n: collection.collectionName, // eslint-disable-line
|
|
16
|
-
s: selector,
|
|
17
|
-
l: locale,
|
|
18
|
-
});
|
|
19
|
-
const cachedText = textCache.get(cacheKey);
|
|
20
|
-
if (cachedText)
|
|
21
|
-
return cachedText;
|
|
22
|
-
const exactTranslation = await collection.findOne(extendSelectorWithLocale(selector, locale), {
|
|
23
|
-
sort: { updated: -1 },
|
|
24
|
-
});
|
|
25
|
-
if (exactTranslation) {
|
|
26
|
-
textCache.set(cacheKey, exactTranslation);
|
|
27
|
-
return exactTranslation;
|
|
28
|
-
}
|
|
29
|
-
if (systemLocale.normalized !== locale.normalized) {
|
|
30
|
-
const fallbackTranslation = await collection.findOne(extendSelectorWithLocale(selector, systemLocale), {
|
|
31
|
-
sort: { updated: -1 },
|
|
32
|
-
});
|
|
33
|
-
if (fallbackTranslation) {
|
|
34
|
-
textCache.set(cacheKey, fallbackTranslation);
|
|
35
|
-
return fallbackTranslation;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
const foundText = await collection.findOne(selector, {
|
|
39
|
-
sort: { updated: -1 },
|
|
40
|
-
});
|
|
41
|
-
textCache.set(cacheKey, foundText);
|
|
42
|
-
return foundText;
|
|
43
|
-
};
|
|
44
|
-
export default findLocalizedText;
|
|
45
|
-
//# sourceMappingURL=find-localized-text.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-localized-text.js","sourceRoot":"","sources":["../src/find-localized-text.ts"],"names":[],"mappings":"AAAA,OAAO,8BAA8B,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEjC,MAAM,GAAG,GAAG,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B;AAEjF,MAAM,SAAS,GAAG,IAAI,QAAQ,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AAEpD,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;IACpD,MAAM,cAAc,GAAG;QACrB,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;KACtD,CAAC;IACF,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC5C,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,KAAK,EAC7B,UAAyB,EACzB,QAAmB,EACnB,MAAc,EACF,EAAE;IACd,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC9B,CAAC,EAAE,UAAU,CAAC,cAAc,EAAE,sBAAsB;QACpD,CAAC,EAAE,QAAQ;QACX,CAAC,EAAE,MAAM;KACV,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,UAAU;QAAE,OAAO,UAAe,CAAC;IAEvC,MAAM,gBAAgB,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;QAC5F,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;KACtB,CAAC,CAAC;IACH,IAAI,gBAAgB,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;QAC1C,OAAO,gBAAqB,CAAC;IAC/B,CAAC;IAED,IAAI,YAAY,CAAC,UAAU,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC;QAClD,MAAM,mBAAmB,GAAG,MAAM,UAAU,CAAC,OAAO,CAClD,wBAAwB,CAAC,QAAQ,EAAE,YAAY,CAAC,EAChD;YACE,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;SACtB,CACF,CAAC;QACF,IAAI,mBAAmB,EAAE,CAAC;YACxB,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;YAC7C,OAAO,mBAAwB,CAAC;QAClC,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE;QACnD,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE;KACtB,CAAC,CAAC;IACH,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnC,OAAO,SAAc,CAAC;AACxB,CAAC,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const { AMAZON_DOCUMENTDB_COMPAT_MODE } = process.env;
|
|
2
|
-
const sortByIndex = {
|
|
3
|
-
index: 1,
|
|
4
|
-
};
|
|
5
|
-
const sortBySequence = {
|
|
6
|
-
sequence: 1,
|
|
7
|
-
};
|
|
8
|
-
const defaultSort = AMAZON_DOCUMENTDB_COMPAT_MODE ? sortBySequence : sortByIndex;
|
|
9
|
-
export const findPreservingIds = (collection) => async (selector, ids, options) => {
|
|
10
|
-
const { skip, limit, sort = defaultSort } = options || {};
|
|
11
|
-
const filteredSelector = {
|
|
12
|
-
...selector,
|
|
13
|
-
_id: { $in: ids },
|
|
14
|
-
};
|
|
15
|
-
const filteredPipeline = [
|
|
16
|
-
{
|
|
17
|
-
$match: filteredSelector,
|
|
18
|
-
},
|
|
19
|
-
typeof sort === 'object' &&
|
|
20
|
-
'index' in sort && {
|
|
21
|
-
$addFields: {
|
|
22
|
-
index: { $indexOfArray: [ids, '$_id'] },
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
sort && { $sort: sort },
|
|
26
|
-
skip && { $skip: skip },
|
|
27
|
-
limit && { $limit: limit },
|
|
28
|
-
].filter(Boolean);
|
|
29
|
-
const aggregationPointer = collection.aggregate(filteredPipeline);
|
|
30
|
-
const items = await aggregationPointer.toArray();
|
|
31
|
-
return items;
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=find-preserving-ids.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-preserving-ids.js","sourceRoot":"","sources":["../src/find-preserving-ids.ts"],"names":[],"mappings":"AAEA,MAAM,EAAE,6BAA6B,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;AAEtD,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,cAAc,GAAG;IACrB,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,MAAM,WAAW,GAAG,6BAA6B,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAC5B,CACE,UAAyB,EAC4D,EAAE,CACzF,KAAK,EAAE,QAAe,EAAE,GAAkB,EAAE,OAAqB,EAAqB,EAAE;IACtF,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,GAAG,WAAW,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAC1D,MAAM,gBAAgB,GAAG;QACvB,GAAG,QAAQ;QACX,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE;KAClB,CAAC;IAEF,MAAM,gBAAgB,GAAG;QACvB;YACE,MAAM,EAAE,gBAAgB;SACzB;QACD,OAAO,IAAI,KAAK,QAAQ;YACtB,OAAO,IAAI,IAAI,IAAI;YACjB,UAAU,EAAE;gBACV,KAAK,EAAE,EAAE,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE;aACxC;SACF;QACH,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACvB,IAAI,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACvB,KAAK,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE;KAC3B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElB,MAAM,kBAAkB,GAAG,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,CAAC;IACjD,OAAO,KAAiB,CAAC;AAC3B,CAAC,CAAC"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { Collection, Indexes, Document } from '@unchainedshop/types/common.js';
|
|
2
|
-
import { log, LogLevel } from '@unchainedshop/logger';
|
|
3
|
-
|
|
4
|
-
const buildIndexes = <T>(
|
|
5
|
-
collection: Collection<T>,
|
|
6
|
-
indexes: Indexes<T>,
|
|
7
|
-
): Promise<Array<false | Error>> =>
|
|
8
|
-
Promise.all(
|
|
9
|
-
indexes.map(async ({ index, options }) => {
|
|
10
|
-
try {
|
|
11
|
-
await collection.createIndex(index, options);
|
|
12
|
-
return false;
|
|
13
|
-
} catch (e: any) {
|
|
14
|
-
log(e, { level: LogLevel.Error });
|
|
15
|
-
return e as Error;
|
|
16
|
-
}
|
|
17
|
-
}),
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
export const buildDbIndexes = async <T extends Document>(
|
|
21
|
-
collection: Collection<T>,
|
|
22
|
-
indexes: Indexes<T>,
|
|
23
|
-
) => {
|
|
24
|
-
let success = true;
|
|
25
|
-
const buildErrors = (await buildIndexes<T>(collection, indexes)).filter(Boolean);
|
|
26
|
-
|
|
27
|
-
if (buildErrors.length) {
|
|
28
|
-
// try {
|
|
29
|
-
// const dropError = await collection.dropIndexes();
|
|
30
|
-
// } catch (e) {
|
|
31
|
-
// /* */
|
|
32
|
-
// }
|
|
33
|
-
|
|
34
|
-
// if (!dropError) {
|
|
35
|
-
const rebuildErrors = (await buildIndexes<T>(collection, indexes)).filter(Boolean);
|
|
36
|
-
|
|
37
|
-
if (rebuildErrors.length) {
|
|
38
|
-
log(`Error building some indexes for ${collection.collectionName}`, {
|
|
39
|
-
level: LogLevel.Error,
|
|
40
|
-
...rebuildErrors,
|
|
41
|
-
});
|
|
42
|
-
success = false;
|
|
43
|
-
}
|
|
44
|
-
// }
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return success;
|
|
48
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { SortOption } from '@unchainedshop/types/api.js';
|
|
2
|
-
import { Sort } from '@unchainedshop/types/common.js';
|
|
3
|
-
|
|
4
|
-
const SORT_DIRECTIONS = {
|
|
5
|
-
ASC: 1,
|
|
6
|
-
DESC: -1,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const buildSortOptions = (sort: Array<SortOption> = []): Sort => {
|
|
10
|
-
const sortBy = {};
|
|
11
|
-
sort?.forEach(({ key, value }) => {
|
|
12
|
-
sortBy[key] = SORT_DIRECTIONS[value];
|
|
13
|
-
});
|
|
14
|
-
return sortBy;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
export default buildSortOptions;
|
package/src/db/check-id.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Filter, _ID } from '@unchainedshop/types/common.js';
|
|
2
|
-
|
|
3
|
-
export const generateDbFilterById = <T extends { _id?: _ID }>(
|
|
4
|
-
id: unknown,
|
|
5
|
-
query: Filter<T> = {},
|
|
6
|
-
): Filter<T> => {
|
|
7
|
-
const _id = id || null; // never undefined, else it will get the first one
|
|
8
|
-
return { _id, ...query };
|
|
9
|
-
};
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import SimpleSchema from 'simpl-schema';
|
|
2
|
-
import { Collection, _ID, Update, TimestampFields } from '@unchainedshop/types/common.js';
|
|
3
|
-
import { ModuleCreateMutation, ModuleMutations } from '@unchainedshop/types/core.js';
|
|
4
|
-
|
|
5
|
-
import { checkId } from './check-id.js';
|
|
6
|
-
import { generateDbObjectId } from './generate-db-object-id.js';
|
|
7
|
-
import { generateDbFilterById } from './generate-db-filter-by-id.js';
|
|
8
|
-
|
|
9
|
-
export const generateDbMutations = <T extends TimestampFields & { _id?: _ID }>(
|
|
10
|
-
collection: Collection<T>,
|
|
11
|
-
schema: SimpleSchema,
|
|
12
|
-
options?: {
|
|
13
|
-
hasCreateOnly?: boolean;
|
|
14
|
-
permanentlyDeleteByDefault?: boolean;
|
|
15
|
-
},
|
|
16
|
-
): ModuleMutations<T> | ModuleCreateMutation<T> => {
|
|
17
|
-
if (!collection) throw new Error('Collection is missing');
|
|
18
|
-
if (!schema) throw new Error('Schema is missing');
|
|
19
|
-
|
|
20
|
-
const { hasCreateOnly, permanentlyDeleteByDefault } = options || {
|
|
21
|
-
hasCreateOnly: false,
|
|
22
|
-
permanentlyDeleteByDefault: false,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const deletePermanently = async (_id) => {
|
|
26
|
-
checkId(_id);
|
|
27
|
-
const filter = generateDbFilterById<T>(_id);
|
|
28
|
-
const result = await collection.deleteOne(filter);
|
|
29
|
-
return result.deletedCount;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
return {
|
|
33
|
-
create: async (doc) => {
|
|
34
|
-
const values: any = schema.clean(doc);
|
|
35
|
-
values.created = new Date();
|
|
36
|
-
schema.validate(values);
|
|
37
|
-
values._id = doc._id || generateDbObjectId();
|
|
38
|
-
|
|
39
|
-
const result = await collection.insertOne(values);
|
|
40
|
-
return result.insertedId as string;
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
update: hasCreateOnly
|
|
44
|
-
? undefined
|
|
45
|
-
: async (_id, doc) => {
|
|
46
|
-
checkId(_id);
|
|
47
|
-
|
|
48
|
-
let modifier: Update<T>;
|
|
49
|
-
|
|
50
|
-
if ((doc as Update<T>)?.$set) {
|
|
51
|
-
const values: any = schema.clean(doc as any, { isModifier: true });
|
|
52
|
-
modifier = {
|
|
53
|
-
...values,
|
|
54
|
-
$set: {
|
|
55
|
-
...(values.$set || {}),
|
|
56
|
-
updated: new Date(),
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
} else {
|
|
60
|
-
const values: any = schema.clean(doc as any);
|
|
61
|
-
modifier = {
|
|
62
|
-
$set: {
|
|
63
|
-
...values,
|
|
64
|
-
updated: new Date(),
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
schema.validate(modifier, { modifier: true });
|
|
70
|
-
const filter = generateDbFilterById<T>(_id, { deleted: null });
|
|
71
|
-
await collection.updateOne(filter, modifier);
|
|
72
|
-
|
|
73
|
-
return _id;
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
deletePermanently: hasCreateOnly ? undefined : deletePermanently,
|
|
77
|
-
|
|
78
|
-
delete: hasCreateOnly
|
|
79
|
-
? undefined
|
|
80
|
-
: async (_id) => {
|
|
81
|
-
if (permanentlyDeleteByDefault) {
|
|
82
|
-
return deletePermanently(_id);
|
|
83
|
-
}
|
|
84
|
-
checkId(_id);
|
|
85
|
-
const filter = generateDbFilterById<T>(_id, { deleted: null });
|
|
86
|
-
const modifier = { $set: { deleted: new Date() } };
|
|
87
|
-
const values = schema.clean(modifier, { isModifier: true });
|
|
88
|
-
const result = await collection.updateOne(filter, values);
|
|
89
|
-
|
|
90
|
-
return result.modifiedCount;
|
|
91
|
-
},
|
|
92
|
-
};
|
|
93
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
|
|
3
|
-
// Source: https://github.com/meteor/meteor/blob/devel/packages/random/NodeRandomGenerator.js
|
|
4
|
-
/**
|
|
5
|
-
* @name Random.hexString
|
|
6
|
-
* @summary Return a random string of `n` hexadecimal digits.
|
|
7
|
-
* @locus Anywhere
|
|
8
|
-
* @param {Number} n Length of the string
|
|
9
|
-
*/
|
|
10
|
-
export const generateDbObjectId = (digits = 24): string => {
|
|
11
|
-
const numBytes = Math.ceil(digits / 2);
|
|
12
|
-
let bytes;
|
|
13
|
-
// Try to get cryptographically strong randomness. Fall back to
|
|
14
|
-
// non-cryptographically strong if not available.
|
|
15
|
-
try {
|
|
16
|
-
bytes = crypto.randomBytes(numBytes);
|
|
17
|
-
} catch (e) {
|
|
18
|
-
// XXX should re-throw any error except insufficient entropy
|
|
19
|
-
bytes = crypto.pseudoRandomBytes(numBytes);
|
|
20
|
-
}
|
|
21
|
-
const result = bytes.toString('hex');
|
|
22
|
-
// If the number of digits is odd, we'll have generated an extra 4 bits
|
|
23
|
-
// of randomness, so we need to trim the last digit.
|
|
24
|
-
return result.substring(0, digits);
|
|
25
|
-
};
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import 'abort-controller/polyfill.js';
|
|
2
|
-
import { LRUCache } from 'lru-cache';
|
|
3
|
-
import { Collection, Filter, Locale, Document } from '@unchainedshop/types/common.js';
|
|
4
|
-
import { systemLocale } from './locale-helpers.js';
|
|
5
|
-
|
|
6
|
-
const { NODE_ENV } = process.env;
|
|
7
|
-
|
|
8
|
-
const ttl = NODE_ENV === 'production' ? 1000 * 10 : 0; // 10 seconds or 0 seconds
|
|
9
|
-
|
|
10
|
-
const textCache = new LRUCache({ max: 50000, ttl });
|
|
11
|
-
|
|
12
|
-
const extendSelectorWithLocale = (selector, locale) => {
|
|
13
|
-
const localeSelector = {
|
|
14
|
-
locale: { $in: [locale.normalized, locale.language] },
|
|
15
|
-
};
|
|
16
|
-
return { ...localeSelector, ...selector };
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const findLocalizedText = async <T extends Document>(
|
|
20
|
-
collection: Collection<T>,
|
|
21
|
-
selector: Filter<T>,
|
|
22
|
-
locale: Locale,
|
|
23
|
-
): Promise<T> => {
|
|
24
|
-
const cacheKey = JSON.stringify({
|
|
25
|
-
n: collection.collectionName, // eslint-disable-line
|
|
26
|
-
s: selector,
|
|
27
|
-
l: locale,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const cachedText = textCache.get(cacheKey);
|
|
31
|
-
|
|
32
|
-
if (cachedText) return cachedText as T;
|
|
33
|
-
|
|
34
|
-
const exactTranslation = await collection.findOne(extendSelectorWithLocale(selector, locale), {
|
|
35
|
-
sort: { updated: -1 },
|
|
36
|
-
});
|
|
37
|
-
if (exactTranslation) {
|
|
38
|
-
textCache.set(cacheKey, exactTranslation);
|
|
39
|
-
return exactTranslation as T;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (systemLocale.normalized !== locale.normalized) {
|
|
43
|
-
const fallbackTranslation = await collection.findOne(
|
|
44
|
-
extendSelectorWithLocale(selector, systemLocale),
|
|
45
|
-
{
|
|
46
|
-
sort: { updated: -1 },
|
|
47
|
-
},
|
|
48
|
-
);
|
|
49
|
-
if (fallbackTranslation) {
|
|
50
|
-
textCache.set(cacheKey, fallbackTranslation);
|
|
51
|
-
return fallbackTranslation as T;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const foundText = await collection.findOne(selector, {
|
|
56
|
-
sort: { updated: -1 },
|
|
57
|
-
});
|
|
58
|
-
textCache.set(cacheKey, foundText);
|
|
59
|
-
return foundText as T;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export default findLocalizedText;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { Collection, FindOptions, Query } from '@unchainedshop/types/common.js';
|
|
2
|
-
|
|
3
|
-
const { AMAZON_DOCUMENTDB_COMPAT_MODE } = process.env;
|
|
4
|
-
|
|
5
|
-
const sortByIndex = {
|
|
6
|
-
index: 1,
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
const sortBySequence = {
|
|
10
|
-
sequence: 1,
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
const defaultSort = AMAZON_DOCUMENTDB_COMPAT_MODE ? sortBySequence : sortByIndex;
|
|
14
|
-
|
|
15
|
-
export const findPreservingIds =
|
|
16
|
-
<T>(
|
|
17
|
-
collection: Collection<T>,
|
|
18
|
-
): ((selector: Query, ids: Array<string>, options?: FindOptions) => Promise<Array<T>>) =>
|
|
19
|
-
async (selector: Query, ids: Array<string>, options?: FindOptions): Promise<Array<T>> => {
|
|
20
|
-
const { skip, limit, sort = defaultSort } = options || {};
|
|
21
|
-
const filteredSelector = {
|
|
22
|
-
...selector,
|
|
23
|
-
_id: { $in: ids },
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const filteredPipeline = [
|
|
27
|
-
{
|
|
28
|
-
$match: filteredSelector,
|
|
29
|
-
},
|
|
30
|
-
typeof sort === 'object' &&
|
|
31
|
-
'index' in sort && {
|
|
32
|
-
$addFields: {
|
|
33
|
-
index: { $indexOfArray: [ids, '$_id'] },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
sort && { $sort: sort },
|
|
37
|
-
skip && { $skip: skip },
|
|
38
|
-
limit && { $limit: limit },
|
|
39
|
-
].filter(Boolean);
|
|
40
|
-
|
|
41
|
-
const aggregationPointer = collection.aggregate(filteredPipeline);
|
|
42
|
-
const items = await aggregationPointer.toArray();
|
|
43
|
-
return items as Array<T>;
|
|
44
|
-
};
|