@stevenkellner/team-conduct-api 1.0.35 → 2.0.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/src/firebase/FirebaseConfiguration.d.ts +45 -1
- package/lib/src/firebase/FirebaseConfiguration.js +44 -0
- package/lib/src/firebase/Firestore.d.ts +196 -0
- package/lib/src/firebase/Firestore.js +235 -0
- package/lib/src/{FirestoreScheme.d.ts → firebase/FirestoreScheme.d.ts} +15 -1
- package/lib/src/firebase/Messaging.d.ts +64 -0
- package/lib/src/firebase/checkAuthentication.d.ts +37 -0
- package/lib/src/{checkAuthentication.js → firebase/checkAuthentication.js} +26 -1
- package/lib/src/firebase/index.d.ts +4 -0
- package/lib/src/firebase/index.js +4 -0
- package/lib/src/firebase/pushNotification.d.ts +39 -0
- package/lib/src/firebase/pushNotification.js +88 -0
- package/lib/src/functions/fine/add.d.ts +10 -13
- package/lib/src/functions/fine/add.js +3 -30
- package/lib/src/functions/fine/delete.d.ts +10 -13
- package/lib/src/functions/fine/delete.js +3 -27
- package/lib/src/functions/fine/update.d.ts +10 -13
- package/lib/src/functions/fine/update.js +3 -28
- package/lib/src/functions/fineTemplate/add.d.ts +6 -9
- package/lib/src/functions/fineTemplate/add.js +3 -12
- package/lib/src/functions/fineTemplate/delete.d.ts +6 -9
- package/lib/src/functions/fineTemplate/delete.js +3 -12
- package/lib/src/functions/fineTemplate/update.d.ts +6 -9
- package/lib/src/functions/fineTemplate/update.js +3 -12
- package/lib/src/functions/invitation/getInvitation.d.ts +41 -42
- package/lib/src/functions/invitation/getInvitation.js +58 -81
- package/lib/src/functions/invitation/invite.d.ts +1 -2
- package/lib/src/functions/invitation/invite.js +3 -18
- package/lib/src/functions/invitation/register.d.ts +6 -11
- package/lib/src/functions/invitation/register.js +3 -39
- package/lib/src/functions/invitation/withdraw.d.ts +1 -2
- package/lib/src/functions/invitation/withdraw.js +3 -13
- package/lib/src/functions/notification/register.d.ts +7 -10
- package/lib/src/functions/notification/register.js +3 -15
- package/lib/src/functions/notification/subscribe.d.ts +8 -11
- package/lib/src/functions/notification/subscribe.js +3 -14
- package/lib/src/functions/paypalMe/edit.d.ts +6 -9
- package/lib/src/functions/paypalMe/edit.js +3 -14
- package/lib/src/functions/person/add.d.ts +7 -10
- package/lib/src/functions/person/add.js +3 -12
- package/lib/src/functions/person/delete.d.ts +6 -9
- package/lib/src/functions/person/delete.js +3 -14
- package/lib/src/functions/person/update.d.ts +7 -10
- package/lib/src/functions/person/update.js +3 -13
- package/lib/src/functions/team/new.d.ts +9 -12
- package/lib/src/functions/team/new.js +3 -22
- package/lib/src/functions/user/kickout.d.ts +6 -9
- package/lib/src/functions/user/kickout.js +3 -25
- package/lib/src/functions/user/login.d.ts +1 -2
- package/lib/src/functions/user/login.js +3 -13
- package/lib/src/functions/user/roleEdit.d.ts +8 -11
- package/lib/src/functions/user/roleEdit.js +3 -18
- package/lib/src/index.d.ts +0 -5
- package/lib/src/index.js +0 -5
- package/lib/src/locales/de.d.ts +10 -67
- package/lib/src/locales/de.js +8 -0
- package/lib/src/locales/en.d.ts +10 -0
- package/lib/src/locales/en.js +19 -2
- package/lib/src/types/Configuration.d.ts +33 -15
- package/lib/src/types/Configuration.js +24 -12
- package/lib/src/types/Currency.d.ts +20 -0
- package/lib/src/types/Currency.js +19 -0
- package/lib/src/types/Fine.d.ts +41 -0
- package/lib/src/types/Fine.js +32 -0
- package/lib/src/types/FineAmount.d.ts +160 -9
- package/lib/src/types/FineAmount.js +128 -7
- package/lib/src/types/FineTemplate.d.ts +41 -0
- package/lib/src/types/FineTemplate.js +32 -0
- package/lib/src/types/FineTemplateRepetition.d.ts +72 -10
- package/lib/src/types/FineTemplateRepetition.js +66 -12
- package/lib/src/types/Invitation.d.ts +48 -0
- package/lib/src/types/Invitation.js +39 -0
- package/lib/src/types/Locale.d.ts +16 -0
- package/lib/src/types/Locale.js +16 -0
- package/lib/src/types/Localization.d.ts +74 -74
- package/lib/src/types/Localization.js +80 -41
- package/lib/src/types/MoneyAmount.d.ts +67 -1
- package/lib/src/types/MoneyAmount.js +62 -0
- package/lib/src/types/NotificationProperties.d.ts +70 -9
- package/lib/src/types/NotificationProperties.js +49 -5
- package/lib/src/types/PayedState.d.ts +25 -9
- package/lib/src/types/PayedState.js +17 -27
- package/lib/src/types/Person.d.ts +45 -0
- package/lib/src/types/Person.js +36 -0
- package/lib/src/types/PersonPrivateProperties.d.ts +28 -0
- package/lib/src/types/PersonPrivateProperties.js +25 -0
- package/lib/src/types/PersonSignInProperties.d.ts +30 -0
- package/lib/src/types/PersonSignInProperties.js +27 -0
- package/lib/src/types/Pluralization.d.ts +46 -0
- package/lib/src/types/Pluralization.js +46 -0
- package/lib/src/types/Team.d.ts +38 -0
- package/lib/src/types/Team.js +29 -0
- package/lib/src/types/User.d.ts +68 -3
- package/lib/src/types/User.js +59 -5
- package/lib/src/types/UserRole.d.ts +26 -4
- package/lib/src/types/UserRole.js +25 -9
- package/lib/src/types/index.d.ts +2 -0
- package/lib/src/types/index.js +2 -0
- package/lib/test/firebase/FirebaseConfiguration.test.js +155 -0
- package/lib/test/firebase/Firestore.test.js +46 -0
- package/lib/test/firebase/checkAuthentication.test.d.ts +1 -0
- package/lib/test/firebase/checkAuthentication.test.js +305 -0
- package/lib/test/firebase/firebase-utils.d.ts +32 -0
- package/lib/test/firebase/firebase-utils.js +131 -0
- package/lib/test/firebase/pushNotification.test.d.ts +1 -0
- package/lib/test/firebase/pushNotification.test.js +300 -0
- package/lib/test/locales/localization.de.test.d.ts +1 -0
- package/lib/test/locales/localization.de.test.js +144 -0
- package/lib/test/locales/localization.en.test.d.ts +1 -0
- package/lib/test/locales/localization.en.test.js +144 -0
- package/lib/test/types/Configuration.test.d.ts +1 -0
- package/lib/test/types/Configuration.test.js +84 -0
- package/lib/test/types/Currency.test.d.ts +1 -0
- package/lib/test/types/Currency.test.js +41 -0
- package/lib/test/types/Fine.test.d.ts +1 -0
- package/lib/test/types/Fine.test.js +265 -0
- package/lib/test/types/FineAmount.test.d.ts +1 -0
- package/lib/test/types/FineAmount.test.js +445 -0
- package/lib/test/types/FineTemplate.test.d.ts +1 -0
- package/lib/test/types/FineTemplate.test.js +271 -0
- package/lib/test/types/FineTemplateRepetition.test.d.ts +1 -0
- package/lib/test/types/FineTemplateRepetition.test.js +361 -0
- package/lib/test/types/Invitation.test.d.ts +1 -0
- package/lib/test/types/Invitation.test.js +269 -0
- package/lib/test/types/Locale.test.d.ts +1 -0
- package/lib/test/types/Locale.test.js +46 -0
- package/lib/test/types/Localization.test.d.ts +1 -0
- package/lib/test/types/Localization.test.js +241 -0
- package/lib/test/types/MoneyAmount.test.d.ts +1 -0
- package/lib/test/types/MoneyAmount.test.js +276 -0
- package/lib/test/types/NotificationProperties.test.d.ts +1 -0
- package/lib/test/types/NotificationProperties.test.js +258 -0
- package/lib/test/types/PayedState.test.d.ts +1 -0
- package/lib/test/types/PayedState.test.js +105 -0
- package/lib/test/types/Person.test.d.ts +1 -0
- package/lib/test/types/Person.test.js +266 -0
- package/lib/test/types/PersonPrivateProperties.test.d.ts +1 -0
- package/lib/test/types/PersonPrivateProperties.test.js +155 -0
- package/lib/test/types/PersonSignInProperties.test.d.ts +1 -0
- package/lib/test/types/PersonSignInProperties.test.js +208 -0
- package/lib/test/types/Pluralization.test.d.ts +1 -0
- package/lib/test/types/Pluralization.test.js +206 -0
- package/lib/test/types/Team.test.d.ts +1 -0
- package/lib/test/types/Team.test.js +145 -0
- package/lib/test/types/User.test.d.ts +1 -0
- package/lib/test/types/User.test.js +232 -0
- package/lib/test/types/UserRole.test.d.ts +1 -0
- package/lib/test/types/UserRole.test.js +140 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/firebase/FirebaseConfiguration.ts +49 -1
- package/src/firebase/Firestore.ts +248 -0
- package/src/{FirestoreScheme.ts → firebase/FirestoreScheme.ts} +15 -1
- package/src/firebase/Messaging.ts +64 -0
- package/src/{checkAuthentication.ts → firebase/checkAuthentication.ts} +39 -1
- package/src/firebase/index.ts +5 -0
- package/src/firebase/pushNotification.ts +90 -0
- package/src/functions/fine/add.ts +10 -48
- package/src/functions/fine/delete.ts +9 -43
- package/src/functions/fine/update.ts +10 -44
- package/src/functions/fineTemplate/add.ts +7 -23
- package/src/functions/fineTemplate/delete.ts +7 -23
- package/src/functions/fineTemplate/update.ts +7 -24
- package/src/functions/index.ts +0 -1
- package/src/functions/invitation/getInvitation.ts +83 -109
- package/src/functions/invitation/invite.ts +2 -25
- package/src/functions/invitation/register.ts +9 -60
- package/src/functions/invitation/withdraw.ts +2 -16
- package/src/functions/notification/register.ts +7 -26
- package/src/functions/notification/subscribe.ts +8 -26
- package/src/functions/paypalMe/edit.ts +7 -25
- package/src/functions/person/add.ts +8 -24
- package/src/functions/person/delete.ts +6 -25
- package/src/functions/person/update.ts +8 -25
- package/src/functions/team/new.ts +12 -42
- package/src/functions/user/kickout.ts +8 -41
- package/src/functions/user/login.ts +2 -16
- package/src/functions/user/roleEdit.ts +8 -32
- package/src/index.ts +0 -5
- package/src/locales/de.ts +10 -1
- package/src/locales/en.ts +21 -2
- package/src/types/Configuration.ts +33 -23
- package/src/types/Currency.ts +24 -0
- package/src/types/Fine.ts +41 -0
- package/src/types/FineAmount.ts +162 -11
- package/src/types/FineTemplate.ts +41 -0
- package/src/types/FineTemplateRepetition.ts +75 -17
- package/src/types/Invitation.ts +48 -0
- package/src/types/Locale.ts +20 -0
- package/src/types/Localization.ts +96 -41
- package/src/types/MoneyAmount.ts +67 -1
- package/src/types/NotificationProperties.ts +67 -9
- package/src/types/PayedState.ts +25 -30
- package/src/types/Person.ts +45 -0
- package/src/types/PersonPrivateProperties.ts +28 -1
- package/src/types/PersonSignInProperties.ts +30 -0
- package/src/types/Pluralization.ts +46 -0
- package/src/types/Team.ts +38 -0
- package/src/types/User.ts +70 -4
- package/src/types/UserRole.ts +32 -16
- package/src/types/index.ts +2 -0
- package/lib/src/Firestore.d.ts +0 -24
- package/lib/src/Firestore.js +0 -62
- package/lib/src/checkAuthentication.d.ts +0 -6
- package/lib/src/firebaseFunctionsContext.d.ts +0 -39
- package/lib/src/firebaseFunctionsContext.js +0 -43
- package/lib/src/pushNotification.d.ts +0 -3
- package/lib/src/pushNotification.js +0 -35
- package/lib/test/localization-utils.d.ts +0 -1
- package/lib/test/localization-utils.js +0 -24
- package/lib/test/localization.de.test.js +0 -151
- package/lib/test/localization.en.test.js +0 -145
- package/src/Firestore.ts +0 -75
- package/src/firebaseFunctionsContext.ts +0 -48
- package/src/pushNotification.ts +0 -37
- /package/lib/src/{FirestoreScheme.js → firebase/FirestoreScheme.js} +0 -0
- /package/lib/test/{localization.de.test.d.ts → firebase/FirebaseConfiguration.test.d.ts} +0 -0
- /package/lib/test/{localization.en.test.d.ts → firebase/Firestore.test.d.ts} +0 -0
|
@@ -1,26 +1,100 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mapRecord } from '@stevenkellner/typescript-common-functionality';
|
|
2
2
|
import { localizationEN } from '../locales/en';
|
|
3
3
|
import { localizationDE } from '../locales/de';
|
|
4
4
|
import { Pluralization } from './Pluralization';
|
|
5
|
+
import { Locale } from './Locale';
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Type representing the structure of a localization dictionary.
|
|
9
|
+
* Derived from the English localization as the base template.
|
|
10
|
+
*/
|
|
11
|
+
export type LocalizationDict = typeof localizationEN;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Helper function to ensure a record satisfies the localization structure
|
|
15
|
+
* while preserving its concrete type.
|
|
16
|
+
*/
|
|
17
|
+
const satisfiesLocalizationRecord = <T extends Record<string, LocalizationDict>>(value: T): T => value;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Record of all available localizations keyed by locale.
|
|
21
|
+
* Each localization must match the structure of LocalizationDict.
|
|
22
|
+
*/
|
|
23
|
+
export const localizations = satisfiesLocalizationRecord({
|
|
7
24
|
en: localizationEN,
|
|
8
25
|
de: localizationDE
|
|
9
|
-
};
|
|
26
|
+
});
|
|
10
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Recursive type definition for localization values.
|
|
30
|
+
* Can be nested objects, strings with template variables, or Pluralization instances.
|
|
31
|
+
*/
|
|
11
32
|
export type SubLocalizationType = { [Key in string]: SubLocalizationType } | string | Pluralization;
|
|
12
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Mapped type that transforms SubLocalizationType into corresponding localization classes.
|
|
36
|
+
* - Objects become nested SubLocalization structures
|
|
37
|
+
* - Strings become ValueLocalization instances
|
|
38
|
+
* - Pluralization instances become PluralLocalization instances
|
|
39
|
+
*/
|
|
13
40
|
export type SubLocalization<T extends SubLocalizationType> =
|
|
14
41
|
T extends { [Key in string]: SubLocalizationType } ? { [Key in keyof T]: SubLocalization<T[Key]> } :
|
|
15
42
|
T extends string ? ValueLocalization :
|
|
16
43
|
T extends Pluralization ? PluralLocalization : never;
|
|
17
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Main localization class that provides access to localized strings.
|
|
47
|
+
* Transforms raw localization data into type-safe localization objects.
|
|
48
|
+
*/
|
|
49
|
+
export class Localization {
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Returns the localization structure for the specified locale.
|
|
53
|
+
* Transforms the raw localization data into ValueLocalization and PluralLocalization instances.
|
|
54
|
+
* @param locale - The locale to retrieve localizations for
|
|
55
|
+
* @returns The complete localization structure with type-safe access
|
|
56
|
+
*/
|
|
57
|
+
public static shared(locale: Locale): SubLocalization<LocalizationDict> {
|
|
58
|
+
return Localization.mapSubLocalization(localizations[locale]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Recursively maps raw localization data to localization class instances.
|
|
63
|
+
* @param localization - The raw localization value to transform
|
|
64
|
+
* @returns The transformed localization with proper class instances
|
|
65
|
+
*/
|
|
66
|
+
private static mapSubLocalization<T extends SubLocalizationType>(localization: T): SubLocalization<T> {
|
|
67
|
+
if (typeof localization === 'object' && ! (localization instanceof Pluralization))
|
|
68
|
+
return mapRecord(localization as Record<string, SubLocalizationType>, subLocalization => Localization.mapSubLocalization(subLocalization)) as SubLocalization<T>;
|
|
69
|
+
if (typeof localization === 'string')
|
|
70
|
+
return new ValueLocalization(localization) as SubLocalization<T>;
|
|
71
|
+
if (localization instanceof Pluralization)
|
|
72
|
+
return new PluralLocalization(localization) as SubLocalization<T>;
|
|
73
|
+
throw new Error('Invalid localization structure');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Handles localization strings with template variable substitution.
|
|
79
|
+
* Supports {{variableName}} syntax for runtime value replacement.
|
|
80
|
+
*/
|
|
18
81
|
export class ValueLocalization {
|
|
19
82
|
|
|
20
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Creates a new ValueLocalization instance.
|
|
85
|
+
* @param rawValue - The template string with {{variable}} placeholders
|
|
86
|
+
*/
|
|
87
|
+
constructor(private readonly rawValue: string) {}
|
|
21
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Returns the localized string with variables substituted.
|
|
91
|
+
* Template variables in the format {{key}} are replaced with provided argument values.
|
|
92
|
+
* @param args - Record of variable names to their replacement values
|
|
93
|
+
* @returns The localized string with all variables replaced
|
|
94
|
+
* @throws Error if a required template variable is not provided in args
|
|
95
|
+
*/
|
|
22
96
|
public value(args: Record<string, string> = {}): string {
|
|
23
|
-
let rawValue = this.
|
|
97
|
+
let rawValue = this.rawValue;
|
|
24
98
|
const regex = /\{\{(?<key>.*?)\}\}/;
|
|
25
99
|
while (true) {
|
|
26
100
|
const match = regex.exec(rawValue);
|
|
@@ -35,49 +109,30 @@ export class ValueLocalization {
|
|
|
35
109
|
}
|
|
36
110
|
}
|
|
37
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Handles pluralized localization strings that vary based on count.
|
|
114
|
+
* Combines Pluralization logic with template variable substitution.
|
|
115
|
+
*/
|
|
38
116
|
export class PluralLocalization {
|
|
39
117
|
|
|
40
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Creates a new PluralLocalization instance.
|
|
120
|
+
* @param pluralization - The Pluralization instance containing plural forms
|
|
121
|
+
*/
|
|
122
|
+
constructor(private readonly pluralization: Pluralization) {}
|
|
41
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Returns the appropriate pluralized string for the given count with variables substituted.
|
|
126
|
+
* Automatically includes 'count' in the template variables.
|
|
127
|
+
* @param count - The count to determine which plural form to use
|
|
128
|
+
* @param args - Additional template variables to substitute (count is added automatically)
|
|
129
|
+
* @returns The localized plural string with all variables replaced
|
|
130
|
+
*/
|
|
42
131
|
public value(count: number, args: Record<string, string> = {}): string {
|
|
43
|
-
const valueLocalization = new ValueLocalization(
|
|
132
|
+
const valueLocalization = new ValueLocalization(this.pluralization.get(count));
|
|
44
133
|
return valueLocalization.value({
|
|
45
134
|
count: `${count}`,
|
|
46
135
|
...args
|
|
47
136
|
});
|
|
48
137
|
}
|
|
49
138
|
}
|
|
50
|
-
|
|
51
|
-
function swap1stAnd2ndLevel<Level1Key extends string, Level2Key extends string, T>(record: Record<Level1Key, Record<Level2Key, T>>): Record<Level2Key, Record<Level1Key, T>> {
|
|
52
|
-
const swapped = {} as Record<Level2Key, Record<Level1Key, T>>;
|
|
53
|
-
for (const key1 of keys(record)) {
|
|
54
|
-
for (const key2 of keys(record[key1]) as Level2Key[]) {
|
|
55
|
-
if (!(key2 in swapped))
|
|
56
|
-
swapped[key2] = {} as Record<Level1Key, T>;
|
|
57
|
-
swapped[key2][key1] = record[key1][key2];
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return swapped;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export class Localization {
|
|
64
|
-
|
|
65
|
-
public static locale: keyof typeof localizations = 'en';
|
|
66
|
-
|
|
67
|
-
public static readonly shared = Localization.getSubLocalization(localizations);
|
|
68
|
-
|
|
69
|
-
private static getSubLocalization<T extends SubLocalizationType>(_localizations: Record<keyof typeof localizations, T>): SubLocalization<T> {
|
|
70
|
-
const _localizationValue = values(_localizations);
|
|
71
|
-
if (_localizationValue.length === 0)
|
|
72
|
-
return {} as SubLocalization<T>;
|
|
73
|
-
if (typeof _localizationValue[0] === 'object' && !(_localizationValue[0] instanceof Pluralization)) {
|
|
74
|
-
const swapped = swap1stAnd2ndLevel(_localizations as Record<string, Record<string, SubLocalizationType>>);
|
|
75
|
-
return mapRecord(swapped, subLocalization => Localization.getSubLocalization(subLocalization)) as SubLocalization<T>;
|
|
76
|
-
}
|
|
77
|
-
if (typeof _localizationValue[0] === 'string')
|
|
78
|
-
return new ValueLocalization(_localizations as Record<keyof typeof localizations, string>) as SubLocalization<T>;
|
|
79
|
-
if (_localizationValue[0] instanceof Pluralization)
|
|
80
|
-
return new PluralLocalization(_localizations as Record<keyof typeof localizations, Pluralization>) as SubLocalization<T>;
|
|
81
|
-
throw new Error('Invalid localization structure');
|
|
82
|
-
}
|
|
83
|
-
}
|
package/src/types/MoneyAmount.ts
CHANGED
|
@@ -1,30 +1,71 @@
|
|
|
1
1
|
import { Flattable, ITypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
2
2
|
import { Configuration } from './Configuration';
|
|
3
|
+
import { Currency } from './Currency';
|
|
3
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Represents a monetary amount with integer value and subunit components.
|
|
7
|
+
*
|
|
8
|
+
* Stores money as two parts: main value (e.g., dollars) and subunit value (e.g., cents).
|
|
9
|
+
* This prevents floating-point precision issues in financial calculations.
|
|
10
|
+
*/
|
|
4
11
|
export class MoneyAmount implements Flattable<MoneyAmount.Flatten> {
|
|
5
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new MoneyAmount instance.
|
|
15
|
+
*
|
|
16
|
+
* @param value - The main value (e.g., dollars, euros)
|
|
17
|
+
* @param subunitValue - The subunit value (e.g., cents), should be 0-99
|
|
18
|
+
*/
|
|
6
19
|
public constructor(
|
|
7
20
|
public value: number,
|
|
8
21
|
public subunitValue: number
|
|
9
22
|
) {}
|
|
10
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Returns a MoneyAmount representing zero.
|
|
26
|
+
*/
|
|
11
27
|
public static get zero(): MoneyAmount {
|
|
12
28
|
return new MoneyAmount(0, 0);
|
|
13
29
|
}
|
|
14
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Adds another MoneyAmount to this one and returns the result.
|
|
33
|
+
*
|
|
34
|
+
* Properly handles subunit overflow (e.g., 50 cents + 60 cents = 1 dollar 10 cents).
|
|
35
|
+
*
|
|
36
|
+
* @param amount - The MoneyAmount to add
|
|
37
|
+
* @returns A new MoneyAmount representing the sum
|
|
38
|
+
*/
|
|
15
39
|
public added(amount: MoneyAmount): MoneyAmount {
|
|
16
40
|
const subunitValue = this.subunitValue + amount.subunitValue;
|
|
17
41
|
const value = this.value + amount.value + Math.floor(subunitValue / 100);
|
|
18
42
|
return new MoneyAmount(value, subunitValue % 100);
|
|
19
43
|
}
|
|
20
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Multiplies this MoneyAmount by a factor and returns the result.
|
|
47
|
+
*
|
|
48
|
+
* Properly handles subunit calculations and overflow.
|
|
49
|
+
*
|
|
50
|
+
* @param factor - The multiplication factor
|
|
51
|
+
* @returns A new MoneyAmount representing the product
|
|
52
|
+
*/
|
|
21
53
|
public multiplied(factor: number): MoneyAmount {
|
|
22
54
|
const subunitValue = this.subunitValue * factor;
|
|
23
55
|
const value = this.value * factor + Math.floor(subunitValue / 100);
|
|
24
56
|
return new MoneyAmount(value, subunitValue % 100);
|
|
25
57
|
}
|
|
26
58
|
|
|
27
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Returns a localized formatted string representation of the amount.
|
|
61
|
+
*
|
|
62
|
+
* Uses Intl.NumberFormat for proper currency formatting based on locale.
|
|
63
|
+
*
|
|
64
|
+
* @param currency - The currency code (e.g., 'USD', 'EUR')
|
|
65
|
+
* @param configuration - Configuration containing locale information
|
|
66
|
+
* @returns Formatted currency string (e.g., "$12.50", "12,50 €")
|
|
67
|
+
*/
|
|
68
|
+
public formatted(currency: Currency, configuration: Configuration): string {
|
|
28
69
|
const numberFormat = Intl.NumberFormat(configuration.locale, {
|
|
29
70
|
style: 'currency',
|
|
30
71
|
currency: currency
|
|
@@ -32,10 +73,18 @@ export class MoneyAmount implements Flattable<MoneyAmount.Flatten> {
|
|
|
32
73
|
return numberFormat.format(this.value + this.subunitValue / 100);
|
|
33
74
|
}
|
|
34
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Returns the complete monetary value as a decimal number.
|
|
78
|
+
*
|
|
79
|
+
* @returns The total value (e.g., 12.50 for 12 dollars and 50 cents)
|
|
80
|
+
*/
|
|
35
81
|
public get completeValue(): number {
|
|
36
82
|
return this.value + this.subunitValue / 100;
|
|
37
83
|
}
|
|
38
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Returns the flattened representation as a decimal number.
|
|
87
|
+
*/
|
|
39
88
|
public get flatten(): MoneyAmount.Flatten {
|
|
40
89
|
return this.value + this.subunitValue / 100;
|
|
41
90
|
}
|
|
@@ -43,14 +92,31 @@ export class MoneyAmount implements Flattable<MoneyAmount.Flatten> {
|
|
|
43
92
|
|
|
44
93
|
export namespace MoneyAmount {
|
|
45
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Flattened representation of MoneyAmount as a decimal number.
|
|
97
|
+
*/
|
|
46
98
|
export type Flatten = number;
|
|
47
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Type builder for MoneyAmount serialization/deserialization.
|
|
102
|
+
*/
|
|
48
103
|
export class TypeBuilder implements ITypeBuilder<Flatten, MoneyAmount> {
|
|
49
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Builds a MoneyAmount instance from a flattened decimal value.
|
|
107
|
+
*
|
|
108
|
+
* Separates the decimal into integer and subunit parts.
|
|
109
|
+
*
|
|
110
|
+
* @param value - Decimal value (e.g., 12.50)
|
|
111
|
+
* @returns MoneyAmount instance
|
|
112
|
+
*/
|
|
50
113
|
public build(value: Flatten): MoneyAmount {
|
|
51
114
|
return new MoneyAmount(Math.floor(value), Math.round((value - Math.floor(value)) * 100));
|
|
52
115
|
}
|
|
53
116
|
}
|
|
54
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Singleton instance of TypeBuilder for MoneyAmount.
|
|
120
|
+
*/
|
|
55
121
|
export const builder = new MoneyAmount.TypeBuilder();
|
|
56
122
|
}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import { BytesCoder, Dictionary, Flattable, ITypeBuilder, Sha512, Tagged, ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Represents notification properties for a user including device tokens and subscription preferences.
|
|
5
|
+
*
|
|
6
|
+
* Manages push notification device tokens (identified by hashed token IDs for security)
|
|
7
|
+
* and user preferences for which types of notifications they want to receive.
|
|
8
|
+
*/
|
|
3
9
|
export class NotificationProperties implements Flattable<NotificationProperties.Flatten> {
|
|
4
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates new notification properties.
|
|
13
|
+
* @param tokens - Dictionary mapping token IDs to device tokens for push notifications (defaults to empty)
|
|
14
|
+
* @param subscriptions - Array of notification types the user is subscribed to (defaults to empty)
|
|
15
|
+
*/
|
|
5
16
|
public constructor(
|
|
6
17
|
public tokens: Dictionary<NotificationProperties.TokenId, string> = new Dictionary(NotificationProperties.TokenId.builder),
|
|
7
18
|
public subscriptions: NotificationProperties.Subscription[] = []
|
|
8
19
|
) {}
|
|
9
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Gets the flattened representation of these notification properties for serialization.
|
|
23
|
+
*/
|
|
10
24
|
public get flatten(): NotificationProperties.Flatten {
|
|
11
25
|
return {
|
|
12
26
|
tokens: this.tokens.flatten,
|
|
@@ -17,10 +31,20 @@ export class NotificationProperties implements Flattable<NotificationProperties.
|
|
|
17
31
|
|
|
18
32
|
export namespace NotificationProperties {
|
|
19
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Tagged type for notification token identifiers.
|
|
36
|
+
* Token IDs are derived from hashing the actual device tokens for security.
|
|
37
|
+
*/
|
|
20
38
|
export type TokenId = Tagged<string, 'notificationToken'>;
|
|
21
39
|
|
|
22
40
|
export namespace TokenId {
|
|
23
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Creates a token ID from a device token by hashing it with SHA-512.
|
|
44
|
+
* Only the first 16 characters of the hash are used as the identifier.
|
|
45
|
+
* @param token - The device push notification token
|
|
46
|
+
* @returns A hashed token ID for secure storage and lookup
|
|
47
|
+
*/
|
|
24
48
|
export function create(token: string): TokenId {
|
|
25
49
|
const hasher = new Sha512();
|
|
26
50
|
const tokenBytes = BytesCoder.fromUtf8(token);
|
|
@@ -30,38 +54,72 @@ export namespace NotificationProperties {
|
|
|
30
54
|
return new Tagged(rawId, 'notificationToken');
|
|
31
55
|
}
|
|
32
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Flattened representation of a token ID (plain string).
|
|
59
|
+
*/
|
|
33
60
|
export type Flatten = string;
|
|
34
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Builder for constructing TokenId instances from strings.
|
|
64
|
+
*/
|
|
35
65
|
export const builder = Tagged.builder('notificationToken' as const, new ValueTypeBuilder<string>());
|
|
36
66
|
}
|
|
37
67
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Available notification subscription types.
|
|
70
|
+
*/
|
|
71
|
+
const subscriptions = [
|
|
72
|
+
'new-fine',
|
|
73
|
+
'fine-reminder',
|
|
74
|
+
'fine-state-change'
|
|
75
|
+
] as const;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Type representing the available notification subscription options.
|
|
79
|
+
* - new-fine: Notifications when a new fine is created
|
|
80
|
+
* - fine-reminder: Reminder notifications for unpaid fines
|
|
81
|
+
* - fine-state-change: Notifications when a fine's status changes
|
|
82
|
+
*/
|
|
83
|
+
export type Subscription = typeof subscriptions[number];
|
|
42
84
|
|
|
43
85
|
export namespace Subscription {
|
|
44
86
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
]
|
|
87
|
+
/**
|
|
88
|
+
* Readonly array of all available subscription types.
|
|
89
|
+
*/
|
|
90
|
+
export const all: readonly Subscription[] = subscriptions
|
|
50
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Builder for constructing Subscription values from strings.
|
|
94
|
+
*/
|
|
51
95
|
export const builder = new ValueTypeBuilder<Subscription>();
|
|
52
96
|
}
|
|
53
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Flattened representation of notification properties for serialization.
|
|
100
|
+
*/
|
|
54
101
|
export type Flatten = {
|
|
55
102
|
tokens: Dictionary.Flatten<string>,
|
|
56
103
|
subscriptions: Subscription[]
|
|
57
104
|
};
|
|
58
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Builder for constructing NotificationProperties from flattened data.
|
|
108
|
+
*/
|
|
59
109
|
export class TypeBuilder implements ITypeBuilder<Flatten, NotificationProperties> {
|
|
60
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Builds a NotificationProperties instance from flattened data.
|
|
113
|
+
* @param value - The flattened notification properties data
|
|
114
|
+
* @returns A new NotificationProperties instance
|
|
115
|
+
*/
|
|
61
116
|
public build(value: Flatten): NotificationProperties {
|
|
62
117
|
return new NotificationProperties(Dictionary.builder(TokenId.builder, new ValueTypeBuilder<string>()).build(value.tokens), value.subscriptions);
|
|
63
118
|
}
|
|
64
119
|
}
|
|
65
120
|
|
|
121
|
+
/**
|
|
122
|
+
* Singleton builder instance for NotificationProperties.
|
|
123
|
+
*/
|
|
66
124
|
export const builder = new TypeBuilder();
|
|
67
125
|
}
|
package/src/types/PayedState.ts
CHANGED
|
@@ -1,41 +1,36 @@
|
|
|
1
1
|
import { ValueTypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
2
2
|
import { Localization } from './Localization';
|
|
3
|
+
import { Locale } from './Locale';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
| 'payed'
|
|
6
|
-
| 'notPayed';
|
|
5
|
+
const payedStates = ['payed', 'notPayed'] as const;
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Represents the payment status of a fine.
|
|
9
|
+
*
|
|
10
|
+
* Can be either 'payed' (fine has been paid) or 'notPayed' (fine is unpaid).
|
|
11
|
+
*/
|
|
12
|
+
export type PayedState = typeof payedStates[number];
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
return Localization.shared.payedState[state].value();
|
|
14
|
-
}
|
|
14
|
+
export namespace PayedState {
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
case 'notPayed':
|
|
21
|
-
return 'payed';
|
|
22
|
-
}
|
|
23
|
-
}
|
|
16
|
+
/**
|
|
17
|
+
* Array containing all possible payment states.
|
|
18
|
+
*/
|
|
19
|
+
export const all: readonly PayedState[] = payedStates;
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
value: formatted(state),
|
|
35
|
-
severity: 'danger'
|
|
36
|
-
};
|
|
37
|
-
}
|
|
21
|
+
/**
|
|
22
|
+
* Returns the localized display string for a payment state.
|
|
23
|
+
*
|
|
24
|
+
* @param state - The payment state to format
|
|
25
|
+
* @param locale - The locale to use for formatting
|
|
26
|
+
* @returns Localized string representation of the payment state
|
|
27
|
+
*/
|
|
28
|
+
export function formatted(state: PayedState, locale: Locale): string {
|
|
29
|
+
return Localization.shared(locale).payedState[state].value();
|
|
38
30
|
}
|
|
39
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Type builder for PayedState serialization/deserialization.
|
|
34
|
+
*/
|
|
40
35
|
export const builder = new ValueTypeBuilder<PayedState>();
|
|
41
36
|
}
|
package/src/types/Person.ts
CHANGED
|
@@ -3,8 +3,21 @@ import { PersonSignInProperties } from './PersonSignInProperties';
|
|
|
3
3
|
import { Fine } from './Fine';
|
|
4
4
|
import { Flattable, Guid, ITypeBuilder, Tagged } from '@stevenkellner/typescript-common-functionality';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Represents a person within a team, including their personal details, assigned fines, and optional sign-in properties.
|
|
8
|
+
*
|
|
9
|
+
* A person can have multiple fines assigned to them and may or may not be signed in (have sign-in properties).
|
|
10
|
+
*/
|
|
6
11
|
export class Person implements Flattable<Person.Flatten> {
|
|
7
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new Person instance.
|
|
15
|
+
*
|
|
16
|
+
* @param id - Unique identifier for the person (GUID)
|
|
17
|
+
* @param properties - Private properties including first name and optional last name
|
|
18
|
+
* @param fineIds - Array of fine IDs assigned to this person (defaults to empty array)
|
|
19
|
+
* @param signInProperties - Optional sign-in properties if the person has signed in (defaults to null)
|
|
20
|
+
*/
|
|
8
21
|
public constructor(
|
|
9
22
|
public id: Person.Id,
|
|
10
23
|
public properties: PersonPrivateProperties,
|
|
@@ -12,6 +25,9 @@ export class Person implements Flattable<Person.Flatten> {
|
|
|
12
25
|
public signInProperties: PersonSignInProperties | null = null
|
|
13
26
|
) {}
|
|
14
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Returns the flattened representation of the person for serialization.
|
|
30
|
+
*/
|
|
15
31
|
public get flatten(): Person.Flatten {
|
|
16
32
|
return {
|
|
17
33
|
id: this.id.flatten,
|
|
@@ -21,6 +37,11 @@ export class Person implements Flattable<Person.Flatten> {
|
|
|
21
37
|
};
|
|
22
38
|
}
|
|
23
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Returns the person's full name.
|
|
42
|
+
*
|
|
43
|
+
* If lastName is null, returns only firstName. Otherwise returns "firstName lastName".
|
|
44
|
+
*/
|
|
24
45
|
public get name(): string {
|
|
25
46
|
if (this.properties.lastName === null)
|
|
26
47
|
return this.properties.firstName;
|
|
@@ -30,15 +51,27 @@ export class Person implements Flattable<Person.Flatten> {
|
|
|
30
51
|
|
|
31
52
|
export namespace Person {
|
|
32
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Tagged GUID type for person identifiers.
|
|
56
|
+
*/
|
|
33
57
|
export type Id = Tagged<Guid, 'person'>;
|
|
34
58
|
|
|
35
59
|
export namespace Id {
|
|
36
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Flattened representation of a person ID (GUID string).
|
|
63
|
+
*/
|
|
37
64
|
export type Flatten = string;
|
|
38
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Type builder for Person.Id serialization/deserialization.
|
|
68
|
+
*/
|
|
39
69
|
export const builder = Tagged.builder('person' as const, Guid.builder);
|
|
40
70
|
}
|
|
41
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Flattened representation of a Person for serialization.
|
|
74
|
+
*/
|
|
42
75
|
export type Flatten = {
|
|
43
76
|
id: Id.Flatten,
|
|
44
77
|
properties: PersonPrivateProperties.Flatten,
|
|
@@ -46,8 +79,17 @@ export namespace Person {
|
|
|
46
79
|
signInProperties: PersonSignInProperties.Flatten | null,
|
|
47
80
|
}
|
|
48
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Type builder for Person serialization/deserialization.
|
|
84
|
+
*/
|
|
49
85
|
export class TypeBuilder implements ITypeBuilder<Flatten, Person> {
|
|
50
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Builds a Person instance from flattened data.
|
|
89
|
+
*
|
|
90
|
+
* @param value - Flattened person data
|
|
91
|
+
* @returns Person instance
|
|
92
|
+
*/
|
|
51
93
|
public build(value: Flatten): Person {
|
|
52
94
|
return new Person(
|
|
53
95
|
Id.builder.build(value.id),
|
|
@@ -58,5 +100,8 @@ export namespace Person {
|
|
|
58
100
|
}
|
|
59
101
|
}
|
|
60
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Singleton instance of TypeBuilder for Person.
|
|
105
|
+
*/
|
|
61
106
|
export const builder = new TypeBuilder();
|
|
62
107
|
}
|
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import { Flattable, ITypeBuilder } from '@stevenkellner/typescript-common-functionality';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Represents the private properties of a person.
|
|
5
|
+
*
|
|
6
|
+
* Contains personal information that is private to the person,
|
|
7
|
+
* such as their name. The last name is optional.
|
|
8
|
+
*/
|
|
3
9
|
export class PersonPrivateProperties implements Flattable<PersonPrivateProperties.Flatten> {
|
|
4
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates new person private properties.
|
|
13
|
+
* @param firstName - The first name of the person
|
|
14
|
+
* @param lastName - The last name of the person (null if not provided)
|
|
15
|
+
*/
|
|
5
16
|
constructor(
|
|
6
17
|
public firstName: string,
|
|
7
18
|
public lastName: string | null
|
|
8
19
|
) {}
|
|
9
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Gets the flattened representation of these properties for serialization.
|
|
23
|
+
*/
|
|
10
24
|
public get flatten(): PersonPrivateProperties.Flatten {
|
|
11
25
|
return {
|
|
12
26
|
firstName: this.firstName,
|
|
@@ -17,13 +31,24 @@ export class PersonPrivateProperties implements Flattable<PersonPrivatePropertie
|
|
|
17
31
|
|
|
18
32
|
export namespace PersonPrivateProperties {
|
|
19
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Flattened representation of person private properties for serialization.
|
|
36
|
+
*/
|
|
20
37
|
export type Flatten = {
|
|
21
38
|
firstName: string;
|
|
22
39
|
lastName: string | null;
|
|
23
40
|
}
|
|
24
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Builder for constructing PersonPrivateProperties from flattened data.
|
|
44
|
+
*/
|
|
25
45
|
export class TypeBuilder implements ITypeBuilder<Flatten, PersonPrivateProperties> {
|
|
26
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Builds a PersonPrivateProperties instance from flattened data.
|
|
49
|
+
* @param value - The flattened person private properties data
|
|
50
|
+
* @returns A new PersonPrivateProperties instance
|
|
51
|
+
*/
|
|
27
52
|
public build(value: Flatten): PersonPrivateProperties {
|
|
28
53
|
return new PersonPrivateProperties(
|
|
29
54
|
value.firstName,
|
|
@@ -32,6 +57,8 @@ export namespace PersonPrivateProperties {
|
|
|
32
57
|
}
|
|
33
58
|
}
|
|
34
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Singleton builder instance for PersonPrivateProperties.
|
|
62
|
+
*/
|
|
35
63
|
export const builder = new TypeBuilder();
|
|
36
64
|
}
|
|
37
|
-
|