@forwardslashns/taskit-validation-messages 1.0.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.
@@ -0,0 +1,27 @@
1
+ name: Node.js Package
2
+
3
+ on:
4
+ push:
5
+ branches: master
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v3
12
+ - uses: actions/setup-node@v3
13
+ with:
14
+ node-version: 22
15
+ - run: npm ci
16
+
17
+ publish-npm:
18
+ needs: build
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: actions/checkout@v3
22
+ - uses: actions/setup-node@v3
23
+ with:
24
+ node-version: 22
25
+ registry-url: https://registry.npmjs.org/
26
+ - run: npm ci
27
+ - run: npm publish
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # Taskit Validation Messages
2
+
3
+ This package provides a centralized list of validation messages used across both frontend and backend of the project. It ensures consistent error display and simplifies maintenance by keeping all validation messages in one place, without altering code in development repositories.
4
+
5
+ # VALIDATION_MESSAGES
6
+
7
+ The package exposes validation messages that can be retrieved using specific aliases. These messages are organized by the features they belong to, making it easier to manage and update them.
8
+
9
+ # getValidationMessage
10
+
11
+ This mechanism allows for the retrieval and dynamic creation of validation messages by passing their aliases and any required parameters. Parameters are optional and passed as objects, following the structure defined within each validation message itself.
@@ -0,0 +1,4 @@
1
+ import { getValidationMessage } from "./validation/validation-message.formatter";
2
+ import { VALIDATION_MESSAGES } from "./validation/validation-messages";
3
+ export { VALIDATION_MESSAGES, getValidationMessage };
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidationMessage = exports.VALIDATION_MESSAGES = void 0;
4
+ const validation_message_formatter_1 = require("./validation/validation-message.formatter");
5
+ Object.defineProperty(exports, "getValidationMessage", { enumerable: true, get: function () { return validation_message_formatter_1.getValidationMessage; } });
6
+ const validation_messages_1 = require("./validation/validation-messages");
7
+ Object.defineProperty(exports, "VALIDATION_MESSAGES", { enumerable: true, get: function () { return validation_messages_1.VALIDATION_MESSAGES; } });
@@ -0,0 +1,12 @@
1
+ import { VALIDATION_MESSAGES } from './validation-messages';
2
+ type Features = keyof typeof VALIDATION_MESSAGES;
3
+ type ErrorType<F extends Features> = keyof (typeof VALIDATION_MESSAGES)[F];
4
+ type ErrorMessageParams<F extends Features, E extends ErrorType<F>> = (typeof VALIDATION_MESSAGES)[F][E] extends {
5
+ params: infer P extends readonly string[];
6
+ } ? P : [];
7
+ type MessageParams<T extends readonly string[]> = {
8
+ [K in T[number]]: string;
9
+ };
10
+ export declare const getValidationMessage: <FeatureType extends Features, FeatureErrorType extends ErrorType<FeatureType>>(feature: FeatureType, featureError: FeatureErrorType, params?: MessageParams<ErrorMessageParams<FeatureType, FeatureErrorType>>) => string;
11
+ export {};
12
+ //# sourceMappingURL=validation-message.formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-message.formatter.d.ts","sourceRoot":"","sources":["../../src/validation/validation-message.formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,KAAK,QAAQ,GAAG,MAAM,OAAO,mBAAmB,CAAC;AACjD,KAAK,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3E,KAAK,kBAAkB,CACrB,CAAC,SAAS,QAAQ,EAClB,CAAC,SAAS,SAAS,CAAC,CAAC,CAAC,IACpB,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;IAC7C,MAAM,EAAE,MAAM,CAAC,SAAS,SAAS,MAAM,EAAE,CAAC;CAC3C,GACG,CAAC,GACD,EAAE,CAAC;AACP,KAAK,aAAa,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,IAAI;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM;CAAE,CAAC;AAM/E,eAAO,MAAM,oBAAoB,GAC/B,WAAW,SAAS,QAAQ,EAC5B,gBAAgB,SAAS,SAAS,CAAC,WAAW,CAAC,EAE/C,SAAS,WAAW,EACpB,cAAc,gBAAgB,EAC9B,SAAS,aAAa,CAAC,kBAAkB,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,KACxE,MAuDF,CAAC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidationMessage = void 0;
4
+ const validation_messages_1 = require("./validation-messages");
5
+ const getValidationMessage = (feature, featureError, params) => {
6
+ const messageConfig = validation_messages_1.VALIDATION_MESSAGES[feature][featureError];
7
+ if (!messageConfig) {
8
+ throw new Error(`Validation error message is not defined properly in configuration for feature: '${String(feature)}', error: '${String(featureError)}')`);
9
+ }
10
+ const inputParams = params || {};
11
+ const errorSuffix = `for feature: ${String(feature)}, error: ${String(featureError)}`;
12
+ let message = messageConfig.message;
13
+ const expectedParams = messageConfig.params?.length
14
+ ? messageConfig.params
15
+ : [];
16
+ if (!message) {
17
+ throw new Error(`Validation error message is not defined properly in configuration ${errorSuffix}`);
18
+ }
19
+ if (params && !expectedParams.length) {
20
+ throw new Error(`Validation error params are not defined properly in configuration ${errorSuffix}`);
21
+ }
22
+ expectedParams.forEach((param) => {
23
+ if (!(param in inputParams)) {
24
+ const missingParamMessage = `Missing parameter: ${param} ${errorSuffix}`;
25
+ throw new Error(missingParamMessage);
26
+ }
27
+ });
28
+ const matchingParamsInsideCurlyBraces = /\{([^}]+)\}/g;
29
+ let match;
30
+ while ((match = matchingParamsInsideCurlyBraces.exec(message)) !== null) {
31
+ const potentialParam = match[1];
32
+ if (expectedParams.length && !expectedParams.includes(potentialParam)) {
33
+ const typoMessage = `Potential typo in parameter name: {${potentialParam}} in message ${errorSuffix}. Expected parameters: ${expectedParams.join(', ')}`;
34
+ throw new Error(typoMessage);
35
+ }
36
+ }
37
+ expectedParams.forEach((param) => {
38
+ message = message.replace(`{${param}}`, inputParams[param]);
39
+ });
40
+ return message;
41
+ };
42
+ exports.getValidationMessage = getValidationMessage;
@@ -0,0 +1,306 @@
1
+ export declare const VALIDATION_MESSAGES: {
2
+ readonly DATA_FILTER: {
3
+ readonly MISSING_PAGE_SIZE: {
4
+ readonly message: "Request is invalid, 'pageSize' must exist if 'pageNumber' exists";
5
+ };
6
+ readonly MISSING_PAGE_NUMBER: {
7
+ readonly message: "Request is invalid, 'pageNumber' must exist if 'pageSize' exists";
8
+ };
9
+ readonly MISSING_SORT_BY: {
10
+ readonly message: "Request is invalid, 'sortBy' must exist if 'sortType' exists";
11
+ };
12
+ readonly MISSING_SORT_TYPE: {
13
+ readonly message: "Request is invalid, 'sortType' must exist if 'sortBy' exists";
14
+ };
15
+ };
16
+ readonly ACCOUNT_CATEGORY: {
17
+ readonly INVALID_REQUEST: {
18
+ readonly message: "Missing account category id in request";
19
+ };
20
+ readonly ID_DOES_NOT_EXIST: {
21
+ readonly message: "Account category with id '{id}' does not exist";
22
+ readonly params: readonly ["id"];
23
+ };
24
+ readonly NAME_ALREADY_EXISTS: {
25
+ readonly message: "Account category with the same name '{name}' already exists";
26
+ readonly params: readonly ["name"];
27
+ };
28
+ readonly OPTION_IN_USE: {
29
+ readonly message: "This option is currently in use and cannot be deleted.";
30
+ };
31
+ };
32
+ readonly ACCOUNT_ID: {
33
+ readonly INVALID_REQUEST: {
34
+ readonly message: "Missing account id identifier in request";
35
+ };
36
+ readonly ID_DOES_NOT_EXIST: {
37
+ readonly message: "Account id with id '{id}' does not exist";
38
+ readonly params: readonly ["id"];
39
+ };
40
+ readonly NAME_ALREADY_EXISTS: {
41
+ readonly message: "Account id with the same name '{name}' already exists";
42
+ readonly params: readonly ["name"];
43
+ };
44
+ readonly ACCOUNT_CATEGORY_ID_DOES_NOT_EXIST: {
45
+ readonly message: "Account category with id '{id}' does not exist";
46
+ readonly params: readonly ["id"];
47
+ };
48
+ readonly OPTION_IN_USE: {
49
+ readonly message: "This option is currently in use and cannot be deleted.";
50
+ };
51
+ };
52
+ readonly BUSINESS_ACTIVITY: {
53
+ readonly INVALID_REQUEST: {
54
+ readonly message: "Missing business activity id in request";
55
+ };
56
+ readonly ID_DOES_NOT_EXIST: {
57
+ readonly message: "Business activity with id '{id}' does not exist";
58
+ readonly params: readonly ["id"];
59
+ };
60
+ readonly NAME_ALREADY_EXISTS: {
61
+ readonly message: "Business activity with the same name '{name}' already exists";
62
+ readonly params: readonly ["name"];
63
+ };
64
+ readonly OPTION_IN_USE: {
65
+ readonly message: "This option is currently in use and cannot be deleted.";
66
+ };
67
+ };
68
+ readonly CLIENT: {
69
+ readonly INVALID_REQUEST: {
70
+ readonly message: "Missing client id in request";
71
+ };
72
+ readonly ID_DOES_NOT_EXIST: {
73
+ readonly message: "Client with id '{id}' does not exist";
74
+ readonly params: readonly ["id"];
75
+ };
76
+ readonly ACCOUNT_ID_DOES_NOT_EXIST: {
77
+ readonly message: "Account id with id '{id}' does not exist";
78
+ readonly params: readonly ["id"];
79
+ };
80
+ readonly FILING_CATEGORY_ID_DOES_NOT_EXIST: {
81
+ readonly message: "Filing category with id '{id}' does not exist";
82
+ readonly params: readonly ["id"];
83
+ };
84
+ readonly FILING_TYPE_ID_DOES_NOT_EXIST: {
85
+ readonly message: "Filing type with id '{id}' does not exist";
86
+ readonly params: readonly ["id"];
87
+ };
88
+ readonly STATE_ID_DOES_NOT_EXIST: {
89
+ readonly message: "State with id '{id}' does not exist";
90
+ readonly params: readonly ["id"];
91
+ };
92
+ readonly BUSINESS_ACTIVITY_ID_DOES_NOT_EXIST: {
93
+ readonly message: "Business activity with id '{id}' does not exist";
94
+ readonly params: readonly ["id"];
95
+ };
96
+ readonly BILLING_TYPE_ID_DOES_NOT_EXIST: {
97
+ readonly message: "Billing type with id '{id}' does not exist";
98
+ readonly params: readonly ["id"];
99
+ };
100
+ readonly ENTITY_TYPE_ID_DOES_NOT_EXIST: {
101
+ readonly message: "Entity type with id '{id}' does not exist";
102
+ readonly params: readonly ["id"];
103
+ };
104
+ readonly CLIENT_WITH_SAME_FEDERAL_LEGAL_ID_EXISTS: {
105
+ readonly message: "This ID is already in use. Please enter a different ID.";
106
+ };
107
+ readonly INVALID_CLIENT_ACTIVITY_STATUS: {
108
+ readonly message: "The 'Is active' field only applies to our clients. Please update the client type to 'Not our client' or update the 'Is active' status to 'Active'.";
109
+ };
110
+ readonly INVALID_FEDERAL_LEGAL_ID: {
111
+ readonly message: "Enter a valid {legalIdType} (e.g. {legalIdValue})";
112
+ readonly params: readonly ["legalIdType", "legalIdValue"];
113
+ };
114
+ readonly NAME_ALREADY_EXISTS: {
115
+ readonly message: "Client with the same name '{name}' already exists";
116
+ readonly params: readonly ["name"];
117
+ };
118
+ readonly NOT_ALIGNED_DATE_ESTABLISHED_ENTITY_TYPE_STARTING_DATE: {
119
+ readonly message: "One or more entity types have a start date that is before the client's date established, {clientDateEstablished}. ({entityType} starting {entityTypeStartingDate}). Please update the entity type start dates to be on or after the client's date established, or update the client's date established.";
120
+ readonly params: readonly ["clientDateEstablished", "entityType", "entityTypeStartingDate"];
121
+ };
122
+ readonly NOT_ALIGNED_DATE_ESTABLISHED_FILING_TYPE_STARTING_DATE: {
123
+ readonly message: "The filing type status {filingType} starts on {filingTypeStartingDate} which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the filing type status or the client's date established.";
124
+ readonly params: readonly ["clientDateEstablished", "filingType", "filingTypeStartingDate"];
125
+ };
126
+ readonly NOT_ALIGNED_DATE_ESTABLISHED_DOMESTIC_STATE_STARTING_DATE: {
127
+ readonly message: "The state, {domesticState}, starts on {domesticStateStartingDate}, which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the state or the client's date established.";
128
+ readonly params: readonly ["clientDateEstablished", "domesticState", "domesticStateStartingDate"];
129
+ };
130
+ readonly NOT_ALIGNED_DATE_ESTABLISHED_CLOSE_DATE: {
131
+ readonly message: "Adjust the close date to be after the date established.";
132
+ };
133
+ readonly NOT_ALIGNED_CLOSE_DATE_ENTITY_TYPE_STARTING_DATE: {
134
+ readonly message: "One or more entity types have start dates that are after the client's close date, {clientCloseDate}. {entityType} starting {entityTypeStartingDate}. Please update the entity type/s end date/s to be on or before the client's close date, or update the client's close date.";
135
+ readonly params: readonly ["clientCloseDate", "entityType", "entityTypeStartingDate"];
136
+ };
137
+ readonly NOT_ALIGNED_CLOSE_DATE_FILING_TYPE_STARTING_DATE: {
138
+ readonly message: "One or more filing type statuses have a start date which is after the client’s close date of {clientCloseDate}. {filingType}, starting {filingTypeStartingDate}. Please update the start date to be earlier than the client’s close date, or update the client's close date.";
139
+ readonly params: readonly ["clientCloseDate", "filingType", "filingTypeStartingDate"];
140
+ };
141
+ readonly NOT_ALIGNED_CLOSE_DATE_DOMEASTIC_STATE_STARTING_DATE: {
142
+ readonly message: "One or more states have a start date which is after the client's close date of {clientCloseDate}. {domesticState} starting {domesticStateStartingDate}. Please update the state/s start date/s to be before the client's close date, or update the client's close date.";
143
+ readonly params: readonly ["clientCloseDate", "domesticState", "domesticStateStartingDate"];
144
+ };
145
+ readonly ENTITY_TYPE_STARTING_DATE_NOT_POPULATED: {
146
+ readonly message: "Current Entity Type Starting Date cannot be Empty";
147
+ };
148
+ readonly FILING_TYPE_STARTING_DATE_NOT_POPULATED: {
149
+ readonly message: "Current Filing Type Starting Date cannot be Empty";
150
+ };
151
+ readonly DOMESTIC_STATE_STARTING_DATE_NOT_POPULATED: {
152
+ readonly message: "Current Domestic State Starting Date cannot be Empty";
153
+ };
154
+ readonly NOT_ALIGNED_ENTITY_TYPE_STARTING_ENDING_DATE: {
155
+ readonly message: "Entity type starting date needs to be before the ending date";
156
+ };
157
+ readonly NOT_ALIGNED_FILING_TYPE_STARTING_ENDING_DATE: {
158
+ readonly message: "Filing type starting date needs to be before the ending date";
159
+ };
160
+ readonly NOT_ALIGNED_DOMESTIC_STATE_STARTING_ENDING_DATE: {
161
+ readonly message: "Domestic state starting date needs to be before the ending date";
162
+ };
163
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ACCOUNT_ID: {
164
+ readonly message: "Choose an Account ID";
165
+ };
166
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BUSINESS_ACTIVITY_ID: {
167
+ readonly message: "Choose a Business Activity";
168
+ };
169
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BILLING_TYPE_ID: {
170
+ readonly message: "Choose a Billing Type";
171
+ };
172
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_FILING_CATEGORY_ID: {
173
+ readonly message: "Choose a Filing Category";
174
+ };
175
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_CONTACT: {
176
+ readonly message: "Create a Contact - One contact needs to have been saved to this client";
177
+ };
178
+ readonly CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ADDRESS: {
179
+ readonly message: "Create an Address - One address needs to have been saved to this client";
180
+ };
181
+ readonly CLIENT_COULD_NOT_BE_DELETED_CLIENT_CIRCLE_EXIST: {
182
+ readonly message: "This client cannot be deleted because it has client circle associated";
183
+ };
184
+ readonly CLIENT_COULD_NOT_BE_DELETED_CLIENT_PROJECT_TEMPLATES_EXIST: {
185
+ readonly message: "This client cannot be deleted because it has client project templates associated";
186
+ };
187
+ readonly CLIENT_COULD_NOT_BE_DELETED_ADDITIONAL_INFORMATION_EXIST: {
188
+ readonly message: "This client cannot be deleted because it has additional information associated";
189
+ };
190
+ readonly CLIENT_COULD_NOT_BE_DELETED_BANK_ACCOUNTS_EXIST: {
191
+ readonly message: "This client cannot be deleted because it has bank accounts associated";
192
+ };
193
+ readonly CLIENT_COULD_NOT_BE_DELETED_WORKLOGS_EXIST: {
194
+ readonly message: "This client cannot be deleted because it has worklogs associated";
195
+ };
196
+ readonly CLIENT_COULD_NOT_BE_DELETED_INVOICES_EXIST: {
197
+ readonly message: "This client cannot be deleted because it has invoices associated";
198
+ };
199
+ readonly CLIENT_COULD_NOT_BE_DELETED_PAYMENTS_EXIST: {
200
+ readonly message: "This client cannot be deleted because it has payments associated";
201
+ };
202
+ readonly CLIENT_COULD_NOT_BE_DELETED_DOCUMENTS_EXIST: {
203
+ readonly message: "This client cannot be deleted because it has documents associated";
204
+ };
205
+ readonly CLIENT_COULD_NOT_BE_DELETED_JOURNALS_EXIST: {
206
+ readonly message: "This client cannot be deleted because it has journals associated";
207
+ };
208
+ readonly CLIENT_COULD_NOT_BE_DELETED_FUTURES_EXIST: {
209
+ readonly message: "This client cannot be deleted because it has futures associated";
210
+ };
211
+ readonly CLIENT_COULD_NOT_BE_DELETED_PROJECTS_EXIST: {
212
+ readonly message: "This client cannot be deleted because it has projects associated";
213
+ };
214
+ readonly CLIENT_COULD_NOT_BE_DELETED_TASKS_EXIST: {
215
+ readonly message: "This client cannot be deleted because it has tasks associated";
216
+ };
217
+ readonly CLIENT_COULD_NOT_BE_DELETED_ADDRESSES_EXIST: {
218
+ readonly message: "This client cannot be deleted because it has addresses associated";
219
+ };
220
+ readonly CLIENT_COULD_NOT_BE_DELETED_CONTACTS_EXIST: {
221
+ readonly message: "This client cannot be deleted because it has contacts associated";
222
+ };
223
+ };
224
+ readonly FILING_CATEGORY: {
225
+ readonly INVALID_REQUEST: {
226
+ readonly message: "Missing filing category id in request";
227
+ };
228
+ readonly ID_DOES_NOT_EXIST: {
229
+ readonly message: "Filing category with id '{id}' does not exist";
230
+ readonly params: readonly ["id"];
231
+ };
232
+ readonly NAME_ALREADY_EXISTS: {
233
+ readonly message: "Filing category with the same name '{name}' already exists";
234
+ readonly params: readonly ["name"];
235
+ };
236
+ readonly OPTION_IN_USE: {
237
+ readonly message: "This option is currently in use and cannot be deleted.";
238
+ };
239
+ };
240
+ readonly STATE: {
241
+ readonly INVALID_REQUEST: {
242
+ readonly message: "Missing state id in request";
243
+ };
244
+ readonly ID_DOES_NOT_EXIST: {
245
+ readonly message: "State with id '{id}' does not exist";
246
+ readonly params: readonly ["id"];
247
+ };
248
+ readonly NAME_ALREADY_EXISTS: {
249
+ readonly message: "State with the same name '{name}' already exists";
250
+ readonly params: readonly ["name"];
251
+ };
252
+ readonly STATE_TYPE_ID_DOES_NOT_EXIST: {
253
+ readonly message: "State type with id '{id}' does not exist";
254
+ readonly params: readonly ["id"];
255
+ };
256
+ readonly IS_PARENT_OF_OTHER_STATES: {
257
+ readonly message: "This option is currently in use and cannot be deleted.";
258
+ };
259
+ readonly PARENT_ID_DOES_NOT_EXIST: {
260
+ readonly message: "Parent state with id '{id}' does not exist";
261
+ readonly params: readonly ["id"];
262
+ };
263
+ readonly PARENT_STATE_TYPE_NOT_ALLOWED: {
264
+ readonly message: "Parent state '{parentName}' has type '{parentType}' which is not allowed parent type for state '{stateName}' with type '{stateType}'";
265
+ readonly params: readonly ["parentName", "parentType", "stateName", "stateType"];
266
+ };
267
+ readonly OPTION_IN_USE: {
268
+ readonly message: "This option is currently in use and cannot be deleted.";
269
+ };
270
+ };
271
+ readonly USER: {
272
+ readonly USERNAME_DOES_NOT_EXIST: {
273
+ readonly message: "User with username {username} does not exist.";
274
+ readonly params: readonly ["username"];
275
+ };
276
+ readonly INVALID_PASSWORD: {
277
+ readonly message: "User with username {username} password does not match.";
278
+ readonly params: readonly ["username"];
279
+ };
280
+ readonly INVALID_RESET_PASSWORD_TOKEN: {
281
+ readonly message: "Invalid or expired reset token.";
282
+ };
283
+ readonly RESET_PASSWORD_LINK_ALREADY_USED: {
284
+ readonly message: "Reset password link has already been used. Please request a new one.";
285
+ };
286
+ readonly RESET_PASSWORD_LINK_NOT_LATEST: {
287
+ readonly message: "Reset password link is no longer valid. Please use the most recent one.";
288
+ };
289
+ };
290
+ readonly USER_PREFERENCE: {
291
+ readonly FEATURE_DOES_NOT_EXIST: {
292
+ readonly message: "Feature with name {feature} does not exist";
293
+ readonly params: readonly ["feature"];
294
+ };
295
+ readonly INVALID_REQUEST: {
296
+ readonly message: "Request is invalid";
297
+ };
298
+ readonly PREFERENCE_DOES_NOT_BELONG_TO_USER: {
299
+ readonly message: "Preference does not belong to the user";
300
+ };
301
+ readonly INVALID_COLUMN_ORDER: {
302
+ readonly message: "Invalid columnOrder values";
303
+ };
304
+ };
305
+ };
306
+ //# sourceMappingURL=validation-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation-messages.d.ts","sourceRoot":"","sources":["../../src/validation/validation-messages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoTtB,CAAC"}
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALIDATION_MESSAGES = void 0;
4
+ exports.VALIDATION_MESSAGES = {
5
+ DATA_FILTER: {
6
+ MISSING_PAGE_SIZE: {
7
+ message: `Request is invalid, 'pageSize' must exist if 'pageNumber' exists`,
8
+ },
9
+ MISSING_PAGE_NUMBER: {
10
+ message: `Request is invalid, 'pageNumber' must exist if 'pageSize' exists`,
11
+ },
12
+ MISSING_SORT_BY: {
13
+ message: `Request is invalid, 'sortBy' must exist if 'sortType' exists`,
14
+ },
15
+ MISSING_SORT_TYPE: {
16
+ message: `Request is invalid, 'sortType' must exist if 'sortBy' exists`,
17
+ },
18
+ },
19
+ ACCOUNT_CATEGORY: {
20
+ INVALID_REQUEST: {
21
+ message: 'Missing account category id in request',
22
+ },
23
+ ID_DOES_NOT_EXIST: {
24
+ message: `Account category with id '{id}' does not exist`,
25
+ params: ['id'],
26
+ },
27
+ NAME_ALREADY_EXISTS: {
28
+ message: `Account category with the same name '{name}' already exists`,
29
+ params: ['name'],
30
+ },
31
+ OPTION_IN_USE: {
32
+ message: `This option is currently in use and cannot be deleted.`,
33
+ },
34
+ },
35
+ ACCOUNT_ID: {
36
+ INVALID_REQUEST: {
37
+ message: 'Missing account id identifier in request',
38
+ },
39
+ ID_DOES_NOT_EXIST: {
40
+ message: `Account id with id '{id}' does not exist`,
41
+ params: ['id'],
42
+ },
43
+ NAME_ALREADY_EXISTS: {
44
+ message: `Account id with the same name '{name}' already exists`,
45
+ params: ['name'],
46
+ },
47
+ ACCOUNT_CATEGORY_ID_DOES_NOT_EXIST: {
48
+ message: `Account category with id '{id}' does not exist`,
49
+ params: ['id'],
50
+ },
51
+ OPTION_IN_USE: {
52
+ message: `This option is currently in use and cannot be deleted.`,
53
+ },
54
+ },
55
+ BUSINESS_ACTIVITY: {
56
+ INVALID_REQUEST: {
57
+ message: 'Missing business activity id in request',
58
+ },
59
+ ID_DOES_NOT_EXIST: {
60
+ message: `Business activity with id '{id}' does not exist`,
61
+ params: ['id'],
62
+ },
63
+ NAME_ALREADY_EXISTS: {
64
+ message: `Business activity with the same name '{name}' already exists`,
65
+ params: ['name'],
66
+ },
67
+ OPTION_IN_USE: {
68
+ message: `This option is currently in use and cannot be deleted.`,
69
+ },
70
+ },
71
+ CLIENT: {
72
+ INVALID_REQUEST: {
73
+ message: 'Missing client id in request',
74
+ },
75
+ ID_DOES_NOT_EXIST: {
76
+ message: `Client with id '{id}' does not exist`,
77
+ params: ['id'],
78
+ },
79
+ ACCOUNT_ID_DOES_NOT_EXIST: {
80
+ message: `Account id with id '{id}' does not exist`,
81
+ params: ['id'],
82
+ },
83
+ FILING_CATEGORY_ID_DOES_NOT_EXIST: {
84
+ message: `Filing category with id '{id}' does not exist`,
85
+ params: ['id'],
86
+ },
87
+ FILING_TYPE_ID_DOES_NOT_EXIST: {
88
+ message: `Filing type with id '{id}' does not exist`,
89
+ params: ['id'],
90
+ },
91
+ STATE_ID_DOES_NOT_EXIST: {
92
+ message: `State with id '{id}' does not exist`,
93
+ params: ['id'],
94
+ },
95
+ BUSINESS_ACTIVITY_ID_DOES_NOT_EXIST: {
96
+ message: `Business activity with id '{id}' does not exist`,
97
+ params: ['id'],
98
+ },
99
+ BILLING_TYPE_ID_DOES_NOT_EXIST: {
100
+ message: `Billing type with id '{id}' does not exist`,
101
+ params: ['id'],
102
+ },
103
+ ENTITY_TYPE_ID_DOES_NOT_EXIST: {
104
+ message: `Entity type with id '{id}' does not exist`,
105
+ params: ['id'],
106
+ },
107
+ CLIENT_WITH_SAME_FEDERAL_LEGAL_ID_EXISTS: {
108
+ message: `This ID is already in use. Please enter a different ID.`,
109
+ },
110
+ INVALID_CLIENT_ACTIVITY_STATUS: {
111
+ message: `The 'Is active' field only applies to our clients. Please update the client type to 'Not our client' or update the 'Is active' status to 'Active'.`,
112
+ },
113
+ INVALID_FEDERAL_LEGAL_ID: {
114
+ message: `Enter a valid {legalIdType} (e.g. {legalIdValue})`,
115
+ params: ['legalIdType', 'legalIdValue'],
116
+ },
117
+ NAME_ALREADY_EXISTS: {
118
+ message: `Client with the same name '{name}' already exists`,
119
+ params: ['name'],
120
+ },
121
+ NOT_ALIGNED_DATE_ESTABLISHED_ENTITY_TYPE_STARTING_DATE: {
122
+ message: `One or more entity types have a start date that is before the client's date established, {clientDateEstablished}. ({entityType} starting {entityTypeStartingDate}). Please update the entity type start dates to be on or after the client's date established, or update the client's date established.`,
123
+ params: ['clientDateEstablished', 'entityType', 'entityTypeStartingDate'],
124
+ },
125
+ NOT_ALIGNED_DATE_ESTABLISHED_FILING_TYPE_STARTING_DATE: {
126
+ message: `The filing type status {filingType} starts on {filingTypeStartingDate} which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the filing type status or the client's date established.`,
127
+ params: ['clientDateEstablished', 'filingType', 'filingTypeStartingDate'],
128
+ },
129
+ NOT_ALIGNED_DATE_ESTABLISHED_DOMESTIC_STATE_STARTING_DATE: {
130
+ message: `The state, {domesticState}, starts on {domesticStateStartingDate}, which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the state or the client's date established.`,
131
+ params: [
132
+ 'clientDateEstablished',
133
+ 'domesticState',
134
+ 'domesticStateStartingDate',
135
+ ],
136
+ },
137
+ NOT_ALIGNED_DATE_ESTABLISHED_CLOSE_DATE: {
138
+ message: `Adjust the close date to be after the date established.`,
139
+ },
140
+ NOT_ALIGNED_CLOSE_DATE_ENTITY_TYPE_STARTING_DATE: {
141
+ message: `One or more entity types have start dates that are after the client's close date, {clientCloseDate}. {entityType} starting {entityTypeStartingDate}. Please update the entity type/s end date/s to be on or before the client's close date, or update the client's close date.`,
142
+ params: ['clientCloseDate', 'entityType', 'entityTypeStartingDate'],
143
+ },
144
+ NOT_ALIGNED_CLOSE_DATE_FILING_TYPE_STARTING_DATE: {
145
+ message: `One or more filing type statuses have a start date which is after the client’s close date of {clientCloseDate}. {filingType}, starting {filingTypeStartingDate}. Please update the start date to be earlier than the client’s close date, or update the client's close date.`,
146
+ params: ['clientCloseDate', 'filingType', 'filingTypeStartingDate'],
147
+ },
148
+ NOT_ALIGNED_CLOSE_DATE_DOMEASTIC_STATE_STARTING_DATE: {
149
+ message: `One or more states have a start date which is after the client's close date of {clientCloseDate}. {domesticState} starting {domesticStateStartingDate}. Please update the state/s start date/s to be before the client's close date, or update the client's close date.`,
150
+ params: ['clientCloseDate', 'domesticState', 'domesticStateStartingDate'],
151
+ },
152
+ ENTITY_TYPE_STARTING_DATE_NOT_POPULATED: {
153
+ message: `Current Entity Type Starting Date cannot be Empty`,
154
+ },
155
+ FILING_TYPE_STARTING_DATE_NOT_POPULATED: {
156
+ message: `Current Filing Type Starting Date cannot be Empty`,
157
+ },
158
+ DOMESTIC_STATE_STARTING_DATE_NOT_POPULATED: {
159
+ message: `Current Domestic State Starting Date cannot be Empty`,
160
+ },
161
+ NOT_ALIGNED_ENTITY_TYPE_STARTING_ENDING_DATE: {
162
+ message: `Entity type starting date needs to be before the ending date`,
163
+ },
164
+ NOT_ALIGNED_FILING_TYPE_STARTING_ENDING_DATE: {
165
+ message: `Filing type starting date needs to be before the ending date`,
166
+ },
167
+ NOT_ALIGNED_DOMESTIC_STATE_STARTING_ENDING_DATE: {
168
+ message: `Domestic state starting date needs to be before the ending date`,
169
+ },
170
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ACCOUNT_ID: {
171
+ message: `Choose an Account ID`,
172
+ },
173
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BUSINESS_ACTIVITY_ID: {
174
+ message: `Choose a Business Activity`,
175
+ },
176
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BILLING_TYPE_ID: {
177
+ message: `Choose a Billing Type`,
178
+ },
179
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_FILING_CATEGORY_ID: {
180
+ message: `Choose a Filing Category`,
181
+ },
182
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_CONTACT: {
183
+ message: `Create a Contact - One contact needs to have been saved to this client`,
184
+ },
185
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ADDRESS: {
186
+ message: `Create an Address - One address needs to have been saved to this client`,
187
+ },
188
+ CLIENT_COULD_NOT_BE_DELETED_CLIENT_CIRCLE_EXIST: {
189
+ message: `This client cannot be deleted because it has client circle associated`,
190
+ },
191
+ CLIENT_COULD_NOT_BE_DELETED_CLIENT_PROJECT_TEMPLATES_EXIST: {
192
+ message: `This client cannot be deleted because it has client project templates associated`,
193
+ },
194
+ CLIENT_COULD_NOT_BE_DELETED_ADDITIONAL_INFORMATION_EXIST: {
195
+ message: `This client cannot be deleted because it has additional information associated`,
196
+ },
197
+ CLIENT_COULD_NOT_BE_DELETED_BANK_ACCOUNTS_EXIST: {
198
+ message: `This client cannot be deleted because it has bank accounts associated`,
199
+ },
200
+ CLIENT_COULD_NOT_BE_DELETED_WORKLOGS_EXIST: {
201
+ message: `This client cannot be deleted because it has worklogs associated`,
202
+ },
203
+ CLIENT_COULD_NOT_BE_DELETED_INVOICES_EXIST: {
204
+ message: `This client cannot be deleted because it has invoices associated`,
205
+ },
206
+ CLIENT_COULD_NOT_BE_DELETED_PAYMENTS_EXIST: {
207
+ message: `This client cannot be deleted because it has payments associated`,
208
+ },
209
+ CLIENT_COULD_NOT_BE_DELETED_DOCUMENTS_EXIST: {
210
+ message: `This client cannot be deleted because it has documents associated`,
211
+ },
212
+ CLIENT_COULD_NOT_BE_DELETED_JOURNALS_EXIST: {
213
+ message: `This client cannot be deleted because it has journals associated`,
214
+ },
215
+ CLIENT_COULD_NOT_BE_DELETED_FUTURES_EXIST: {
216
+ message: `This client cannot be deleted because it has futures associated`,
217
+ },
218
+ CLIENT_COULD_NOT_BE_DELETED_PROJECTS_EXIST: {
219
+ message: `This client cannot be deleted because it has projects associated`,
220
+ },
221
+ CLIENT_COULD_NOT_BE_DELETED_TASKS_EXIST: {
222
+ message: `This client cannot be deleted because it has tasks associated`,
223
+ },
224
+ CLIENT_COULD_NOT_BE_DELETED_ADDRESSES_EXIST: {
225
+ message: `This client cannot be deleted because it has addresses associated`,
226
+ },
227
+ CLIENT_COULD_NOT_BE_DELETED_CONTACTS_EXIST: {
228
+ message: `This client cannot be deleted because it has contacts associated`,
229
+ },
230
+ },
231
+ FILING_CATEGORY: {
232
+ INVALID_REQUEST: {
233
+ message: 'Missing filing category id in request',
234
+ },
235
+ ID_DOES_NOT_EXIST: {
236
+ message: `Filing category with id '{id}' does not exist`,
237
+ params: ['id'],
238
+ },
239
+ NAME_ALREADY_EXISTS: {
240
+ message: `Filing category with the same name '{name}' already exists`,
241
+ params: ['name'],
242
+ },
243
+ OPTION_IN_USE: {
244
+ message: `This option is currently in use and cannot be deleted.`,
245
+ },
246
+ },
247
+ STATE: {
248
+ INVALID_REQUEST: {
249
+ message: 'Missing state id in request',
250
+ },
251
+ ID_DOES_NOT_EXIST: {
252
+ message: `State with id '{id}' does not exist`,
253
+ params: ['id'],
254
+ },
255
+ NAME_ALREADY_EXISTS: {
256
+ message: `State with the same name '{name}' already exists`,
257
+ params: ['name'],
258
+ },
259
+ STATE_TYPE_ID_DOES_NOT_EXIST: {
260
+ message: `State type with id '{id}' does not exist`,
261
+ params: ['id'],
262
+ },
263
+ IS_PARENT_OF_OTHER_STATES: {
264
+ message: `This option is currently in use and cannot be deleted.`,
265
+ },
266
+ PARENT_ID_DOES_NOT_EXIST: {
267
+ message: `Parent state with id '{id}' does not exist`,
268
+ params: ['id'],
269
+ },
270
+ PARENT_STATE_TYPE_NOT_ALLOWED: {
271
+ message: `Parent state '{parentName}' has type '{parentType}' which is not allowed parent type for state '{stateName}' with type '{stateType}'`,
272
+ params: ['parentName', 'parentType', 'stateName', 'stateType'],
273
+ },
274
+ OPTION_IN_USE: {
275
+ message: `This option is currently in use and cannot be deleted.`,
276
+ },
277
+ },
278
+ USER: {
279
+ USERNAME_DOES_NOT_EXIST: {
280
+ message: `User with username {username} does not exist.`,
281
+ params: ['username'],
282
+ },
283
+ INVALID_PASSWORD: {
284
+ message: `User with username {username} password does not match.`,
285
+ params: ['username'],
286
+ },
287
+ INVALID_RESET_PASSWORD_TOKEN: {
288
+ message: `Invalid or expired reset token.`,
289
+ },
290
+ RESET_PASSWORD_LINK_ALREADY_USED: {
291
+ message: `Reset password link has already been used. Please request a new one.`,
292
+ },
293
+ RESET_PASSWORD_LINK_NOT_LATEST: {
294
+ message: `Reset password link is no longer valid. Please use the most recent one.`,
295
+ },
296
+ },
297
+ USER_PREFERENCE: {
298
+ FEATURE_DOES_NOT_EXIST: {
299
+ message: `Feature with name {feature} does not exist`,
300
+ params: ['feature'],
301
+ },
302
+ INVALID_REQUEST: {
303
+ message: 'Request is invalid',
304
+ },
305
+ PREFERENCE_DOES_NOT_BELONG_TO_USER: {
306
+ message: 'Preference does not belong to the user',
307
+ },
308
+ INVALID_COLUMN_ORDER: {
309
+ message: 'Invalid columnOrder values',
310
+ },
311
+ },
312
+ };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@forwardslashns/taskit-validation-messages",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "type": "commonjs",
7
+ "scripts": {
8
+ "build": "rimraf ./dist && tsc",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "engines": {
12
+ "node": ">=22.0.0"
13
+ },
14
+ "author": "forwardslash",
15
+ "license": "ISC",
16
+ "description": "Validation messages for Taskit and mechanism for reading these messages dynamically.",
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^22.9.1",
22
+ "rimraf": "^6.0.1",
23
+ "typescript": "^5.8.2"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/fws-solutions/taskit-validation-messages.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/fws-solutions/taskit-validation-messages/issues"
31
+ },
32
+ "homepage": "https://github.com/fws-solutions/taskit-validation-messages#readme"
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { getValidationMessage } from "./validation/validation-message.formatter";
2
+ import { VALIDATION_MESSAGES } from "./validation/validation-messages";
3
+
4
+ export { VALIDATION_MESSAGES, getValidationMessage };
@@ -0,0 +1,81 @@
1
+ import { VALIDATION_MESSAGES } from './validation-messages';
2
+
3
+ type Features = keyof typeof VALIDATION_MESSAGES;
4
+ type ErrorType<F extends Features> = keyof (typeof VALIDATION_MESSAGES)[F];
5
+ type ErrorMessageParams<
6
+ F extends Features,
7
+ E extends ErrorType<F>,
8
+ > = (typeof VALIDATION_MESSAGES)[F][E] extends {
9
+ params: infer P extends readonly string[];
10
+ }
11
+ ? P
12
+ : [];
13
+ type MessageParams<T extends readonly string[]> = { [K in T[number]]: string };
14
+ type MessageConfig = {
15
+ message: string;
16
+ params?: readonly string[];
17
+ };
18
+
19
+ export const getValidationMessage = <
20
+ FeatureType extends Features,
21
+ FeatureErrorType extends ErrorType<FeatureType>,
22
+ >(
23
+ feature: FeatureType,
24
+ featureError: FeatureErrorType,
25
+ params?: MessageParams<ErrorMessageParams<FeatureType, FeatureErrorType>>
26
+ ): string => {
27
+ const messageConfig = VALIDATION_MESSAGES[feature][
28
+ featureError
29
+ ] as MessageConfig;
30
+
31
+ if (!messageConfig) {
32
+ throw new Error(
33
+ `Validation error message is not defined properly in configuration for feature: '${String(feature)}', error: '${String(featureError)}')`
34
+ );
35
+ }
36
+
37
+ const inputParams = params || {};
38
+ const errorSuffix = `for feature: ${String(feature)}, error: ${String(featureError)}`;
39
+ let message = messageConfig.message;
40
+ const expectedParams = messageConfig.params?.length
41
+ ? messageConfig.params
42
+ : [];
43
+
44
+ if (!message) {
45
+ throw new Error(
46
+ `Validation error message is not defined properly in configuration ${errorSuffix}`
47
+ );
48
+ }
49
+
50
+ if (params && !expectedParams.length) {
51
+ throw new Error(
52
+ `Validation error params are not defined properly in configuration ${errorSuffix}`
53
+ );
54
+ }
55
+
56
+ expectedParams.forEach((param) => {
57
+ if (!(param in inputParams)) {
58
+ const missingParamMessage = `Missing parameter: ${param} ${errorSuffix}`;
59
+ throw new Error(missingParamMessage);
60
+ }
61
+ });
62
+
63
+ const matchingParamsInsideCurlyBraces = /\{([^}]+)\}/g;
64
+ let match;
65
+ while ((match = matchingParamsInsideCurlyBraces.exec(message)) !== null) {
66
+ const potentialParam = match[1];
67
+ if (expectedParams.length && !expectedParams.includes(potentialParam)) {
68
+ const typoMessage = `Potential typo in parameter name: {${potentialParam}} in message ${errorSuffix}. Expected parameters: ${expectedParams.join(', ')}`;
69
+ throw new Error(typoMessage);
70
+ }
71
+ }
72
+
73
+ expectedParams.forEach((param) => {
74
+ message = message.replace(
75
+ `{${param}}`,
76
+ (inputParams as Record<string, string>)[param]
77
+ );
78
+ });
79
+
80
+ return message;
81
+ };
@@ -0,0 +1,309 @@
1
+ export const VALIDATION_MESSAGES = {
2
+ DATA_FILTER: {
3
+ MISSING_PAGE_SIZE: {
4
+ message: `Request is invalid, 'pageSize' must exist if 'pageNumber' exists`,
5
+ },
6
+ MISSING_PAGE_NUMBER: {
7
+ message: `Request is invalid, 'pageNumber' must exist if 'pageSize' exists`,
8
+ },
9
+ MISSING_SORT_BY: {
10
+ message: `Request is invalid, 'sortBy' must exist if 'sortType' exists`,
11
+ },
12
+ MISSING_SORT_TYPE: {
13
+ message: `Request is invalid, 'sortType' must exist if 'sortBy' exists`,
14
+ },
15
+ },
16
+ ACCOUNT_CATEGORY: {
17
+ INVALID_REQUEST: {
18
+ message: 'Missing account category id in request',
19
+ },
20
+ ID_DOES_NOT_EXIST: {
21
+ message: `Account category with id '{id}' does not exist`,
22
+ params: ['id'],
23
+ },
24
+ NAME_ALREADY_EXISTS: {
25
+ message: `Account category with the same name '{name}' already exists`,
26
+ params: ['name'],
27
+ },
28
+ OPTION_IN_USE: {
29
+ message: `This option is currently in use and cannot be deleted.`,
30
+ },
31
+ },
32
+ ACCOUNT_ID: {
33
+ INVALID_REQUEST: {
34
+ message: 'Missing account id identifier in request',
35
+ },
36
+ ID_DOES_NOT_EXIST: {
37
+ message: `Account id with id '{id}' does not exist`,
38
+ params: ['id'],
39
+ },
40
+ NAME_ALREADY_EXISTS: {
41
+ message: `Account id with the same name '{name}' already exists`,
42
+ params: ['name'],
43
+ },
44
+ ACCOUNT_CATEGORY_ID_DOES_NOT_EXIST: {
45
+ message: `Account category with id '{id}' does not exist`,
46
+ params: ['id'],
47
+ },
48
+ OPTION_IN_USE: {
49
+ message: `This option is currently in use and cannot be deleted.`,
50
+ },
51
+ },
52
+ BUSINESS_ACTIVITY: {
53
+ INVALID_REQUEST: {
54
+ message: 'Missing business activity id in request',
55
+ },
56
+ ID_DOES_NOT_EXIST: {
57
+ message: `Business activity with id '{id}' does not exist`,
58
+ params: ['id'],
59
+ },
60
+ NAME_ALREADY_EXISTS: {
61
+ message: `Business activity with the same name '{name}' already exists`,
62
+ params: ['name'],
63
+ },
64
+ OPTION_IN_USE: {
65
+ message: `This option is currently in use and cannot be deleted.`,
66
+ },
67
+ },
68
+ CLIENT: {
69
+ INVALID_REQUEST: {
70
+ message: 'Missing client id in request',
71
+ },
72
+ ID_DOES_NOT_EXIST: {
73
+ message: `Client with id '{id}' does not exist`,
74
+ params: ['id'],
75
+ },
76
+ ACCOUNT_ID_DOES_NOT_EXIST: {
77
+ message: `Account id with id '{id}' does not exist`,
78
+ params: ['id'],
79
+ },
80
+ FILING_CATEGORY_ID_DOES_NOT_EXIST: {
81
+ message: `Filing category with id '{id}' does not exist`,
82
+ params: ['id'],
83
+ },
84
+ FILING_TYPE_ID_DOES_NOT_EXIST: {
85
+ message: `Filing type with id '{id}' does not exist`,
86
+ params: ['id'],
87
+ },
88
+ STATE_ID_DOES_NOT_EXIST: {
89
+ message: `State with id '{id}' does not exist`,
90
+ params: ['id'],
91
+ },
92
+ BUSINESS_ACTIVITY_ID_DOES_NOT_EXIST: {
93
+ message: `Business activity with id '{id}' does not exist`,
94
+ params: ['id'],
95
+ },
96
+ BILLING_TYPE_ID_DOES_NOT_EXIST: {
97
+ message: `Billing type with id '{id}' does not exist`,
98
+ params: ['id'],
99
+ },
100
+ ENTITY_TYPE_ID_DOES_NOT_EXIST: {
101
+ message: `Entity type with id '{id}' does not exist`,
102
+ params: ['id'],
103
+ },
104
+ CLIENT_WITH_SAME_FEDERAL_LEGAL_ID_EXISTS: {
105
+ message: `This ID is already in use. Please enter a different ID.`,
106
+ },
107
+ INVALID_CLIENT_ACTIVITY_STATUS: {
108
+ message: `The 'Is active' field only applies to our clients. Please update the client type to 'Not our client' or update the 'Is active' status to 'Active'.`,
109
+ },
110
+ INVALID_FEDERAL_LEGAL_ID: {
111
+ message: `Enter a valid {legalIdType} (e.g. {legalIdValue})`,
112
+ params: ['legalIdType', 'legalIdValue'],
113
+ },
114
+ NAME_ALREADY_EXISTS: {
115
+ message: `Client with the same name '{name}' already exists`,
116
+ params: ['name'],
117
+ },
118
+ NOT_ALIGNED_DATE_ESTABLISHED_ENTITY_TYPE_STARTING_DATE: {
119
+ message: `One or more entity types have a start date that is before the client's date established, {clientDateEstablished}. ({entityType} starting {entityTypeStartingDate}). Please update the entity type start dates to be on or after the client's date established, or update the client's date established.`,
120
+ params: ['clientDateEstablished', 'entityType', 'entityTypeStartingDate'],
121
+ },
122
+ NOT_ALIGNED_DATE_ESTABLISHED_FILING_TYPE_STARTING_DATE: {
123
+ message: `The filing type status {filingType} starts on {filingTypeStartingDate} which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the filing type status or the client's date established.`,
124
+ params: ['clientDateEstablished', 'filingType', 'filingTypeStartingDate'],
125
+ },
126
+ NOT_ALIGNED_DATE_ESTABLISHED_DOMESTIC_STATE_STARTING_DATE: {
127
+ message: `The state, {domesticState}, starts on {domesticStateStartingDate}, which is earlier than the client's date established, {clientDateEstablished}. Please adjust the start date of the state or the client's date established.`,
128
+ params: [
129
+ 'clientDateEstablished',
130
+ 'domesticState',
131
+ 'domesticStateStartingDate',
132
+ ],
133
+ },
134
+ NOT_ALIGNED_DATE_ESTABLISHED_CLOSE_DATE: {
135
+ message: `Adjust the close date to be after the date established.`,
136
+ },
137
+ NOT_ALIGNED_CLOSE_DATE_ENTITY_TYPE_STARTING_DATE: {
138
+ message: `One or more entity types have start dates that are after the client's close date, {clientCloseDate}. {entityType} starting {entityTypeStartingDate}. Please update the entity type/s end date/s to be on or before the client's close date, or update the client's close date.`,
139
+ params: ['clientCloseDate', 'entityType', 'entityTypeStartingDate'],
140
+ },
141
+ NOT_ALIGNED_CLOSE_DATE_FILING_TYPE_STARTING_DATE: {
142
+ message: `One or more filing type statuses have a start date which is after the client’s close date of {clientCloseDate}. {filingType}, starting {filingTypeStartingDate}. Please update the start date to be earlier than the client’s close date, or update the client's close date.`,
143
+ params: ['clientCloseDate', 'filingType', 'filingTypeStartingDate'],
144
+ },
145
+ NOT_ALIGNED_CLOSE_DATE_DOMEASTIC_STATE_STARTING_DATE: {
146
+ message: `One or more states have a start date which is after the client's close date of {clientCloseDate}. {domesticState} starting {domesticStateStartingDate}. Please update the state/s start date/s to be before the client's close date, or update the client's close date.`,
147
+ params: ['clientCloseDate', 'domesticState', 'domesticStateStartingDate'],
148
+ },
149
+ ENTITY_TYPE_STARTING_DATE_NOT_POPULATED: {
150
+ message: `Current Entity Type Starting Date cannot be Empty`,
151
+ },
152
+ FILING_TYPE_STARTING_DATE_NOT_POPULATED: {
153
+ message: `Current Filing Type Starting Date cannot be Empty`,
154
+ },
155
+ DOMESTIC_STATE_STARTING_DATE_NOT_POPULATED: {
156
+ message: `Current Domestic State Starting Date cannot be Empty`,
157
+ },
158
+ NOT_ALIGNED_ENTITY_TYPE_STARTING_ENDING_DATE: {
159
+ message: `Entity type starting date needs to be before the ending date`,
160
+ },
161
+ NOT_ALIGNED_FILING_TYPE_STARTING_ENDING_DATE: {
162
+ message: `Filing type starting date needs to be before the ending date`,
163
+ },
164
+ NOT_ALIGNED_DOMESTIC_STATE_STARTING_ENDING_DATE: {
165
+ message: `Domestic state starting date needs to be before the ending date`,
166
+ },
167
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ACCOUNT_ID: {
168
+ message: `Choose an Account ID`,
169
+ },
170
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BUSINESS_ACTIVITY_ID: {
171
+ message: `Choose a Business Activity`,
172
+ },
173
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_BILLING_TYPE_ID: {
174
+ message: `Choose a Billing Type`,
175
+ },
176
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_FILING_CATEGORY_ID: {
177
+ message: `Choose a Filing Category`,
178
+ },
179
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_CONTACT: {
180
+ message: `Create a Contact - One contact needs to have been saved to this client`,
181
+ },
182
+ CLIENT_COULD_NOT_BE_LOCKED_WITHOUT_ADDRESS: {
183
+ message: `Create an Address - One address needs to have been saved to this client`,
184
+ },
185
+ CLIENT_COULD_NOT_BE_DELETED_CLIENT_CIRCLE_EXIST: {
186
+ message: `This client cannot be deleted because it has client circle associated`,
187
+ },
188
+ CLIENT_COULD_NOT_BE_DELETED_CLIENT_PROJECT_TEMPLATES_EXIST: {
189
+ message: `This client cannot be deleted because it has client project templates associated`,
190
+ },
191
+ CLIENT_COULD_NOT_BE_DELETED_ADDITIONAL_INFORMATION_EXIST: {
192
+ message: `This client cannot be deleted because it has additional information associated`,
193
+ },
194
+ CLIENT_COULD_NOT_BE_DELETED_BANK_ACCOUNTS_EXIST: {
195
+ message: `This client cannot be deleted because it has bank accounts associated`,
196
+ },
197
+ CLIENT_COULD_NOT_BE_DELETED_WORKLOGS_EXIST: {
198
+ message: `This client cannot be deleted because it has worklogs associated`,
199
+ },
200
+ CLIENT_COULD_NOT_BE_DELETED_INVOICES_EXIST: {
201
+ message: `This client cannot be deleted because it has invoices associated`,
202
+ },
203
+ CLIENT_COULD_NOT_BE_DELETED_PAYMENTS_EXIST: {
204
+ message: `This client cannot be deleted because it has payments associated`,
205
+ },
206
+ CLIENT_COULD_NOT_BE_DELETED_DOCUMENTS_EXIST: {
207
+ message: `This client cannot be deleted because it has documents associated`,
208
+ },
209
+ CLIENT_COULD_NOT_BE_DELETED_JOURNALS_EXIST: {
210
+ message: `This client cannot be deleted because it has journals associated`,
211
+ },
212
+ CLIENT_COULD_NOT_BE_DELETED_FUTURES_EXIST: {
213
+ message: `This client cannot be deleted because it has futures associated`,
214
+ },
215
+ CLIENT_COULD_NOT_BE_DELETED_PROJECTS_EXIST: {
216
+ message: `This client cannot be deleted because it has projects associated`,
217
+ },
218
+ CLIENT_COULD_NOT_BE_DELETED_TASKS_EXIST: {
219
+ message: `This client cannot be deleted because it has tasks associated`,
220
+ },
221
+ CLIENT_COULD_NOT_BE_DELETED_ADDRESSES_EXIST: {
222
+ message: `This client cannot be deleted because it has addresses associated`,
223
+ },
224
+ CLIENT_COULD_NOT_BE_DELETED_CONTACTS_EXIST: {
225
+ message: `This client cannot be deleted because it has contacts associated`,
226
+ },
227
+ },
228
+ FILING_CATEGORY: {
229
+ INVALID_REQUEST: {
230
+ message: 'Missing filing category id in request',
231
+ },
232
+ ID_DOES_NOT_EXIST: {
233
+ message: `Filing category with id '{id}' does not exist`,
234
+ params: ['id'],
235
+ },
236
+ NAME_ALREADY_EXISTS: {
237
+ message: `Filing category with the same name '{name}' already exists`,
238
+ params: ['name'],
239
+ },
240
+ OPTION_IN_USE: {
241
+ message: `This option is currently in use and cannot be deleted.`,
242
+ },
243
+ },
244
+ STATE: {
245
+ INVALID_REQUEST: {
246
+ message: 'Missing state id in request',
247
+ },
248
+ ID_DOES_NOT_EXIST: {
249
+ message: `State with id '{id}' does not exist`,
250
+ params: ['id'],
251
+ },
252
+ NAME_ALREADY_EXISTS: {
253
+ message: `State with the same name '{name}' already exists`,
254
+ params: ['name'],
255
+ },
256
+ STATE_TYPE_ID_DOES_NOT_EXIST: {
257
+ message: `State type with id '{id}' does not exist`,
258
+ params: ['id'],
259
+ },
260
+ IS_PARENT_OF_OTHER_STATES: {
261
+ message: `This option is currently in use and cannot be deleted.`,
262
+ },
263
+ PARENT_ID_DOES_NOT_EXIST: {
264
+ message: `Parent state with id '{id}' does not exist`,
265
+ params: ['id'],
266
+ },
267
+ PARENT_STATE_TYPE_NOT_ALLOWED: {
268
+ message: `Parent state '{parentName}' has type '{parentType}' which is not allowed parent type for state '{stateName}' with type '{stateType}'`,
269
+ params: ['parentName', 'parentType', 'stateName', 'stateType'],
270
+ },
271
+ OPTION_IN_USE: {
272
+ message: `This option is currently in use and cannot be deleted.`,
273
+ },
274
+ },
275
+ USER: {
276
+ USERNAME_DOES_NOT_EXIST: {
277
+ message: `User with username {username} does not exist.`,
278
+ params: ['username'],
279
+ },
280
+ INVALID_PASSWORD: {
281
+ message: `User with username {username} password does not match.`,
282
+ params: ['username'],
283
+ },
284
+ INVALID_RESET_PASSWORD_TOKEN: {
285
+ message: `Invalid or expired reset token.`,
286
+ },
287
+ RESET_PASSWORD_LINK_ALREADY_USED: {
288
+ message: `Reset password link has already been used. Please request a new one.`,
289
+ },
290
+ RESET_PASSWORD_LINK_NOT_LATEST: {
291
+ message: `Reset password link is no longer valid. Please use the most recent one.`,
292
+ },
293
+ },
294
+ USER_PREFERENCE: {
295
+ FEATURE_DOES_NOT_EXIST: {
296
+ message: `Feature with name {feature} does not exist`,
297
+ params: ['feature'],
298
+ },
299
+ INVALID_REQUEST: {
300
+ message: 'Request is invalid',
301
+ },
302
+ PREFERENCE_DOES_NOT_BELONG_TO_USER: {
303
+ message: 'Preference does not belong to the user',
304
+ },
305
+ INVALID_COLUMN_ORDER: {
306
+ message: 'Invalid columnOrder values',
307
+ },
308
+ },
309
+ } as const;
package/tsconfig.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "Node16",
5
+ "moduleResolution": "node16",
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "outDir": "./dist",
13
+ "rootDir": "./src"
14
+ },
15
+ "include": ["src/**/*", "types/**/*"],
16
+ "exclude": ["node_modules"]
17
+ }