@getcommunity/gc-validators 0.0.104 → 0.0.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # 🪨 GC Validators
2
+
3
+ ## Example Permission Constants Usage
4
+
5
+ ```ts
6
+ const userDoc: UserDocument = {
7
+ id: 1,
8
+ documentId: "1234asdfhjkl",
9
+ createdAt: "2024-01-01T00:00:00.000Z",
10
+ updatedAt: "2024-01-01T00:00:00.000Z",
11
+ publishedAt: "2024-01-01T00:00:00.000Z",
12
+ username: "tester",
13
+ email: "test@test.com",
14
+ provider: "local",
15
+ confirmed: true,
16
+ blocked: true,
17
+ clerk_user_id: ""
18
+ }
19
+ const user: AuthorizedUserDocument = {
20
+ ...userDoc,
21
+ role: {
22
+ id: 1,
23
+ documentId: "1234asdfhjkl",
24
+ createdAt: "2024-01-01T00:00:00.000Z",
25
+ updatedAt: "2024-01-01T00:00:00.000Z",
26
+ publishedAt: "2024-01-01T00:00:00.000Z",
27
+ type: "employee",
28
+ name: "Employee",
29
+ description: "Employee role with access to client data",
30
+ permissions: []
31
+ },
32
+ account: {
33
+ id: 1,
34
+ documentId: "1234asdfhjkl",
35
+ createdAt: "2024-01-01T00:00:00.000Z",
36
+ updatedAt: "2024-01-01T00:00:00.000Z",
37
+ publishedAt: "2024-01-01T00:00:00.000Z",
38
+ preferred_name: "Test Account",
39
+ first_name: "Test",
40
+ last_name: "User"
41
+ }
42
+ }
43
+ const client: ClientDocument = {
44
+ id: 1,
45
+ documentId: "1234asdfhjkl",
46
+ createdAt: "2024-01-01T00:00:00.000Z",
47
+ updatedAt: "2024-01-01T00:00:00.000Z",
48
+ publishedAt: "2024-01-01T00:00:00.000Z",
49
+ title: "Test Client",
50
+ teamwork_name: "Test Client",
51
+ teamwork_id: "123456",
52
+ is_featured: true,
53
+ utm_sheet_id: "asdkjhflawhfl",
54
+ allow_create_utm_link: true,
55
+ is_organic_social: true,
56
+ is_paid_media: true,
57
+ is_active: true,
58
+ classification: ["organic", "paid"]
59
+ }
60
+ const clientUserStatus: ClientUserDocumentStatus = {
61
+ verified: true,
62
+ clientUser: {
63
+ id: 1,
64
+ documentId: "1234asdfhjkl",
65
+ createdAt: "2024-01-01T00:00:00.000Z",
66
+ updatedAt: "2024-01-01T00:00:00.000Z",
67
+ publishedAt: "2024-01-01T00:00:00.000Z",
68
+ client: client,
69
+ user: userDoc,
70
+ scopes: ["client:access", "client:manager", "client-project:udate"]
71
+ },
72
+ scopes: ["client:access", "client:manager", "client-project:udate"]
73
+ }
74
+ const clientProject: ClientProjectDocument = {
75
+ id: 1,
76
+ documentId: "1234asdfhjkl",
77
+ createdAt: "2024-01-01T00:00:00.000Z",
78
+ updatedAt: "2024-01-01T00:00:00.000Z",
79
+ publishedAt: "2024-01-01T00:00:00.000Z",
80
+ title: "Test Client Project",
81
+ slug: "test-client-project",
82
+ project_status: ["for-sale"]
83
+ project_phase: "p1"
84
+ featured_image: null
85
+ }
86
+
87
+ // Check if user has permission to create a client project
88
+ hasPermission(user, clientUserStatus, "client-project", "create")
89
+ // > false
90
+
91
+ // Check if user has permission to update a client project
92
+ hasPermission(user, clientUserStatus, "client-project", "update", clientProject)
93
+ // > true
94
+
95
+ // Check if user has permission to access a client
96
+ hasPermission(user, clientUserStatus, "client", "access", client)
97
+ // > true
98
+ ```
package/dist/index.cjs CHANGED
@@ -100,7 +100,468 @@ var LIMIT_TAGS_MAX_SIZE = 1e3;
100
100
  var LIMIT_UTM_TRACKING_LINK_PAGINATION_DEFAULT_SIZE = 10;
