@unchainedshop/utils 4.3.3 → 4.4.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/README.md +112 -2
- package/lib/build-obfuscated-fields-filter.d.ts +0 -1
- package/lib/build-obfuscated-fields-filter.js +2 -3
- package/lib/calculation.d.ts +0 -1
- package/lib/calculation.js +0 -1
- package/lib/ch/addressToString.d.ts +0 -1
- package/lib/ch/addressToString.js +0 -1
- package/lib/ch/index.d.ts +2 -3
- package/lib/ch/index.js +2 -4
- package/lib/ch/priceToString.d.ts +0 -1
- package/lib/ch/priceToString.js +0 -1
- package/lib/director/BaseAdapter.d.ts +1 -2
- package/lib/director/BaseAdapter.js +2 -3
- package/lib/director/BaseDirector.d.ts +1 -2
- package/lib/director/BaseDirector.js +0 -1
- package/lib/find-unused-slug.d.ts +0 -1
- package/lib/find-unused-slug.js +0 -1
- package/lib/generate-random-hash.d.ts +0 -1
- package/lib/generate-random-hash.js +0 -1
- package/lib/locale-helpers.d.ts +0 -1
- package/lib/locale-helpers.js +0 -1
- package/lib/object-invert.d.ts +0 -1
- package/lib/object-invert.js +0 -1
- package/lib/pipe-promises.d.ts +0 -1
- package/lib/pipe-promises.js +0 -1
- package/lib/sha1.d.ts +0 -1
- package/lib/sha1.js +0 -2
- package/lib/sha256.d.ts +0 -1
- package/lib/sha256.js +0 -2
- package/lib/slugify.d.ts +0 -1
- package/lib/slugify.js +5 -6
- package/lib/utils-index.d.ts +17 -17
- package/lib/utils-index.js +16 -18
- package/package.json +5 -5
- package/lib/build-obfuscated-fields-filter.d.ts.map +0 -1
- package/lib/build-obfuscated-fields-filter.js.map +0 -1
- package/lib/calculation.d.ts.map +0 -1
- package/lib/calculation.js.map +0 -1
- package/lib/ch/addressToString.d.ts.map +0 -1
- package/lib/ch/addressToString.js.map +0 -1
- package/lib/ch/index.d.ts.map +0 -1
- package/lib/ch/index.js.map +0 -1
- package/lib/ch/priceToString.d.ts.map +0 -1
- package/lib/ch/priceToString.js.map +0 -1
- package/lib/director/BaseAdapter.d.ts.map +0 -1
- package/lib/director/BaseAdapter.js.map +0 -1
- package/lib/director/BaseDirector.d.ts.map +0 -1
- package/lib/director/BaseDirector.js.map +0 -1
- package/lib/director/BaseDiscountAdapter.d.ts +0 -3
- package/lib/director/BaseDiscountAdapter.d.ts.map +0 -1
- package/lib/director/BaseDiscountAdapter.js +0 -48
- package/lib/director/BaseDiscountAdapter.js.map +0 -1
- package/lib/director/BaseDiscountDirector.d.ts +0 -3
- package/lib/director/BaseDiscountDirector.d.ts.map +0 -1
- package/lib/director/BaseDiscountDirector.js +0 -50
- package/lib/director/BaseDiscountDirector.js.map +0 -1
- package/lib/director/BasePricingAdapter.d.ts +0 -3
- package/lib/director/BasePricingAdapter.d.ts.map +0 -1
- package/lib/director/BasePricingAdapter.js +0 -25
- package/lib/director/BasePricingAdapter.js.map +0 -1
- package/lib/director/BasePricingDirector.d.ts +0 -3
- package/lib/director/BasePricingDirector.d.ts.map +0 -1
- package/lib/director/BasePricingDirector.js +0 -61
- package/lib/director/BasePricingDirector.js.map +0 -1
- package/lib/director/BasePricingSheet.d.ts +0 -3
- package/lib/director/BasePricingSheet.d.ts.map +0 -1
- package/lib/director/BasePricingSheet.js +0 -54
- package/lib/director/BasePricingSheet.js.map +0 -1
- package/lib/find-unused-slug.d.ts.map +0 -1
- package/lib/find-unused-slug.js.map +0 -1
- package/lib/generate-random-hash.d.ts.map +0 -1
- package/lib/generate-random-hash.js.map +0 -1
- package/lib/locale-helpers.d.ts.map +0 -1
- package/lib/locale-helpers.js.map +0 -1
- package/lib/object-invert.d.ts.map +0 -1
- package/lib/object-invert.js.map +0 -1
- package/lib/pipe-promises.d.ts.map +0 -1
- package/lib/pipe-promises.js.map +0 -1
- package/lib/random-value-hex.d.ts +0 -2
- package/lib/random-value-hex.d.ts.map +0 -1
- package/lib/random-value-hex.js +0 -8
- package/lib/random-value-hex.js.map +0 -1
- package/lib/schemas/AddressSchema.d.ts +0 -3
- package/lib/schemas/AddressSchema.d.ts.map +0 -1
- package/lib/schemas/AddressSchema.js +0 -13
- package/lib/schemas/AddressSchema.js.map +0 -1
- package/lib/schemas/ContactSchema.d.ts +0 -3
- package/lib/schemas/ContactSchema.d.ts.map +0 -1
- package/lib/schemas/ContactSchema.js +0 -6
- package/lib/schemas/ContactSchema.js.map +0 -1
- package/lib/schemas/UsersSchema.d.ts +0 -5
- package/lib/schemas/UsersSchema.d.ts.map +0 -1
- package/lib/schemas/UsersSchema.js +0 -52
- package/lib/schemas/UsersSchema.js.map +0 -1
- package/lib/schemas/commonSchemaFields.d.ts +0 -35
- package/lib/schemas/commonSchemaFields.d.ts.map +0 -1
- package/lib/schemas/commonSchemaFields.js +0 -28
- package/lib/schemas/commonSchemaFields.js.map +0 -1
- package/lib/schemas/index.d.ts +0 -43
- package/lib/schemas/index.d.ts.map +0 -1
- package/lib/schemas/index.js +0 -14
- package/lib/schemas/index.js.map +0 -1
- package/lib/sha1.d.ts.map +0 -1
- package/lib/sha1.js.map +0 -1
- package/lib/sha256.d.ts.map +0 -1
- package/lib/sha256.js.map +0 -1
- package/lib/slugify.d.ts.map +0 -1
- package/lib/slugify.js.map +0 -1
- package/lib/utils-index.d.ts.map +0 -1
- package/lib/utils-index.js.map +0 -1
- package/src/build-obfuscated-fields-filter.ts +0 -41
- package/src/calculation.test.ts +0 -171
- package/src/calculation.ts +0 -43
- package/src/ch/addressToString.ts +0 -25
- package/src/ch/index.ts +0 -3
- package/src/ch/priceToString.ts +0 -6
- package/src/director/BaseAdapter.ts +0 -25
- package/src/director/BaseDirector.ts +0 -40
- package/src/director/base-director.test.ts +0 -112
- package/src/find-unused-slug.ts +0 -39
- package/src/generate-random-hash.ts +0 -8
- package/src/locale-helpers.ts +0 -79
- package/src/object-invert.ts +0 -8
- package/src/pipe-promises.ts +0 -2
- package/src/sha1.ts +0 -6
- package/src/sha256.ts +0 -8
- package/src/slugify.ts +0 -10
- package/src/utils-index.test.ts +0 -58
- package/src/utils-index.ts +0 -45
- package/tsconfig.json +0 -10
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
const defaultObfuscatedFields = [
|
|
2
|
-
'password',
|
|
3
|
-
'newPassword',
|
|
4
|
-
'oldPassword',
|
|
5
|
-
'authorization',
|
|
6
|
-
'secret',
|
|
7
|
-
'accesskey',
|
|
8
|
-
'accesstoken',
|
|
9
|
-
'token',
|
|
10
|
-
];
|
|
11
|
-
|
|
12
|
-
const buildObfuscatedFieldsFilter = (blacklistedVariables: string[] = []) => {
|
|
13
|
-
const sensitiveFields = blacklistedVariables || defaultObfuscatedFields;
|
|
14
|
-
|
|
15
|
-
const obfuscateSensitiveFields = (data) => {
|
|
16
|
-
if (!data) return data;
|
|
17
|
-
|
|
18
|
-
if (Array.isArray(data)) {
|
|
19
|
-
return data.map((item) => obfuscateSensitiveFields(item));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (typeof data === 'object') {
|
|
23
|
-
const temp = data;
|
|
24
|
-
Object.keys(temp).forEach((key) => {
|
|
25
|
-
if (sensitiveFields.includes(key)) {
|
|
26
|
-
temp[key] = '******';
|
|
27
|
-
} else {
|
|
28
|
-
temp[key] = obfuscateSensitiveFields(temp[key]);
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
return temp; // Return the modified copy
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return data; // Return unchanged data for non-objects
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
return obfuscateSensitiveFields;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
export default buildObfuscatedFieldsFilter;
|
package/src/calculation.test.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
applyRate,
|
|
6
|
-
roundToNext,
|
|
7
|
-
resolveAmountAndTax,
|
|
8
|
-
applyDiscountToMultipleShares,
|
|
9
|
-
calculateAmountToSplit,
|
|
10
|
-
} from './calculation';
|
|
11
|
-
|
|
12
|
-
describe('roundToNext', () => {
|
|
13
|
-
it('rounds to the next multiple of precision correctly when the value is positive', () => {
|
|
14
|
-
assert.strictEqual(roundToNext(5, 2), 6);
|
|
15
|
-
assert.strictEqual(roundToNext(10, 5), 10);
|
|
16
|
-
assert.strictEqual(roundToNext(13, 5), 15);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('rounds to the next multiple of precision correctly when the value is negative', () => {
|
|
20
|
-
assert.strictEqual(roundToNext(-5, 2), -4);
|
|
21
|
-
assert.strictEqual(roundToNext(-10, 5), -10);
|
|
22
|
-
assert.strictEqual(roundToNext(-13, 5), -10);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('returns 0 when the value is 0', () => {
|
|
26
|
-
assert.strictEqual(roundToNext(0, 5), 0);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('returns the same value when the precision is 1', () => {
|
|
30
|
-
assert.strictEqual(roundToNext(5, 1), 5);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
describe('resolveAmountAndTax', () => {
|
|
35
|
-
it('ratio is 0 and taxDivisor is 0', () => {
|
|
36
|
-
const result = resolveAmountAndTax({ ratio: 0, taxDivisor: 0 }, 100);
|
|
37
|
-
assert.deepStrictEqual(result, [0, 0]);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('ratio is not 0 and taxDivisor is 0', () => {
|
|
41
|
-
const result = resolveAmountAndTax({ ratio: 0.5, taxDivisor: 0 }, 100);
|
|
42
|
-
assert.deepStrictEqual(result, [50, 0]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('ratio is 0 and taxDivisor is not 0', () => {
|
|
46
|
-
const result = resolveAmountAndTax({ ratio: 0, taxDivisor: 2 }, 100);
|
|
47
|
-
assert.deepStrictEqual(result, [0, 0]);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('ratio and taxDivisor are not 0', () => {
|
|
51
|
-
const result = resolveAmountAndTax({ ratio: 0.5, taxDivisor: 2 }, 100);
|
|
52
|
-
assert.deepStrictEqual(result, [50, 25]);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('ratio and taxDivisor are not finite number', () => {
|
|
56
|
-
const result = resolveAmountAndTax({ ratio: Number.NaN, taxDivisor: Number.NaN }, 100);
|
|
57
|
-
assert.deepStrictEqual(result, [0, 0]);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe('applyDiscountToMultipleShares', () => {
|
|
62
|
-
it('shares are empty', () => {
|
|
63
|
-
const result = applyDiscountToMultipleShares([], 100);
|
|
64
|
-
assert.deepStrictEqual(result, [0, 0]);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('shares have one share', () => {
|
|
68
|
-
const shares = [{ ratio: 0.5, taxDivisor: 2 }];
|
|
69
|
-
const result = applyDiscountToMultipleShares(shares, 100);
|
|
70
|
-
assert.deepStrictEqual(result, [50, 25]);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('shares have multiple shares', () => {
|
|
74
|
-
const shares = [
|
|
75
|
-
{ ratio: 0.5, taxDivisor: 2 },
|
|
76
|
-
{ ratio: 0.2, taxDivisor: 1.5 },
|
|
77
|
-
];
|
|
78
|
-
const result = applyDiscountToMultipleShares(shares, 100);
|
|
79
|
-
assert.deepStrictEqual(result, [70, 31.666666666666664]);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
describe('applyRate', () => {
|
|
84
|
-
it('applies the rate correctly when a rate is provided', () => {
|
|
85
|
-
const configuration = {
|
|
86
|
-
rate: 0.1,
|
|
87
|
-
};
|
|
88
|
-
const amount = 100;
|
|
89
|
-
assert.strictEqual(applyRate(configuration, amount), 10);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('applies the fixed rate correctly when a fixed rate is provided', () => {
|
|
93
|
-
const configuration = {
|
|
94
|
-
fixedRate: 50,
|
|
95
|
-
};
|
|
96
|
-
const amount = 100;
|
|
97
|
-
assert.strictEqual(applyRate(configuration, amount), 50);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('applies the fixed rate correctly when a fixed rate is provided and the amount is less than fixed rate', () => {
|
|
101
|
-
const configuration = {
|
|
102
|
-
fixedRate: 150,
|
|
103
|
-
};
|
|
104
|
-
const amount = 100;
|
|
105
|
-
assert.strictEqual(applyRate(configuration, amount), 100);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('applies the rate correctly when rate is less than or equal to 0', () => {
|
|
109
|
-
const configuration = {
|
|
110
|
-
rate: -0.1,
|
|
111
|
-
};
|
|
112
|
-
const amount = 100;
|
|
113
|
-
assert.strictEqual(applyRate(configuration, amount), -10);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('applies the rate correctly when only rate is provided and amount is negative', () => {
|
|
117
|
-
const configuration = {
|
|
118
|
-
rate: 0.1,
|
|
119
|
-
};
|
|
120
|
-
const amount = -100;
|
|
121
|
-
assert.strictEqual(applyRate(configuration, amount), -10);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('returns 0 when rate and fixed rate are not provided', () => {
|
|
125
|
-
const configuration = {};
|
|
126
|
-
const amount = 100;
|
|
127
|
-
assert.strictEqual(applyRate(configuration, amount), 0);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('calculateAmountToSplit', () => {
|
|
132
|
-
it('calculates the correct amount to split when using a rate', () => {
|
|
133
|
-
const configuration = {
|
|
134
|
-
rate: 0.1,
|
|
135
|
-
};
|
|
136
|
-
const amount = 1000;
|
|
137
|
-
assert.strictEqual(calculateAmountToSplit(configuration, amount), 100);
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('calculates the correct amount to split when using a fixed rate', () => {
|
|
141
|
-
const configuration = {
|
|
142
|
-
fixedRate: 50,
|
|
143
|
-
};
|
|
144
|
-
const amount = 1000;
|
|
145
|
-
assert.strictEqual(calculateAmountToSplit(configuration, amount), 50);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('returns 0 when the amount is less than or equal to 0', () => {
|
|
149
|
-
const configuration = {
|
|
150
|
-
rate: 0.1,
|
|
151
|
-
};
|
|
152
|
-
const amount = 0;
|
|
153
|
-
assert.strictEqual(calculateAmountToSplit(configuration, amount), 0);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('returns 0 when amount is negative', () => {
|
|
157
|
-
const configuration = {
|
|
158
|
-
rate: 0.1,
|
|
159
|
-
};
|
|
160
|
-
const amount = -1000;
|
|
161
|
-
assert.strictEqual(calculateAmountToSplit(configuration, amount), 0);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('returns 0 when configuration rate is negative', () => {
|
|
165
|
-
const configuration = {
|
|
166
|
-
rate: -0.1,
|
|
167
|
-
};
|
|
168
|
-
const amount = 1000;
|
|
169
|
-
assert.strictEqual(calculateAmountToSplit(configuration, amount), 0);
|
|
170
|
-
});
|
|
171
|
-
});
|
package/src/calculation.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export const roundToNext = (value: number, precision: number) =>
|
|
2
|
-
Math.ceil(value / precision) * precision;
|
|
3
|
-
|
|
4
|
-
export const calculateAmountToSplit = (
|
|
5
|
-
configuration: { rate?: number; fixedRate?: number },
|
|
6
|
-
amount: number,
|
|
7
|
-
) => {
|
|
8
|
-
const deductionAmount = configuration.rate
|
|
9
|
-
? amount * configuration.rate
|
|
10
|
-
: Math.min(configuration.fixedRate || 0, amount);
|
|
11
|
-
|
|
12
|
-
const leftInDiscount = Math.max(0, deductionAmount);
|
|
13
|
-
return leftInDiscount;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const applyRate = (configuration: { fixedRate?: number; rate?: number }, amount) => {
|
|
17
|
-
const { rate, fixedRate } = configuration;
|
|
18
|
-
return rate ? amount * rate : Math.min(fixedRate || 0, amount);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export const getTaxAmount = (total: number, rate: number, isNetPrice: boolean) => {
|
|
22
|
-
return isNetPrice ? total * rate : total - total / (1 + rate);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export const resolveAmountAndTax = (
|
|
26
|
-
{ ratio, taxDivisor }: { ratio?: number; taxDivisor?: number },
|
|
27
|
-
amount: number,
|
|
28
|
-
) => {
|
|
29
|
-
const shareAmount = Number.isFinite(ratio) ? amount * ratio! : 0;
|
|
30
|
-
const shareTaxAmount =
|
|
31
|
-
Number.isFinite(taxDivisor) && taxDivisor !== 0 ? shareAmount - shareAmount / taxDivisor! : 0;
|
|
32
|
-
return [shareAmount, shareTaxAmount];
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export const applyDiscountToMultipleShares = (shares, amount) => {
|
|
36
|
-
return shares.reduce(
|
|
37
|
-
([currentDiscountAmount, currentTaxAmount], share) => {
|
|
38
|
-
const [shareAmount, shareTaxAmount] = resolveAmountAndTax(share, amount);
|
|
39
|
-
return [currentDiscountAmount + shareAmount, currentTaxAmount + shareTaxAmount];
|
|
40
|
-
},
|
|
41
|
-
[0, 0],
|
|
42
|
-
);
|
|
43
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export const addressToString = (address?: {
|
|
2
|
-
addressLine?: string;
|
|
3
|
-
addressLine2?: string;
|
|
4
|
-
city?: string;
|
|
5
|
-
company?: string;
|
|
6
|
-
countryCode?: string;
|
|
7
|
-
firstName?: string;
|
|
8
|
-
lastName?: string;
|
|
9
|
-
postalCode?: string;
|
|
10
|
-
regionCode?: string;
|
|
11
|
-
}): string => {
|
|
12
|
-
if (!address) return '';
|
|
13
|
-
|
|
14
|
-
return [
|
|
15
|
-
[address.firstName, address.lastName].filter(Boolean).join(' '),
|
|
16
|
-
address.company,
|
|
17
|
-
address.addressLine,
|
|
18
|
-
address.addressLine2,
|
|
19
|
-
[address.postalCode, address.city].filter(Boolean).join(' '),
|
|
20
|
-
address.regionCode,
|
|
21
|
-
[address.countryCode].filter(Boolean).join(''),
|
|
22
|
-
]
|
|
23
|
-
.filter(Boolean)
|
|
24
|
-
.join('\n');
|
|
25
|
-
};
|
package/src/ch/index.ts
DELETED
package/src/ch/priceToString.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { defaultLogger, LogLevel } from '@unchainedshop/logger';
|
|
2
|
-
|
|
3
|
-
export interface IBaseAdapter {
|
|
4
|
-
key: string;
|
|
5
|
-
label: string;
|
|
6
|
-
version: string;
|
|
7
|
-
asString: () => string;
|
|
8
|
-
log: (
|
|
9
|
-
message: string,
|
|
10
|
-
options?: {
|
|
11
|
-
level?: LogLevel;
|
|
12
|
-
[x: string]: any;
|
|
13
|
-
},
|
|
14
|
-
) => void;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export const BaseAdapter: Omit<IBaseAdapter, 'key' | 'label' | 'version'> = {
|
|
18
|
-
log(message: string, { level = LogLevel.Debug, ...options } = {}) {
|
|
19
|
-
defaultLogger[level](message, options);
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
asString() {
|
|
23
|
-
return `${this.key}@${this.version}`;
|
|
24
|
-
},
|
|
25
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { IBaseAdapter } from './BaseAdapter.js';
|
|
2
|
-
|
|
3
|
-
export interface IBaseDirector<Adapter extends IBaseAdapter> {
|
|
4
|
-
getAdapters: (options?: { adapterFilter?: (adapter: Adapter) => boolean }) => Adapter[];
|
|
5
|
-
getAdapter: (key: string) => Adapter | null;
|
|
6
|
-
registerAdapter: (A: Adapter) => void;
|
|
7
|
-
unregisterAdapter: (key: string) => boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const BaseDirector = <AdapterType extends IBaseAdapter>(
|
|
11
|
-
directorName: string,
|
|
12
|
-
options?: {
|
|
13
|
-
adapterSortKey?: string;
|
|
14
|
-
adapterKeyField?: string; // Set to 'key' per default
|
|
15
|
-
},
|
|
16
|
-
): IBaseDirector<AdapterType> => {
|
|
17
|
-
const Adapters = new Map<string, AdapterType>();
|
|
18
|
-
const keyField = options?.adapterKeyField || 'key';
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
getAdapter: (key) => {
|
|
22
|
-
return Adapters.get(key) || null;
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
getAdapters: ({ adapterFilter } = {}) => {
|
|
26
|
-
const sortKey = options?.adapterSortKey || keyField;
|
|
27
|
-
return Array.from(Adapters.values())
|
|
28
|
-
.toSorted((left, right) => left[sortKey] - right[sortKey])
|
|
29
|
-
.filter(adapterFilter || (() => true));
|
|
30
|
-
},
|
|
31
|
-
|
|
32
|
-
registerAdapter: (Adapter) => {
|
|
33
|
-
Adapters.set(Adapter[keyField], Adapter);
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
unregisterAdapter: (key) => {
|
|
37
|
-
return Adapters.delete(key);
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { describe, it, beforeEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert';
|
|
3
|
-
import { BaseDirector, IBaseDirector } from './BaseDirector.js';
|
|
4
|
-
|
|
5
|
-
const adapter1 = {
|
|
6
|
-
key: 'adapter1',
|
|
7
|
-
label: 'Adapter 1',
|
|
8
|
-
version: '1',
|
|
9
|
-
log: () => ({}),
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
const adapter2 = {
|
|
13
|
-
key: 'adapter2',
|
|
14
|
-
label: 'Adapter 2',
|
|
15
|
-
version: '2',
|
|
16
|
-
log: () => ({}),
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const adapter3 = {
|
|
20
|
-
key: 'adapter3',
|
|
21
|
-
label: 'Adapter 3',
|
|
22
|
-
version: '3',
|
|
23
|
-
log: () => ({}),
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
describe('BaseDirector', () => {
|
|
27
|
-
let director: IBaseDirector<any>;
|
|
28
|
-
|
|
29
|
-
beforeEach(() => {
|
|
30
|
-
director = BaseDirector('TestDirector');
|
|
31
|
-
director.registerAdapter(adapter1);
|
|
32
|
-
director.registerAdapter(adapter3);
|
|
33
|
-
director.registerAdapter(adapter2);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
describe('registerAdapter', () => {
|
|
37
|
-
it('should add the adapter to the director', () => {
|
|
38
|
-
director.registerAdapter(adapter1);
|
|
39
|
-
assert.strictEqual(director.getAdapter(adapter1.key), adapter1);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should allow multiple adapters to be registered', () => {
|
|
43
|
-
assert.strictEqual(director.getAdapter(adapter1.key), adapter1);
|
|
44
|
-
assert.strictEqual(director.getAdapter(adapter2.key), adapter2);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('should register an adapter and add it to the internal map', () => {
|
|
48
|
-
assert.deepStrictEqual(director.getAdapter(adapter1.key), adapter1);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('should use the adapterKeyField specified in the options to store the adapter in the internal map', () => {
|
|
52
|
-
director = BaseDirector('TestDirector', {
|
|
53
|
-
adapterKeyField: 'label',
|
|
54
|
-
});
|
|
55
|
-
director.registerAdapter(adapter1);
|
|
56
|
-
assert.deepStrictEqual(director.getAdapter(adapter1.label), adapter1);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should return the correct Adapter object', () => {
|
|
60
|
-
const directorName = 'TestDirector';
|
|
61
|
-
const adapterKeyField = 'key';
|
|
62
|
-
director = BaseDirector(directorName, { adapterKeyField });
|
|
63
|
-
director.registerAdapter(adapter1);
|
|
64
|
-
|
|
65
|
-
assert.deepStrictEqual(director.getAdapter(adapter1.key), adapter1);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should return undefined if the Adapter does not exist', () => {
|
|
69
|
-
const directorName = 'TestDirector';
|
|
70
|
-
const adapterKeyField = 'key';
|
|
71
|
-
director = BaseDirector(directorName, { adapterKeyField });
|
|
72
|
-
assert.strictEqual(director.getAdapter(adapter1.key), null);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('getAdapter', () => {
|
|
77
|
-
it('should return the correct Adapter object for a given key', () => {
|
|
78
|
-
assert.strictEqual(director.getAdapter(adapter1.key), adapter1);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('should return undefined if no Adapter is registered with the given key', () => {
|
|
82
|
-
assert.strictEqual(director.getAdapter('invalid-key'), null);
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it('should return the correct Adapter object when the keyField is set to a property other than "key"', () => {
|
|
86
|
-
director = BaseDirector('TestDirector', { adapterKeyField: 'label' });
|
|
87
|
-
director.registerAdapter(adapter1);
|
|
88
|
-
assert.strictEqual(director.getAdapter(adapter1.label), adapter1);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
describe('getAdapters', () => {
|
|
93
|
-
it('should return an array of registered Adapter objects', () => {
|
|
94
|
-
assert.deepStrictEqual(director.getAdapters(), [adapter1, adapter3, adapter2]);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should return an empty array if no Adapter objects have been registered', () => {
|
|
98
|
-
const directorName = 'TestDirector';
|
|
99
|
-
const adapterKeyField = 'key';
|
|
100
|
-
const baseDirector = BaseDirector(directorName, { adapterKeyField });
|
|
101
|
-
assert.deepStrictEqual(baseDirector.getAdapters(), []);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('should return an array of registered Adapter objects sorted by the adapterSortKey provided', () => {
|
|
105
|
-
director = BaseDirector('TestDirector', { adapterSortKey: 'version' });
|
|
106
|
-
director.registerAdapter(adapter1);
|
|
107
|
-
director.registerAdapter(adapter3);
|
|
108
|
-
director.registerAdapter(adapter2);
|
|
109
|
-
assert.deepStrictEqual(director.getAdapters(), [adapter1, adapter2, adapter3]);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
});
|
package/src/find-unused-slug.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const DELIMITER = '-';
|
|
2
|
-
|
|
3
|
-
const addSuffixToSlug = (slug, index = 1, delimiter = DELIMITER) => {
|
|
4
|
-
return `${slug}${delimiter}${index}`;
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
const incrementSuffixedSlug = (slugIncludingSuffix, delimiter = DELIMITER) => {
|
|
8
|
-
const slugParts = slugIncludingSuffix.split(delimiter);
|
|
9
|
-
const suffixedIndex = parseInt(slugParts.pop(), 10);
|
|
10
|
-
const slugWithoutSuffix = slugParts.join(delimiter);
|
|
11
|
-
return addSuffixToSlug(slugWithoutSuffix, suffixedIndex + 1);
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export default (
|
|
15
|
-
checkSlugIsUniqueFn: (slug: string) => Promise<boolean>,
|
|
16
|
-
{ slugify }: { slugify: (text: string) => string },
|
|
17
|
-
): ((params: { title?: string; existingSlug?: string; newSlug?: string }) => Promise<string>) => {
|
|
18
|
-
const findUnusedSlug = async ({
|
|
19
|
-
title,
|
|
20
|
-
existingSlug,
|
|
21
|
-
newSlug,
|
|
22
|
-
}: {
|
|
23
|
-
title: string;
|
|
24
|
-
existingSlug?: string;
|
|
25
|
-
newSlug?: string;
|
|
26
|
-
}) => {
|
|
27
|
-
const slug = newSlug || existingSlug || `${slugify(title)}`;
|
|
28
|
-
if (!(await checkSlugIsUniqueFn(slug))) {
|
|
29
|
-
const isSlugAlreadySuffixed = !!newSlug;
|
|
30
|
-
return findUnusedSlug({
|
|
31
|
-
title,
|
|
32
|
-
existingSlug,
|
|
33
|
-
newSlug: isSlugAlreadySuffixed ? incrementSuffixedSlug(slug) : addSuffixToSlug(slug),
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
return slug;
|
|
37
|
-
};
|
|
38
|
-
return findUnusedSlug;
|
|
39
|
-
};
|
package/src/locale-helpers.ts
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { resolveAcceptLanguage } from 'resolve-accept-language';
|
|
2
|
-
|
|
3
|
-
const { UNCHAINED_LANG = 'de', UNCHAINED_COUNTRY = 'CH', UNCHAINED_CURRENCY = 'CHF' } = process.env;
|
|
4
|
-
|
|
5
|
-
export const systemLocale = new Intl.Locale(`${UNCHAINED_LANG}-${UNCHAINED_COUNTRY}`);
|
|
6
|
-
|
|
7
|
-
export const determineFallbackLocale = (
|
|
8
|
-
countries: { isoCode: string }[],
|
|
9
|
-
languages: { isoCode: string }[],
|
|
10
|
-
): Intl.Locale => {
|
|
11
|
-
try {
|
|
12
|
-
const country =
|
|
13
|
-
countries.find((country) => country.isoCode === systemLocale.region)?.isoCode ||
|
|
14
|
-
countries[0]?.isoCode;
|
|
15
|
-
const language =
|
|
16
|
-
languages.find((language) => language.isoCode === systemLocale.language)?.isoCode ||
|
|
17
|
-
languages[0]?.isoCode;
|
|
18
|
-
return new Intl.Locale(`${language}-${country}`);
|
|
19
|
-
} catch {
|
|
20
|
-
return systemLocale;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export const resolveBestSupported = (
|
|
25
|
-
acceptLanguage: string,
|
|
26
|
-
acceptCountry: string,
|
|
27
|
-
{
|
|
28
|
-
countries = [],
|
|
29
|
-
languages = [],
|
|
30
|
-
}: {
|
|
31
|
-
countries: { isoCode: string }[];
|
|
32
|
-
languages: { isoCode: string }[];
|
|
33
|
-
},
|
|
34
|
-
): Intl.Locale => {
|
|
35
|
-
const supportedLocales: string[] = languages.reduce<string[]>((accumulator, language) => {
|
|
36
|
-
const added = countries
|
|
37
|
-
.filter((country) => {
|
|
38
|
-
if (acceptCountry) {
|
|
39
|
-
return country.isoCode === acceptCountry;
|
|
40
|
-
}
|
|
41
|
-
return true;
|
|
42
|
-
})
|
|
43
|
-
.map((country) => {
|
|
44
|
-
return `${language.isoCode}-${country.isoCode}`;
|
|
45
|
-
});
|
|
46
|
-
return accumulator.concat(added);
|
|
47
|
-
}, []);
|
|
48
|
-
|
|
49
|
-
const fallbackLocale = determineFallbackLocale(countries, languages);
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const { match } = resolveAcceptLanguage(
|
|
53
|
-
acceptLanguage || '',
|
|
54
|
-
supportedLocales,
|
|
55
|
-
fallbackLocale.baseName,
|
|
56
|
-
{
|
|
57
|
-
returnMatchType: true,
|
|
58
|
-
},
|
|
59
|
-
);
|
|
60
|
-
return new Intl.Locale(match);
|
|
61
|
-
} catch {
|
|
62
|
-
return fallbackLocale;
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
export const resolveBestCurrency = (currencyCode: string | null, currencies: { isoCode: string }[]) => {
|
|
67
|
-
if (currencyCode) {
|
|
68
|
-
const resolvedCurrency = currencies.find(
|
|
69
|
-
(currency) => currency.isoCode.toUpperCase() === currencyCode.toUpperCase(),
|
|
70
|
-
);
|
|
71
|
-
if (resolvedCurrency) {
|
|
72
|
-
return resolvedCurrency.isoCode;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return (
|
|
76
|
-
currencies.find((currency) => currency.isoCode === UNCHAINED_CURRENCY)?.isoCode ||
|
|
77
|
-
currencies[0]?.isoCode
|
|
78
|
-
);
|
|
79
|
-
};
|
package/src/object-invert.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
const invertMapObject = (theMapObject: Record<string, string>): Record<string, string> =>
|
|
2
|
-
Object.keys(theMapObject).reduce((invertedObj, key) => {
|
|
3
|
-
const newObj = invertedObj;
|
|
4
|
-
newObj[theMapObject[key]] = key;
|
|
5
|
-
return newObj;
|
|
6
|
-
}, {});
|
|
7
|
-
|
|
8
|
-
export default invertMapObject;
|
package/src/pipe-promises.ts
DELETED
package/src/sha1.ts
DELETED
package/src/sha256.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export default async function sha256(message) {
|
|
2
|
-
const bytes = new TextEncoder().encode(message);
|
|
3
|
-
const hashBuffer = await crypto.subtle.digest('SHA-256', bytes);
|
|
4
|
-
// Convert ArrayBuffer to hex string without using Buffer
|
|
5
|
-
return Array.from(new Uint8Array(hashBuffer))
|
|
6
|
-
.map((b) => b.toString(16).padStart(2, '0'))
|
|
7
|
-
.join('');
|
|
8
|
-
}
|
package/src/slugify.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export default function slugify(text: string): string {
|
|
2
|
-
return text
|
|
3
|
-
.toString()
|
|
4
|
-
.toLowerCase()
|
|
5
|
-
.replace(/\s+/g, '-') // Replace spaces with -
|
|
6
|
-
.replace(/[^\w-]+/g, '') // Remove all non-word chars
|
|
7
|
-
.replace(/--+/g, '-') // Replace multiple - with single -
|
|
8
|
-
.replace(/^-+/, '') // Trim - from start of text
|
|
9
|
-
.replace(/-+$/, ''); // Trim - from end of text
|
|
10
|
-
}
|