@unchainedshop/utils 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/README.md +3 -0
  2. package/lib/buildSortOption.d.ts +5 -0
  3. package/lib/buildSortOption.js +13 -0
  4. package/lib/buildSortOption.js.map +1 -0
  5. package/lib/db/build-db-indexes.d.ts +2 -0
  6. package/lib/db/build-db-indexes.js +23 -0
  7. package/lib/db/build-db-indexes.js.map +1 -0
  8. package/lib/db/check-id.d.ts +4 -0
  9. package/lib/db/check-id.js +6 -0
  10. package/lib/db/check-id.js.map +1 -0
  11. package/lib/db/generate-db-filter-by-id.d.ts +5 -0
  12. package/lib/db/generate-db-filter-by-id.js +5 -0
  13. package/lib/db/generate-db-filter-by-id.js.map +1 -0
  14. package/lib/db/generate-db-mutations.d.ts +7 -0
  15. package/lib/db/generate-db-mutations.js +76 -0
  16. package/lib/db/generate-db-mutations.js.map +1 -0
  17. package/lib/db/generate-db-object-id.d.ts +7 -0
  18. package/lib/db/generate-db-object-id.js +26 -0
  19. package/lib/db/generate-db-object-id.js.map +1 -0
  20. package/lib/director/BaseAdapter.d.ts +2 -0
  21. package/lib/director/BaseAdapter.js +7 -0
  22. package/lib/director/BaseAdapter.js.map +1 -0
  23. package/lib/director/BaseDirector.d.ts +5 -0
  24. package/lib/director/BaseDirector.js +21 -0
  25. package/lib/director/BaseDirector.js.map +1 -0
  26. package/lib/director/BaseDiscountAdapter.d.ts +2 -0
  27. package/lib/director/BaseDiscountAdapter.js +48 -0
  28. package/lib/director/BaseDiscountAdapter.js.map +1 -0
  29. package/lib/director/BaseDiscountDirector.d.ts +2 -0
  30. package/lib/director/BaseDiscountDirector.js +57 -0
  31. package/lib/director/BaseDiscountDirector.js.map +1 -0
  32. package/lib/director/BasePricingAdapter.d.ts +2 -0
  33. package/lib/director/BasePricingAdapter.js +25 -0
  34. package/lib/director/BasePricingAdapter.js.map +1 -0
  35. package/lib/director/BasePricingDirector.d.ts +2 -0
  36. package/lib/director/BasePricingDirector.js +61 -0
  37. package/lib/director/BasePricingDirector.js.map +1 -0
  38. package/lib/director/BasePricingSheet.d.ts +2 -0
  39. package/lib/director/BasePricingSheet.js +55 -0
  40. package/lib/director/BasePricingSheet.js.map +1 -0
  41. package/lib/find-localized-text.d.ts +2 -0
  42. package/lib/find-localized-text.js +39 -0
  43. package/lib/find-localized-text.js.map +1 -0
  44. package/lib/find-preserving-ids.d.ts +2 -0
  45. package/lib/find-preserving-ids.js +33 -0
  46. package/lib/find-preserving-ids.js.map +1 -0
  47. package/lib/find-unused-slug.d.ts +8 -0
  48. package/lib/find-unused-slug.js +24 -0
  49. package/lib/find-unused-slug.js.map +1 -0
  50. package/lib/generate-random-hash.d.ts +2 -0
  51. package/lib/generate-random-hash.js +7 -0
  52. package/lib/generate-random-hash.js.map +1 -0
  53. package/lib/locale-helpers.d.ts +7 -0
  54. package/lib/locale-helpers.js +34 -0
  55. package/lib/locale-helpers.js.map +1 -0
  56. package/lib/object-invert.d.ts +2 -0
  57. package/lib/object-invert.js +7 -0
  58. package/lib/object-invert.js.map +1 -0
  59. package/lib/pipe-promises.d.ts +2 -0
  60. package/lib/pipe-promises.js +2 -0
  61. package/lib/pipe-promises.js.map +1 -0
  62. package/lib/random-value-hex.d.ts +1 -0
  63. package/lib/random-value-hex.js +8 -0
  64. package/lib/random-value-hex.js.map +1 -0
  65. package/lib/schemas/AddressSchema.d.ts +1 -0
  66. package/lib/schemas/AddressSchema.js +13 -0
  67. package/lib/schemas/AddressSchema.js.map +1 -0
  68. package/lib/schemas/ContactSchema.d.ts +1 -0
  69. package/lib/schemas/ContactSchema.js +6 -0
  70. package/lib/schemas/ContactSchema.js.map +1 -0
  71. package/lib/schemas/UsersSchema.d.ts +3 -0
  72. package/lib/schemas/UsersSchema.js +52 -0
  73. package/lib/schemas/UsersSchema.js.map +1 -0
  74. package/lib/schemas/commonSchemaFields.d.ts +50 -0
  75. package/lib/schemas/commonSchemaFields.js +31 -0
  76. package/lib/schemas/commonSchemaFields.js.map +1 -0
  77. package/lib/slugify.d.ts +1 -0
  78. package/lib/slugify.js +11 -0
  79. package/lib/slugify.js.map +1 -0
  80. package/lib/utils-index.d.ts +36 -0
  81. package/lib/utils-index.js +45 -0
  82. package/lib/utils-index.js.map +1 -0
  83. package/package.json +44 -0
  84. package/tests/generate-db-mutations.test.js +69 -0
  85. package/tests/utils-index.test.js +44 -0
  86. package/tsconfig.build.json +26 -0
  87. package/tsconfig.json +8 -0
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Utils (Unchained Engine)
2
+
3
+ This package acts as common helpers that can be used by core or extension modules of Unchained.
@@ -0,0 +1,5 @@
1
+ import { SortOption } from '@unchainedshop/types/api';
2
+ declare const buildSortOptions: (sort?: Array<SortOption>) => {
3
+ [key: string]: [value: number];
4
+ };
5
+ export default buildSortOptions;
@@ -0,0 +1,13 @@
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=buildSortOption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildSortOption.js","sourceRoot":"","sources":["../src/buildSortOption.ts"],"names":[],"mappings":"AAEA,MAAM,eAAe,GAAG;IACtB,GAAG,EAAE,CAAC;IACN,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,OAA0B,EAAE,EAAsC,EAAE;IAC5F,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"}
@@ -0,0 +1,2 @@
1
+ import { Collection, Indexes, Document } from '@unchainedshop/types/common';
2
+ export declare const buildDbIndexes: <T extends Document>(collection: Collection<T>, indexes: Indexes<T>) => Promise<boolean>;
@@ -0,0 +1,23 @@
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ const buildIndexes = (collection, indexes) => Promise.all(indexes.map(async ({ index, options }) => {
3
+ await collection.createIndex(index, options).catch((error) => error);
4
+ }));
5
+ export const buildDbIndexes = async (collection, indexes) => {
6
+ let success = true;
7
+ const buildErrors = (await buildIndexes(collection, indexes)).filter(Boolean);
8
+ if (buildErrors.length) {
9
+ const dropError = await collection.dropIndexes().catch((e) => e);
10
+ if (!dropError) {
11
+ const rebuildErrors = (await buildIndexes(collection, indexes)).filter(Boolean);
12
+ if (rebuildErrors.length) {
13
+ log('Error building indexes', {
14
+ level: LogLevel.Error,
15
+ ...rebuildErrors,
16
+ });
17
+ success = false;
18
+ }
19
+ }
20
+ }
21
+ return success;
22
+ };
23
+ //# sourceMappingURL=build-db-indexes.js.map
@@ -0,0 +1 @@
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,CAAI,UAAyB,EAAE,OAAmB,EAAgC,EAAE,CACvG,OAAO,CAAC,GAAG,CACT,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;IACvC,MAAM,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAc,CAAC,CAAC;AAChF,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;QACtB,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjE,IAAI,CAAC,SAAS,EAAE;YACd,MAAM,aAAa,GAAG,CAAC,MAAM,YAAY,CAAI,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAEnF,IAAI,aAAa,CAAC,MAAM,EAAE;gBACxB,GAAG,CAAC,wBAAwB,EAAE;oBAC5B,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,GAAG,aAAa;iBACjB,CAAC,CAAC;gBACH,OAAO,GAAG,KAAK,CAAC;aACjB;SACF;KACF;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare const checkId: (value: string, error?: {
2
+ message: string;
3
+ path?: string;
4
+ }) => void;
@@ -0,0 +1,6 @@
1
+ export const checkId = (value, error) => {
2
+ if (typeof value !== 'string') {
3
+ throw error || { message: 'Invalid id' };
4
+ }
5
+ };
6
+ //# sourceMappingURL=check-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-id.js","sourceRoot":"","sources":["../../src/db/check-id.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,KAA0C,EAAQ,EAAE;IACzF,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;QAC7B,MAAM,KAAK,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;KAC1C;AACH,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { Filter, Query, _ID } from '@unchainedshop/types/common';
2
+ export declare const generateDbFilterById: (id: unknown, query?: Query) => Filter<{
3
+ [x: string]: any;
4
+ _id?: _ID;
5
+ }>;
@@ -0,0 +1,5 @@
1
+ export const generateDbFilterById = (id, query = {}) => {
2
+ const _id = id || null; // never undefined, else it will get the first one
3
+ return { _id, ...query };
4
+ };
5
+ //# sourceMappingURL=generate-db-filter-by-id.js.map
@@ -0,0 +1 @@
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,QAAe,EAAE,EACwB,EAAE;IAC3C,MAAM,GAAG,GAAG,EAAE,IAAI,IAAI,CAAC,CAAC,kDAAkD;IAC1E,OAAO,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;AAC3B,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Collection, ModuleMutations, ModuleCreateMutation, _ID, TimestampFields } from '@unchainedshop/types/common';
2
+ export declare const generateDbMutations: <T extends TimestampFields & {
3
+ _id?: _ID;
4
+ }>(collection: Collection<T>, schema: SimpleSchema, options?: {
5
+ hasCreateOnly?: boolean;
6
+ permanentlyDeleteByDefault?: boolean;
7
+ }) => ModuleMutations<T> | ModuleCreateMutation<T>;
@@ -0,0 +1,76 @@
1
+ import { checkId } from './check-id';
2
+ import { generateDbObjectId } from './generate-db-object-id';
3
+ import { generateDbFilterById } from './generate-db-filter-by-id';
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, userId) => {
21
+ const values = schema.clean(doc);
22
+ values.created = new Date();
23
+ values.createdBy = userId;
24
+ schema.validate(values);
25
+ values._id = doc._id || generateDbObjectId();
26
+ const result = await collection.insertOne(values);
27
+ return result.insertedId;
28
+ },
29
+ update: hasCreateOnly
30
+ ? undefined
31
+ : async (_id, doc, userId) => {
32
+ checkId(_id);
33
+ let modifier;
34
+ if (doc?.$set) {
35
+ const values = schema.clean(doc, { isModifier: true });
36
+ modifier = {
37
+ ...values,
38
+ $set: {
39
+ ...(values.$set || {}),
40
+ updated: new Date(),
41
+ updatedBy: userId,
42
+ },
43
+ };
44
+ }
45
+ else {
46
+ const values = schema.clean(doc);
47
+ modifier = {
48
+ $set: {
49
+ ...values,
50
+ updated: new Date(),
51
+ updatedBy: userId,
52
+ },
53
+ };
54
+ }
55
+ schema.validate(modifier, { modifier: true });
56
+ const filter = generateDbFilterById(_id, { deleted: null });
57
+ await collection.updateOne(filter, modifier);
58
+ return _id;
59
+ },
60
+ deletePermanently: hasCreateOnly ? undefined : deletePermanently,
61
+ delete: hasCreateOnly
62
+ ? undefined
63
+ : async (_id, userId) => {
64
+ if (permanentlyDeleteByDefault) {
65
+ return deletePermanently(_id);
66
+ }
67
+ checkId(_id);
68
+ const filter = generateDbFilterById(_id, { deleted: null });
69
+ const modifier = { $set: { deleted: new Date(), deletedBy: userId } };
70
+ const values = schema.clean(modifier, { isModifier: true });
71
+ const result = await collection.updateOne(filter, values);
72
+ return result.modifiedCount;
73
+ },
74
+ };
75
+ };
76
+ //# sourceMappingURL=generate-db-mutations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-db-mutations.js","sourceRoot":"","sources":["../../src/db/generate-db-mutations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @name Random.hexString
3
+ * @summary Return a random string of `n` hexadecimal digits.
4
+ * @locus Anywhere
5
+ * @param {Number} n Length of the string
6
+ */
7
+ export declare const generateDbObjectId: (digits?: number) => string;
@@ -0,0 +1,26 @@
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
@@ -0,0 +1 @@
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;QACF,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;KACtC;IAAC,OAAO,CAAC,EAAE;QACV,4DAA4D;QAC5D,KAAK,GAAG,MAAM,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;KAC5C;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"}
@@ -0,0 +1,2 @@
1
+ import { IBaseAdapter } from '@unchainedshop/types/common';
2
+ export declare const BaseAdapter: Omit<IBaseAdapter, 'key' | 'label' | 'version'>;
@@ -0,0 +1,7 @@
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ export const BaseAdapter = {
3
+ log(message, { level = LogLevel.Debug, ...options } = {}) {
4
+ return log(message, { level, ...options });
5
+ },
6
+ };
7
+ //# sourceMappingURL=BaseAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAdapter.js","sourceRoot":"","sources":["../../src/director/BaseAdapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,CAAC,MAAM,WAAW,GAAoD;IAC1E,GAAG,CAAC,OAAe,EAAE,EAAE,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE;QAC9D,OAAO,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { IBaseAdapter, IBaseDirector } from '@unchainedshop/types/common';
2
+ export declare const BaseDirector: <AdapterType extends IBaseAdapter>(directorName: string, options?: {
3
+ adapterSortKey?: string;
4
+ adapterKeyField?: string;
5
+ }) => IBaseDirector<AdapterType>;
@@ -0,0 +1,21 @@
1
+ import { log } from '@unchainedshop/logger';
2
+ export const BaseDirector = (directorName, options) => {
3
+ const Adapters = new Map();
4
+ const keyField = options?.adapterKeyField || 'key';
5
+ return {
6
+ getAdapter: (key) => {
7
+ return Adapters.get(key);
8
+ },
9
+ getAdapters: ({ adapterFilter } = {}) => {
10
+ const sortKey = options?.adapterSortKey || keyField;
11
+ return Array.from(Adapters.values())
12
+ .sort((left, right) => left[sortKey] - right[sortKey])
13
+ .filter(adapterFilter || (() => true));
14
+ },
15
+ registerAdapter: (Adapter) => {
16
+ log(`${directorName} -> Registered ${keyField !== 'key' ? `${Adapter[keyField]} ` : ' '} ${Adapter.key} ${Adapter.version} (${Adapter.label})`);
17
+ Adapters.set(Adapter[keyField], Adapter);
18
+ },
19
+ };
20
+ };
21
+ //# sourceMappingURL=BaseDirector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDirector.js","sourceRoot":"","sources":["../../src/director/BaseDirector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,YAAoB,EACpB,OAGC,EAC2B,EAAE;IAC9B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAChD,MAAM,QAAQ,GAAG,OAAO,EAAE,eAAe,IAAI,KAAK,CAAC;IAEnD,OAAO;QACL,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE;YAClB,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAED,WAAW,EAAE,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,OAAO,EAAE,cAAc,IAAI,QAAQ,CAAC;YACpD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;iBACjC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;iBACrD,MAAM,CAAC,aAAa,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE;YAC3B,GAAG,CACD,GAAG,YAAY,kBAAkB,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IACjF,OAAO,CAAC,GACV,IAAI,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,GAAG,CACzC,CAAC;YAEF,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { IDiscountAdapter } from '@unchainedshop/types/discount';
2
+ export declare const BaseDiscountAdapter: Omit<IDiscountAdapter, 'key' | 'label' | 'version'>;
@@ -0,0 +1,48 @@
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ export const BaseDiscountAdapter = {
3
+ orderIndex: 0,
4
+ isManualAdditionAllowed: async () => {
5
+ return false;
6
+ },
7
+ // return true if a discount is allowed to get removed manually by a user
8
+ isManualRemovalAllowed: async () => {
9
+ return false;
10
+ },
11
+ actions: async () => ({
12
+ // return true if a discount is valid to be part of the order
13
+ // without input of a user. that could be a time based global discount
14
+ // like a 10% discount day
15
+ // if you return false, this discount will
16
+ // get removed from the order before any price calculation
17
+ // takes place.
18
+ // eslint-disable-next-line
19
+ isValidForSystemTriggering: async () => {
20
+ return false;
21
+ },
22
+ // return an arbitrary JSON serializable object with reservation data
23
+ // this method is called when a discount is added through a manual code and let's
24
+ // you manually deduct expendable discounts (coupon balances for ex.) before checkout
25
+ reserve: async () => {
26
+ return {};
27
+ },
28
+ // return void, allows you to free up any reservations in backend systems
29
+ release: async () => {
30
+ return null;
31
+ },
32
+ // return true if a discount is valid to be part of the order.
33
+ // if you return false, this discount will
34
+ // get removed from the order before any price calculation
35
+ // takes place.
36
+ isValidForCodeTriggering: async () => {
37
+ return false;
38
+ },
39
+ // returns the appropriate discount context for a calculation adapter
40
+ discountForPricingAdapterKey() {
41
+ return null;
42
+ },
43
+ }),
44
+ log(message, { level = LogLevel.Debug, ...options } = {}) {
45
+ return log(message, { level, ...options });
46
+ },
47
+ };
48
+ //# sourceMappingURL=BaseDiscountAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDiscountAdapter.js","sourceRoot":"","sources":["../../src/director/BaseDiscountAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAItD,MAAM,CAAC,MAAM,mBAAmB,GAAwD;IACtF,UAAU,EAAE,CAAC;IAEb,uBAAuB,EAAE,KAAK,IAAI,EAAE;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yEAAyE;IACzE,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QACpB,6DAA6D;QAC7D,sEAAsE;QACtE,0BAA0B;QAC1B,0CAA0C;QAC1C,0DAA0D;QAC1D,eAAe;QACf,2BAA2B;QAC3B,0BAA0B,EAAE,KAAK,IAAI,EAAE;YACrC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qEAAqE;QACrE,iFAAiF;QACjF,qFAAqF;QACrF,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,yEAAyE;QACzE,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,8DAA8D;QAC9D,0CAA0C;QAC1C,0DAA0D;QAC1D,eAAe;QACf,wBAAwB,EAAE,KAAK,IAAI,EAAE;YACnC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,qEAAqE;QACrE,4BAA4B;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;IAEF,GAAG,CAAC,OAAe,EAAE,EAAE,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE;QAC9D,OAAO,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { IDiscountDirector } from '@unchainedshop/types/discount';
2
+ export declare const BaseDiscountDirector: (directorName: string) => IDiscountDirector;
@@ -0,0 +1,57 @@
1
+ import { log } from '@unchainedshop/logger';
2
+ import { BaseDirector } from 'meteor/unchained:utils';
3
+ export const BaseDiscountDirector = (directorName) => {
4
+ const baseDirector = BaseDirector(directorName, {
5
+ adapterSortKey: 'orderIndex',
6
+ });
7
+ return {
8
+ ...baseDirector,
9
+ actions: async (discountContext, requestContext) => {
10
+ const context = { ...discountContext, ...requestContext };
11
+ return {
12
+ interface(discountKey) {
13
+ const Adapter = baseDirector.getAdapter(discountKey);
14
+ if (!Adapter)
15
+ return null;
16
+ const adapter = Adapter.actions({ context });
17
+ return adapter;
18
+ },
19
+ resolveDiscountKeyFromStaticCode: async (options) => {
20
+ if (!context.order)
21
+ return null;
22
+ log(`DiscountDirector -> Find user discount for static code ${options?.code}`);
23
+ const discounts = await Promise.all(baseDirector
24
+ .getAdapters()
25
+ .filter((Adapter) => Adapter.isManualAdditionAllowed(options?.code))
26
+ .map(async (Adapter) => {
27
+ const adapter = await Adapter.actions({ context });
28
+ return {
29
+ key: Adapter.key,
30
+ isValid: await adapter.isValidForCodeTriggering(options),
31
+ };
32
+ }));
33
+ return discounts.find(({ isValid }) => isValid === true)?.key;
34
+ },
35
+ async findSystemDiscounts() {
36
+ if (!context.order)
37
+ return [];
38
+ const discounts = await Promise.all(baseDirector.getAdapters().map(async (Adapter) => {
39
+ const adapter = await Adapter.actions({ context });
40
+ return {
41
+ key: Adapter.key,
42
+ isValid: await adapter.isValidForSystemTriggering(),
43
+ };
44
+ }));
45
+ const validDiscounts = discounts
46
+ .filter(({ isValid }) => isValid === true)
47
+ .map(({ key }) => key);
48
+ if (validDiscounts.length > 0) {
49
+ log(`DiscountDirector -> Found ${validDiscounts.length} system discounts`);
50
+ }
51
+ return validDiscounts;
52
+ },
53
+ };
54
+ },
55
+ };
56
+ };
57
+ //# sourceMappingURL=BaseDiscountDirector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseDiscountDirector.js","sourceRoot":"","sources":["../../src/director/BaseDiscountDirector.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEtD,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAoB,EAAqB,EAAE;IAC9E,MAAM,YAAY,GAAG,YAAY,CAAmB,YAAY,EAAE;QAChE,cAAc,EAAE,YAAY;KAC7B,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,YAAY;QAEf,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,EAAE;YACjD,MAAM,OAAO,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,cAAc,EAAE,CAAC;YAE1D,OAAO;gBACL,SAAS,CAAC,WAAmB;oBAC3B,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;oBACrD,IAAI,CAAC,OAAO;wBAAE,OAAO,IAAI,CAAC;oBAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC7C,OAAO,OAAO,CAAC;gBACjB,CAAC;gBAED,gCAAgC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;oBAClD,IAAI,CAAC,OAAO,CAAC,KAAK;wBAAE,OAAO,IAAI,CAAC;oBAEhC,GAAG,CAAC,0DAA0D,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;oBAE/E,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,YAAY;yBACT,WAAW,EAAE;yBACb,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;yBACnE,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;wBACrB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;wBACnD,OAAO;4BACL,GAAG,EAAE,OAAO,CAAC,GAAG;4BAChB,OAAO,EAAE,MAAM,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC;yBACzD,CAAC;oBACJ,CAAC,CAAC,CACL,CAAC;oBAEF,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,EAAE,GAAG,CAAC;gBAChE,CAAC;gBAED,KAAK,CAAC,mBAAmB;oBACvB,IAAI,CAAC,OAAO,CAAC,KAAK;wBAAE,OAAO,EAAE,CAAC;oBAC9B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,GAAG,CACjC,YAAY,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;wBAC/C,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;wBACnD,OAAO;4BACL,GAAG,EAAE,OAAO,CAAC,GAAG;4BAChB,OAAO,EAAE,MAAM,OAAO,CAAC,0BAA0B,EAAE;yBACpD,CAAC;oBACJ,CAAC,CAAC,CACH,CAAC;oBAEF,MAAM,cAAc,GAAG,SAAS;yBAC7B,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC;yBACzC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;oBAEzB,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE;wBAC7B,GAAG,CAAC,6BAA6B,cAAc,CAAC,MAAM,mBAAmB,CAAC,CAAC;qBAC5E;oBACD,OAAO,cAAc,CAAC;gBACxB,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { BasePricingAdapterContext, IPricingSheet, IPricingAdapter, PricingCalculation } from '@unchainedshop/types/pricing';
2
+ export declare const BasePricingAdapter: <Context extends BasePricingAdapterContext, Calculation extends PricingCalculation>() => IPricingAdapter<Context, Calculation, IPricingSheet<Calculation>>;
@@ -0,0 +1,25 @@
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ export const BasePricingAdapter = () => ({
3
+ key: '',
4
+ label: '',
5
+ version: '',
6
+ orderIndex: 0,
7
+ isActivatedFor: () => {
8
+ return false;
9
+ },
10
+ actions: (params) => {
11
+ const calculation = [];
12
+ const actions = {
13
+ calculate: async () => {
14
+ return [];
15
+ },
16
+ getCalculation: () => calculation,
17
+ getContext: () => params.context,
18
+ };
19
+ return actions;
20
+ },
21
+ log(message, { level = LogLevel.Debug, ...options } = {}) {
22
+ return log(message, { level, ...options });
23
+ },
24
+ });
25
+ //# sourceMappingURL=BasePricingAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasePricingAdapter.js","sourceRoot":"","sources":["../../src/director/BasePricingAdapter.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAGqC,EAAE,CAAC,CAAC;IACzE,GAAG,EAAE,EAAE;IACP,KAAK,EAAE,EAAE;IACT,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,CAAC;IAEb,cAAc,EAAE,GAAG,EAAE;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;QAClB,MAAM,WAAW,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAiD;YAC5D,SAAS,EAAE,KAAK,IAAI,EAAE;gBACpB,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,cAAc,EAAE,GAAG,EAAE,CAAC,WAAW;YACjC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO;SACjC,CAAC;QAEF,OAAO,OAEN,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,OAAe,EAAE,EAAE,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE;QAC9D,OAAO,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { BasePricingAdapterContext, BasePricingContext, IPricingDirector, IPricingAdapter, IPricingSheet, PricingCalculation } from '@unchainedshop/types/pricing';
2
+ export declare const BasePricingDirector: <DirectorContext extends BasePricingContext, AdapterContext extends BasePricingAdapterContext, Calculation extends PricingCalculation, PricingAdapter extends IPricingAdapter<AdapterContext, Calculation, IPricingSheet<Calculation>>>(directorName: string) => IPricingDirector<DirectorContext, Calculation, AdapterContext, IPricingSheet<Calculation>, PricingAdapter>;
@@ -0,0 +1,61 @@
1
+ import { log, LogLevel } from '@unchainedshop/logger';
2
+ import { BaseDirector } from './BaseDirector';
3
+ export const BasePricingDirector = (directorName) => {
4
+ const baseDirector = BaseDirector(directorName, {
5
+ adapterSortKey: 'orderIndex',
6
+ });
7
+ const director = {
8
+ ...baseDirector,
9
+ buildPricingContext: async () => {
10
+ return {};
11
+ },
12
+ actions: async (pricingContext, requestContext, buildPricingContext) => {
13
+ const context = await buildPricingContext(pricingContext, requestContext);
14
+ let calculation = [];
15
+ const actions = {
16
+ async calculate() {
17
+ const Adapters = baseDirector.getAdapters({
18
+ adapterFilter: (Adapter) => {
19
+ return Adapter.isActivatedFor(context);
20
+ },
21
+ });
22
+ calculation = await Adapters.reduce(async (previousPromise, Adapter) => {
23
+ const resolvedCalculation = await previousPromise;
24
+ if (!resolvedCalculation)
25
+ return null;
26
+ const discounts = await Promise.all(context.discounts.map(async (discount) => ({
27
+ discountId: discount._id,
28
+ configuration: await context.modules.orders.discounts.configurationForPricingAdapterKey(discount, Adapter.key, this.calculationSheet(), context),
29
+ })));
30
+ try {
31
+ const adapter = Adapter.actions({
32
+ context,
33
+ calculationSheet: this.calculationSheet(),
34
+ discounts: discounts.filter(({ configuration }) => configuration !== null),
35
+ });
36
+ const nextCalculationResult = await adapter.calculate();
37
+ if (!nextCalculationResult)
38
+ return null;
39
+ calculation = resolvedCalculation.concat(nextCalculationResult);
40
+ return calculation;
41
+ }
42
+ catch (error) {
43
+ log(error, { level: LogLevel.Error });
44
+ }
45
+ return resolvedCalculation;
46
+ }, Promise.resolve([]));
47
+ return calculation;
48
+ },
49
+ getCalculation() {
50
+ return calculation;
51
+ },
52
+ getContext() {
53
+ return context;
54
+ },
55
+ };
56
+ return actions;
57
+ },
58
+ };
59
+ return director;
60
+ };
61
+ //# sourceMappingURL=BasePricingDirector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasePricingDirector.js","sourceRoot":"","sources":["../../src/director/BasePricingDirector.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAMjC,YAAoB,EAOpB,EAAE;IACF,MAAM,YAAY,GAAG,YAAY,CAAiB,YAAY,EAAE;QAC9D,cAAc,EAAE,YAAY;KAC7B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAMV;QACF,GAAG,YAAY;QACf,mBAAmB,EAAE,KAAK,IAAI,EAAE;YAC9B,OAAO,EAAoB,CAAC;QAC9B,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,mBAAmB,EAAE,EAAE;YACrE,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;YAE1E,IAAI,WAAW,GAAuB,EAAE,CAAC;YAEzC,MAAM,OAAO,GAAwD;gBACnE,KAAK,CAAC,SAAS;oBACb,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC;wBACxC,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;4BACzB,OAAO,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;wBACzC,CAAC;qBACF,CAAC,CAAC;oBAEH,WAAW,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,EAAE;wBACrE,MAAM,mBAAmB,GAAG,MAAM,eAAe,CAAC;wBAClD,IAAI,CAAC,mBAAmB;4BAAE,OAAO,IAAI,CAAC;wBAEtC,MAAM,SAAS,GAAoB,MAAM,OAAO,CAAC,GAAG,CAClD,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;4BACzC,UAAU,EAAE,QAAQ,CAAC,GAAG;4BACxB,aAAa,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,iCAAiC,CACrF,QAAQ,EACR,OAAO,CAAC,GAAG,EACX,IAAI,CAAC,gBAAgB,EAAE,EACvB,OAAO,CACR;yBACF,CAAC,CAAC,CACJ,CAAC;wBAEF,IAAI;4BACF,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;gCAC9B,OAAO;gCACP,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,EAAE;gCACzC,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,CAAC;6BAC3E,CAAC,CAAC;4BAEH,MAAM,qBAAqB,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC;4BACxD,IAAI,CAAC,qBAAqB;gCAAE,OAAO,IAAI,CAAC;4BACxC,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;4BAChE,OAAO,WAAW,CAAC;yBACpB;wBAAC,OAAO,KAAK,EAAE;4BACd,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;yBACvC;wBACD,OAAO,mBAAmB,CAAC;oBAC7B,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;oBAExB,OAAO,WAAW,CAAC;gBACrB,CAAC;gBACD,cAAc;oBACZ,OAAO,WAAW,CAAC;gBACrB,CAAC;gBACD,UAAU;oBACR,OAAO,OAAO,CAAC;gBACjB,CAAC;aACF,CAAC;YAEF,OAAO,OAEN,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { PricingCalculation, IBasePricingSheet, PricingSheetParams } from '@unchainedshop/types/pricing';
2
+ export declare const BasePricingSheet: <Calculation extends PricingCalculation>(params: PricingSheetParams<Calculation>) => IBasePricingSheet<Calculation>;
@@ -0,0 +1,55 @@
1
+ export const BasePricingSheet = (params) => {
2
+ const calculation = params.calculation || [];
3
+ const pricingSheet = {
4
+ calculation,
5
+ currency: params.currency,
6
+ quantity: params.quantity,
7
+ getRawPricingSheet() {
8
+ return calculation;
9
+ },
10
+ isValid() {
11
+ return calculation.length > 0;
12
+ },
13
+ sum(filter) {
14
+ return this.filterBy(filter)
15
+ .filter(Boolean)
16
+ .reduce((sum, calculationRow) => sum + calculationRow.amount, 0);
17
+ },
18
+ taxSum() {
19
+ return 0;
20
+ },
21
+ gross() {
22
+ return this.sum();
23
+ },
24
+ net() {
25
+ return this.gross() - this.taxSum();
26
+ },
27
+ total({ category, useNetPrice } = { useNetPrice: false }) {
28
+ if (!category) {
29
+ return {
30
+ amount: Math.round(useNetPrice ? this.net() : this.gross()),
31
+ currency: params.currency,
32
+ };
33
+ }
34
+ return {
35
+ amount: Math.round(this.sum({ category })),
36
+ currency: params.currency,
37
+ };
38
+ },
39
+ filterBy(filter) {
40
+ const filteredCalculation = Object.keys(filter || {}).reduce((oldCalculation, filterKey) => oldCalculation.filter((row) => !!row && (filter[filterKey] === undefined || row[filterKey] === filter[filterKey])), calculation);
41
+ return filteredCalculation;
42
+ },
43
+ resetCalculation(calculationSheet) {
44
+ calculationSheet.filterBy().forEach(({ amount, ...row }) => {
45
+ pricingSheet.calculation.push({
46
+ ...row,
47
+ amount: amount * -1,
48
+ });
49
+ });
50
+ return pricingSheet.calculation;
51
+ },
52
+ };
53
+ return pricingSheet;
54
+ };
55
+ //# sourceMappingURL=BasePricingSheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasePricingSheet.js","sourceRoot":"","sources":["../../src/director/BasePricingSheet.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,MAAuC,EACP,EAAE;IAClC,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IAE7C,MAAM,YAAY,GAAmC;QACnD,WAAW;QACX,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QAEzB,kBAAkB;YAChB,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,OAAO;YACL,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QAChC,CAAC;QAED,GAAG,CAAC,MAAM;YACR,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;iBACzB,MAAM,CAAC,OAAO,CAAC;iBACf,MAAM,CAAC,CAAC,GAAW,EAAE,cAA2B,EAAE,EAAE,CAAC,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1F,CAAC;QAED,MAAM;YACJ,OAAO,CAAC,CAAC;QACX,CAAC;QAED,KAAK;YACH,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;QACpB,CAAC;QAED,GAAG;YACD,OAAO,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE;YACtD,IAAI,CAAC,QAAQ,EAAE;gBACb,OAAO;oBACL,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC3D,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC;aACH;YAED,OAAO;gBACL,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAS,CAAC,CAAC;gBACjD,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC;QACJ,CAAC;QAED,QAAQ,CAAC,MAAM;YACb,MAAM,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,MAAM,CAC1D,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,CAC5B,cAAc,CAAC,MAAM,CACnB,CAAC,GAAgB,EAAE,EAAE,CACnB,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,MAAM,CAAC,SAAS,CAAC,CAAC,CACrF,EACH,WAAW,CACZ,CAAC;YAEF,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QAED,gBAAgB,CAAC,gBAAgB;YAC/B,gBAAgB,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,GAAG,EAAe,EAAE,EAAE;gBACtE,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC;oBAC5B,GAAG,GAAG;oBACN,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC;iBACL,CAAC,CAAC;YACpB,CAAC,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,WAAW,CAAC;QAClC,CAAC;KACF,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export default findLocalizedText;
2
+ declare function findLocalizedText(collection: any, selector: any, locale: any): Promise<any>;
@@ -0,0 +1,39 @@
1
+ import 'abort-controller/polyfill';
2
+ import LRU from 'lru-cache';
3
+ import { systemLocale } from './locale-helpers';
4
+ const { NODE_ENV } = process.env;
5
+ const ttl = NODE_ENV === 'production' ? 1000 * 30 : 0; // 30 seconds or 1 second
6
+ const textCache = new LRU({ 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._name,
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
+ if (exactTranslation) {
24
+ textCache.set(cacheKey, exactTranslation);
25
+ return exactTranslation;
26
+ }
27
+ if (systemLocale.normalized !== locale.normalized) {
28
+ const fallbackTranslation = await collection.findOne(extendSelectorWithLocale(selector, systemLocale));
29
+ if (fallbackTranslation) {
30
+ textCache.set(cacheKey, fallbackTranslation);
31
+ return fallbackTranslation;
32
+ }
33
+ }
34
+ const foundText = await collection.findOne(selector, {});
35
+ textCache.set(cacheKey, foundText);
36
+ return foundText;
37
+ };
38
+ export default findLocalizedText;
39
+ //# sourceMappingURL=find-localized-text.js.map