101
101
  var LIMIT_UTM_TRACKING_LINK_PAGINATION_MAX_SIZE = 1e3;
102
102
 
103
- // src/constants/permission.constants.ts
103
+ // src/constants/regex.constants.ts
104
+ var ERROR_MESSAGE_REGEX_DOMAIN = "please provide a valid domain name";
105
+ var REGEX_DOMAIN = /^(?=.{1,253}$)(?!-)((xn--)?[a-zA-Z0-9]{1,59}(-[a-zA-Z0-9]{1,62})?\.)+([a-zA-Z]{2,63}|xn--[a-zA-Z0-9]{2,59})$/;
106
+ var ERROR_MESSAGE_REGEX_UTM_VALUE = `can only contain letters, numbers, and the special characters: - _ .`;
107
+ var REGEX_UTM_VALUE = /^([a-zA-Z0-9._-]+)?$/;
108
+ var REGEX_BRAND_COLOR_SLUG = /^([a-zA-Z0-9_-]+)?$/;
109
+ var ERROR_MESSAGE_REGEX_PHONE = "please provide a valid phone number";
110
+ var REGEX_NANP_PHONE = /^(?:\+?1[\s.-]?)?(?:\(?([2-9]\d{2})\)?[\s.-]?)(?:([2-9](?!11)\d{2}))[\s.-]?(\d{4})(?:\s*(?:#|x|ext\.?|extension)\s*\d+)?$/i;
111
+ var ERROR_MESSAGE_REGEX_URL_SLUG = `can only contain letters, numbers, and the special characters: - _ .`;
112
+ var REGEX_URL_SLUG = /^([a-zA-Z0-9._-]+)?$/;
113
+
114
+ // src/permissions/permission.abac.ts
115
+ var ROLE_PERMISSIONS = {
116
+ authenticated: {
117
+ client: {
118
+ access: false,
119
+ billing: false,
120
+ owner: false,
121
+ manager: false,
122
+ admin: false,
123
+ list: false,
124
+ create: false,
125
+ read: false,
126
+ update: false,
127
+ delete: false
128
+ },
129
+ "client-content-pillar": {
130
+ list: false,
131
+ create: false,
132
+ read: false,
133
+ update: false,
134
+ delete: false
135
+ },
136
+ "client-media-platform": {
137
+ list: false,
138
+ create: false,
139
+ read: false,
140
+ update: false,
141
+ delete: false
142
+ },
143
+ "client-project": {
144
+ list: false,
145
+ create: false,
146
+ read: false,
147
+ update: false,
148
+ delete: false,
149
+ assign: false
150
+ },
151
+ "client-report": {
152
+ list: false,
153
+ create: false,
154
+ read: false,
155
+ update: false,
156
+ delete: false
157
+ },
158
+ "client-styleguide": {
159
+ list: false,
160
+ create: false,
161
+ read: false,
162
+ update: false,
163
+ delete: false
164
+ },
165
+ "client-user": {
166
+ list: false,
167
+ create: false,
168
+ read: false,
169
+ update: false,
170
+ delete: false
171
+ },
172
+ "content-pillar": {
173
+ list: false,
174
+ create: false,
175
+ read: false,
176
+ update: false,
177
+ delete: false
178
+ },
179
+ "media-platform": {
180
+ list: false,
181
+ create: false,
182
+ read: false,
183
+ update: false,
184
+ delete: false
185
+ },
186
+ "user-account": {
187
+ list: false,
188
+ create: false,
189
+ read: false,
190
+ update: false,
191
+ delete: false
192
+ },
193
+ "utm-tracking-link": {
194
+ list: false,
195
+ create: false,
196
+ read: false,
197
+ update: false,
198
+ delete: false
199
+ }
200
+ },
201
+ public: {
202
+ client: {
203
+ access: false,
204
+ billing: false,
205
+ owner: false,
206
+ manager: false,
207
+ admin: false,
208
+ list: false,
209
+ create: false,
210
+ read: false,
211
+ update: false,
212
+ delete: false
213
+ },
214
+ "client-content-pillar": {
215
+ list: false,
216
+ create: false,
217
+ read: false,
218
+ update: false,
219
+ delete: false
220
+ },
221
+ "client-media-platform": {
222
+ list: false,
223
+ create: false,
224
+ read: false,
225
+ update: false,
226
+ delete: false
227
+ },
228
+ "client-project": {
229
+ list: false,
230
+ create: false,
231
+ read: false,
232
+ update: false,
233
+ delete: false,
234
+ assign: false
235
+ },
236
+ "client-report": {
237
+ list: false,
238
+ create: false,
239
+ read: false,
240
+ update: false,
241
+ delete: false
242
+ },
243
+ "client-styleguide": {
244
+ list: false,
245
+ create: false,
246
+ read: false,
247
+ update: false,
248
+ delete: false
249
+ },
250
+ "client-user": {
251
+ list: false,
252
+ create: false,
253
+ read: false,
254
+ update: false,
255
+ delete: false
256
+ },
257
+ "content-pillar": {
258
+ list: false,
259
+ create: false,
260
+ read: false,
261
+ update: false,
262
+ delete: false
263
+ },
264
+ "media-platform": {
265
+ list: false,
266
+ create: false,
267
+ read: false,
268
+ update: false,
269
+ delete: false
270
+ },
271
+ "user-account": {
272
+ list: false,
273
+ create: false,
274
+ read: false,
275
+ update: false,
276
+ delete: false
277
+ },
278
+ "utm-tracking-link": {
279
+ list: false,
280
+ create: false,
281
+ read: false,
282
+ update: false,
283
+ delete: false
284
+ }
285
+ },
286
+ employee: {
287
+ client: {
288
+ access: (u, p, d) => p.scopes.includes("client:access"),
289
+ billing: (u, p, d) => p.scopes.includes("client:billing"),
290
+ owner: (u, p, d) => p.scopes.includes("client:owner"),
291
+ manager: (u, p, d) => p.scopes.includes("client:manager"),
292
+ admin: (u, p, d) => p.scopes.includes("client:admin"),
293
+ list: (u, p, d) => p.scopes.includes("client:access"),
294
+ create: false,
295
+ read: (u, p, d) => p.scopes.includes("client:access"),
296
+ update: (u, p, d) => p.scopes.includes("client:manager"),
297
+ delete: false
298
+ },
299
+ "client-content-pillar": {
300
+ list: (u, p, d) => p.scopes.includes("client-content-pillar:list"),
301
+ create: (u, p) => p.scopes.includes("client-content-pillar:create"),
302
+ read: (u, p, d) => p.scopes.includes("client-content-pillar:read"),
303
+ update: (u, p, d) => p.scopes.includes("client-content-pillar:update"),
304
+ delete: false
305
+ },
306
+ "client-media-platform": {
307
+ list: (u, p, d) => p.scopes.includes("client-media-platform:list"),
308
+ create: (u, p) => p.scopes.includes("client-media-platform:create"),
309
+ read: (u, p, d) => p.scopes.includes("client-media-platform:read"),
310
+ update: (u, p, d) => p.scopes.includes("client-media-platform:update"),
311
+ delete: false
312
+ },
313
+ "client-project": {
314
+ list: (u, p, d) => p.scopes.includes("client-project:list"),
315
+ create: (u, p) => p.scopes.includes("client-project:create"),
316
+ read: (u, p, d) => p.scopes.includes("client-project:read"),
317
+ update: (u, p, d) => p.scopes.includes("client-project:update"),
318
+ delete: false,
319
+ assign: (u, p, d) => p.scopes.includes("client-project:assign")
320
+ },
321
+ "client-report": {
322
+ list: (u, p, d) => p.scopes.includes("client-report:list"),
323
+ create: (u, p) => p.scopes.includes("client-report:create"),
324
+ read: (u, p, d) => p.scopes.includes("client-report:read"),
325
+ update: (u, p, d) => p.scopes.includes("client-report:update"),
326
+ delete: false
327
+ },
328
+ "client-styleguide": {
329
+ list: (u, p, d) => p.scopes.includes("client-styleguide:list"),
330
+ create: false,
331
+ read: (u, p, d) => p.scopes.includes("client-styleguide:read"),
332
+ update: false,
333
+ delete: false
334
+ },
335
+ "client-user": {
336
+ list: true,
337
+ create: false,
338
+ read: true,
339
+ update: false,
340
+ delete: false,
341
+ verify: true
342
+ },
343
+ "content-pillar": {
344
+ list: true,
345
+ create: false,
346
+ read: true,
347
+ update: false,
348
+ delete: false
349
+ },
350
+ "media-platform": {
351
+ list: true,
352
+ create: false,
353
+ read: true,
354
+ update: false,
355
+ delete: false
356
+ },
357
+ "user-account": {
358
+ list: true,
359
+ create: false,
360
+ read: true,
361
+ update: (u, p, d) => u.account.documentId === d.documentId,
362
+ delete: false
363
+ },
364
+ "utm-tracking-link": {
365
+ list: (u, p, d) => p.scopes.includes("utm-tracking-link:list"),
366
+ create: (u, p) => p.scopes.includes("utm-tracking-link:create"),
367
+ read: (u, p, d) => {
368
+ var _a;
369
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:read");
370
+ },
371
+ update: (u, p, d) => {
372
+ var _a;
373
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:update");
374
+ },
375
+ delete: (u, p, d) => {
376
+ var _a;
377
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:delete");
378
+ }
379
+ }
380
+ },
381
+ manager: {
382
+ client: {
383
+ access: true,
384
+ billing: true,
385
+ owner: true,
386
+ manager: true,
387
+ admin: true,
388
+ list: true,
389
+ create: true,
390
+ read: true,
391
+ update: true,
392
+ delete: false
393
+ },
394
+ "client-content-pillar": {
395
+ list: true,
396
+ create: true,
397
+ read: true,
398
+ update: true,
399
+ delete: true
400
+ },
401
+ "client-media-platform": {
402
+ list: true,
403
+ create: true,
404
+ read: true,
405
+ update: true,
406
+ delete: true
407
+ },
408
+ "client-project": {
409
+ list: true,
410
+ create: true,
411
+ read: true,
412
+ update: true,
413
+ delete: true,
414
+ assign: true
415
+ },
416
+ "client-report": {
417
+ list: true,
418
+ create: true,
419
+ read: true,
420
+ update: true,
421
+ delete: true
422
+ },
423
+ "client-styleguide": {
424
+ list: true,
425
+ create: true,
426
+ read: true,
427
+ update: true,
428
+ delete: true
429
+ },
430
+ "client-user": {
431
+ list: true,
432
+ create: true,
433
+ read: true,
434
+ update: true,
435
+ delete: true,
436
+ verify: true
437
+ },
438
+ "content-pillar": {
439
+ list: true,
440
+ create: true,
441
+ read: true,
442
+ update: true,
443
+ delete: true
444
+ },
445
+ "media-platform": {
446
+ list: true,
447
+ create: true,
448
+ read: true,
449
+ update: true,
450
+ delete: true
451
+ },
452
+ "user-account": {
453
+ list: true,
454
+ create: false,
455
+ read: true,
456
+ update: (u, p, d) => u.account.documentId === d.documentId,
457
+ delete: false
458
+ },
459
+ "utm-tracking-link": {
460
+ list: true,
461
+ create: true,
462
+ read: true,
463
+ update: true,
464
+ delete: true
465
+ }
466
+ },
467
+ client: {
468
+ client: {
469
+ access: (u, p, d) => p.scopes.includes("client:access"),
470
+ billing: (u, p, d) => p.scopes.includes("client:billing"),
471
+ owner: (u, p, d) => p.scopes.includes("client:owner"),
472
+ manager: (u, p, d) => p.scopes.includes("client:manager"),
473
+ admin: (u, p, d) => p.scopes.includes("client:admin"),
474
+ list: (u, p, d) => p.scopes.includes("client:access"),
475
+ create: false,
476
+ read: (u, p, d) => p.scopes.includes("client:access"),
477
+ update: (u, p, d) => p.scopes.includes("client:manager"),
478
+ delete: false
479
+ },
480
+ "client-content-pillar": {
481
+ list: (u, p, d) => p.scopes.includes("client-content-pillar:list"),
482
+ create: (u, p) => p.scopes.includes("client-content-pillar:create"),
483
+ read: (u, p, d) => p.scopes.includes("client-content-pillar:read"),
484
+ update: (u, p, d) => p.scopes.includes("client-content-pillar:update"),
485
+ delete: false
486
+ },
487
+ "client-media-platform": {
488
+ list: (u, p, d) => p.scopes.includes("client-media-platform:list"),
489
+ create: (u, p) => p.scopes.includes("client-media-platform:create"),
490
+ read: (u, p, d) => p.scopes.includes("client-media-platform:read"),
491
+ update: (u, p, d) => p.scopes.includes("client-media-platform:update"),
492
+ delete: false
493
+ },
494
+ "client-project": {
495
+ list: (u, p, d) => p.scopes.includes("client-project:list"),
496
+ create: (u, p) => p.scopes.includes("client-project:create"),
497
+ read: (u, p, d) => p.scopes.includes("client-project:read"),
498
+ update: (u, p, d) => p.scopes.includes("client-project:update"),
499
+ delete: false,
500
+ assign: (u, p, d) => p.scopes.includes("client-project:assign")
501
+ },
502
+ "client-report": {
503
+ list: (u, p, d) => p.scopes.includes("client-report:list"),
504
+ create: (u, p) => p.scopes.includes("client-report:create"),
505
+ read: (u, p, d) => p.scopes.includes("client-report:read"),
506
+ update: (u, p, d) => p.scopes.includes("client-report:update"),
507
+ delete: false
508
+ },
509
+ "client-styleguide": {
510
+ list: (u, p, d) => p.scopes.includes("client-styleguide:list"),
511
+ create: false,
512
+ read: (u, p, d) => p.scopes.includes("client-styleguide:read"),
513
+ update: false,
514
+ delete: false
515
+ },
516
+ "client-user": {
517
+ list: true,
518
+ create: false,
519
+ read: true,
520
+ update: false,
521
+ delete: false,
522
+ verify: true
523
+ },
524
+ "content-pillar": {
525
+ list: true,
526
+ create: false,
527
+ read: true,
528
+ update: false,
529
+ delete: false
530
+ },
531
+ "media-platform": {
532
+ list: true,
533
+ create: false,
534
+ read: true,
535
+ update: false,
536
+ delete: false
537
+ },
538
+ "user-account": {
539
+ list: true,
540
+ create: false,
541
+ read: true,
542
+ update: (u, p, d) => u.account.documentId === d.documentId,
543
+ delete: false
544
+ },
545
+ "utm-tracking-link": {
546
+ list: (u, p, d) => p.scopes.includes("utm-tracking-link:list"),
547
+ create: (u, p) => p.scopes.includes("utm-tracking-link:create"),
548
+ read: (u, p, d) => {
549
+ var _a;
550
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:read");
551
+ },
552
+ update: (u, p, d) => {
553
+ var _a;
554
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:update");
555
+ },
556
+ delete: (u, p, d) => {
557
+ var _a;
558
+ return ((_a = d.creator) == null ? void 0 : _a.documentId) === u.documentId || p.scopes.includes("utm-tracking-link:delete");
559
+ }
560
+ }
561
+ }
562
+ };
563
+
564
+ // src/permissions/permission.constants.ts
104
565
  var CLIENT_ENTITY_PERMISSIONS = {
105
566
  client: ["admin", "owner", "manager", "billing", "access"],
106
567
  "client-project": ["list", "create", "read", "update", "delete", "assign"],
@@ -119,16 +580,14 @@ var CLIENT_ENTITY_SCOPES = Object.entries(
119
580
  ([entity, actions]) => actions.map((action) => `${entity}:${action}`)
120
581
  );
121
582
 
122
- // src/constants/regex.constants.ts
123
- var ERROR_MESSAGE_REGEX_DOMAIN = "please provide a valid domain name";
124
- var REGEX_DOMAIN = /^(?=.{1,253}$)(?!-)((xn--)?[a-zA-Z0-9]{1,59}(-[a-zA-Z0-9]{1,62})?\.)+([a-zA-Z]{2,63}|xn--[a-zA-Z0-9]{2,59})$/;
125
- var ERROR_MESSAGE_REGEX_UTM_VALUE = `can only contain letters, numbers, and the special characters: - _ .`;
126
- var REGEX_UTM_VALUE = /^([a-zA-Z0-9._-]+)?$/;
127
- var REGEX_BRAND_COLOR_SLUG = /^([a-zA-Z0-9_-]+)?$/;
128
- var ERROR_MESSAGE_REGEX_PHONE = "please provide a valid phone number";
129
- var REGEX_NANP_PHONE = /^(?:\+?1[\s.-]?)?(?:\(?([2-9]\d{2})\)?[\s.-]?)(?:([2-9](?!11)\d{2}))[\s.-]?(\d{4})(?:\s*(?:#|x|ext\.?|extension)\s*\d+)?$/i;
130
- var ERROR_MESSAGE_REGEX_URL_SLUG = `can only contain letters, numbers, and the special characters: - _ .`;
131
- var REGEX_URL_SLUG = /^([a-zA-Z0-9._-]+)?$/;
583
+ // src/permissions/permission.utilities.ts
584
+ function hasPermission(user, permissions, resource, action, data) {
585
+ var _a;
586
+ const permission = (_a = ROLE_PERMISSIONS[user.role.type][resource]) == null ? void 0 : _a[action];
587
+ if (permission == null) return false;
588
+ if (typeof permission === "boolean") return permission;
589
+ return data != null && permission(user, permissions, data);
590
+ }
132
591
  var IsValidBlogPostStatus = v6__namespace.picklist(["draft", "published"]);
133
592
  var IsValidOrUndefinedBlogPostStatus = v6__namespace.optional(IsValidBlogPostStatus);
134
593
  var IsValidOrUndefinedBlogPostStatusFallback = v6__namespace.optional(
@@ -1902,6 +2361,8 @@ var QuerySortUtmTrackingLinks = v6__namespace.optional(
1902
2361
  v6__namespace.object({
1903
2362
  key: v6__namespace.picklist([
1904
2363
  "id",
2364
+ "creator",
2365
+ "client",
1905
2366
  "url_destination",
1906
2367
  "utm_medium",
1907
2368
  "utm_source",
@@ -1932,6 +2393,8 @@ var QueryStrapiSearchUtmTrackingLinks = v6__namespace.object({
1932
2393
  v6__namespace.maxValue(LIMIT_UTM_TRACKING_LINK_PAGINATION_MAX_SIZE)
1933
2394
  )
1934
2395
  ),
2396
+ client_id: IsValidOrUndefinedReferenceDocumentId,
2397
+ creator_id: IsValidOrUndefinedReferenceDocumentId,
1935
2398
  url_destination: IsValidOrUndefinedDestinationUrl,
1936
2399
  utm_medium: IsValidOrUndefinedUrlUtmMedium,
1937
2400
  utm_source: IsValidOrUndefinedUrlUtmSource,
@@ -2382,6 +2845,7 @@ exports.REGEX_DOMAIN = REGEX_DOMAIN;
2382
2845
  exports.REGEX_NANP_PHONE = REGEX_NANP_PHONE;
2383
2846
  exports.REGEX_URL_SLUG = REGEX_URL_SLUG;
2384
2847
  exports.REGEX_UTM_VALUE = REGEX_UTM_VALUE;
2848
+ exports.ROLE_PERMISSIONS = ROLE_PERMISSIONS;
2385
2849
  exports.SAssociateClientToClientProjectDocument = SAssociateClientToClientProjectDocument;
2386
2850
  exports.SAuthConnectProviderConfirmation = SAuthConnectProviderConfirmation;
2387
2851
  exports.SAuthConnectProviderRedirectSearch = SAuthConnectProviderRedirectSearch;
@@ -2480,6 +2944,7 @@ exports.ValidNumberOfEmployeeOptions = ValidNumberOfEmployeeOptions;
2480
2944
  exports.ValidRatingRange5 = ValidRatingRange5;
2481
2945
  exports.datePlusDays = datePlusDays;
2482
2946
  exports.dateToday = dateToday;
2947
+ exports.hasPermission = hasPermission;
2483
2948
  exports.isStrapiAttributeError = isStrapiAttributeError;
2484
2949
  exports.isStrapiStandardError = isStrapiStandardError;
2485
2950
  exports.isValidationFailure = isValidationFailure;