@koloseum/utils 0.1.11 → 0.1.13

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/dist/utils.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import type { CustomError, UserWithAppMetadata } from "@koloseum/types/general";
1
+ import type { Database } from "@koloseum/types/database";
2
+ import type { CustomError, Microservice, MicroserviceGroup, MicroserviceObject, UserWithAppMetadata } from "@koloseum/types/general";
2
3
  import type { PronounsCheckboxes, SocialMediaPlatform } from "@koloseum/types/public-auth";
4
+ import type { Page } from "@sveltejs/kit";
5
+ import type { SupabaseClient, PostgrestError } from "@supabase/supabase-js";
3
6
  import type { SubscriberResponseDto } from "@novu/api/models/components/subscriberresponsedto.js";
4
- import type { PostgrestError } from "@supabase/supabase-js";
5
7
  import type { MobilePhoneLocale } from "validator";
6
8
  import { Novu } from "@novu/api";
7
9
  export declare const Status: {
@@ -19,6 +21,20 @@ export declare const Status: {
19
21
  PASSWORD_RESET_REQUESTED: string;
20
22
  };
21
23
  export declare const Utility: {
24
+ /**
25
+ * Calls a Supabase Edge function.
26
+ * @param {boolean} browser - Whether the function is being called in the browser
27
+ * @param {SupabaseClient} supabase - The Supabase client
28
+ * @param {string} path - The path to the Edge function
29
+ * @param {"GET" | "POST"} [method="GET"] - The HTTP method to use
30
+ * @returns The response from the Edge function
31
+ */
32
+ callEdgeFunction: (browser: boolean, supabase: SupabaseClient<Database>, path: string, method?: "GET" | "POST") => Promise<{
33
+ code: number;
34
+ data?: any;
35
+ error?: string;
36
+ context?: Record<string, any>;
37
+ }>;
22
38
  /**
23
39
  * Capitalises a given word.
24
40
  * @param {string} word - The word to be capitalised
@@ -82,10 +98,28 @@ export declare const Utility: {
82
98
  * - begins with "KL" followed by 7 digits
83
99
  */
84
100
  loungeIdRegex: RegExp;
101
+ /**
102
+ * A reference of microservices available on the platform, represented as an object with each user group (i.e. `public`, `players`, `lounges`, and `backroom`) having its own array of microservices. Each microservice in a list is an object with the following properties:
103
+ * - `name`: The name of the microservice.
104
+ * - `description`: A description of the microservice.
105
+ * - `slug`: The slug of the microservice.
106
+ * - `features`: An array of features that the microservice has.
107
+ * - `roles`: An array of roles attached to the microservice.
108
+ */
109
+ microservices: { [key in MicroserviceGroup]: MicroserviceObject<key>[]; };
85
110
  /**
86
111
  * The minimum birth date (from today's date) for a user who is a minor, i.e. `YYYY-MM-DD`
87
112
  */
88
113
  minimumMinorBirthDate: string;
114
+ /**
115
+ * Check if a page is active based on the slug and microservice.
116
+ * @param page - The current page object.
117
+ * @param slug - The slug of the page to check.
118
+ * @param microservice - The microservice to check against.
119
+ * @param base - The base path of the application; defaults to an empty string.
120
+ * @returns `true` if the page is active, `false` otherwise.
121
+ */
122
+ pageIsActive: (page: Page, slug: string, microservice?: Microservice<MicroserviceGroup>, base?: string) => boolean;
89
123
  /**
90
124
  * Parses a `CustomError` object within a page/layout server load function and returns an error to be thrown.
91
125
  * @param {CustomError} error - The error object
package/dist/utils.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { error as svelteError } from "@sveltejs/kit";
2
+ import { FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/supabase-js";
2
3
  import { ErrorDto } from "@novu/api/models/errors/errordto.js";
3
4
  import sanitize from "sanitize-html";
4
5
  import validator from "validator";
@@ -21,6 +22,76 @@ export const Status = {
21
22
  };
22
23
  /* Utility functions */
23
24
  export const Utility = {
25
+ /**
26
+ * Calls a Supabase Edge function.
27
+ * @param {boolean} browser - Whether the function is being called in the browser
28
+ * @param {SupabaseClient} supabase - The Supabase client
29
+ * @param {string} path - The path to the Edge function
30
+ * @param {"GET" | "POST"} [method="GET"] - The HTTP method to use
31
+ * @returns The response from the Edge function
32
+ */
33
+ callEdgeFunction: async (browser, supabase, path, method = "GET") => {
34
+ try {
35
+ // Set up headers with safe origin handling for SSR
36
+ const headers = {
37
+ "Content-Type": "application/json",
38
+ Accept: "application/json"
39
+ };
40
+ // Only add Origin header in browser environment
41
+ if (browser)
42
+ headers["Origin"] = window.location.origin;
43
+ // Fetch response with additional options for better cross-origin handling
44
+ const { data, error } = await supabase.functions.invoke(path, {
45
+ method,
46
+ headers
47
+ });
48
+ // Handle different error types
49
+ if (error) {
50
+ // Define context
51
+ const context = {};
52
+ // Define error code and message
53
+ const code = Number(error.context.status) || 500;
54
+ let message = Status.ERROR;
55
+ // Handle HTTP errors
56
+ if (error instanceof FunctionsHttpError) {
57
+ // Get error data
58
+ try {
59
+ // Get content type header
60
+ const contentType = error.context.headers.get("content-type");
61
+ // If content type is JSON, get error data
62
+ if (contentType.includes("application/json")) {
63
+ // Get error data
64
+ const data = await error.context.json();
65
+ // Assign error message
66
+ message = data.message;
67
+ }
68
+ // If content type is plain text, get error message
69
+ else if (contentType.includes("text/plain"))
70
+ message = await error.context.text();
71
+ // If any other content type, use the status text
72
+ else
73
+ message = error.context.statusText;
74
+ // Assign attempt ID to context if present
75
+ if (path.includes("verify-id") && data.attemptId)
76
+ context.attemptId = data.attemptId;
77
+ }
78
+ catch (error) {
79
+ console.error(error);
80
+ }
81
+ }
82
+ // Handle relay and fetch errors
83
+ else if (error instanceof FunctionsRelayError || error instanceof FunctionsFetchError)
84
+ message = error.message;
85
+ // Return error
86
+ return { code: code, error: message, context };
87
+ }
88
+ // Return response
89
+ return { code: 200, data };
90
+ }
91
+ catch (_err) {
92
+ return { code: 500, error: Status.ERROR };
93
+ }
94
+ },
24
95
  /**
25
96
  * Capitalises a given word.
26
97
  * @param {string} word - The word to be capitalised
@@ -134,15 +205,20 @@ export const Utility = {
134
205
  // Get person data from user metadata
135
206
  const { first_name: firstName, last_name: lastName, pseudonym } = user.app_metadata.person_data;
136
207
  // Create subscriber
137
- ({ result: subscriber } = await novu.subscribers.create({
138
- subscriberId: user.id,
139
- firstName,
140
- lastName,
141
- phone: user.phone,
142
- timezone: "Africa/Nairobi",
143
- locale: "en_KE",
144
- data: { pseudonym }
145
- }));
208
+ try {
209
+ ({ result: subscriber } = await novu.subscribers.create({
210
+ subscriberId: user.id,
211
+ firstName,
212
+ lastName,
213
+ phone: user.phone,
214
+ timezone: "Africa/Nairobi",
215
+ locale: "en_KE",
216
+ data: { pseudonym }
217
+ }));
218
+ }
219
+ catch (error) {
220
+ console.error(error);
221
+ }
146
222
  }
147
223
  // Otherwise, log error
148
224
  else
@@ -213,6 +289,187 @@ export const Utility = {
213
289
  * - begins with "KL" followed by 7 digits
214
290
  */
215
291
  loungeIdRegex: /^KL\d{7}$/,
292
+ /**
293
+ * A reference of microservices available on the platform, represented as an object with each user group (i.e. `public`, `players`, `lounges`, and `backroom`) having its own array of microservices. Each microservice in a list is an object with the following properties:
294
+ * - `name`: The name of the microservice.
295
+ * - `description`: A description of the microservice.
296
+ * - `slug`: The slug of the microservice.
297
+ * - `features`: An array of features that the microservice has.
298
+ * - `roles`: An array of roles attached to the microservice.
299
+ */
300
+ microservices: {
301
+ backroom: [
302
+ {
303
+ name: "Compliance",
304
+ description: "Management of compliance and regulatory requirements for Players and Lounges.",
305
+ slug: "compliance",
306
+ features: [
307
+ {
308
+ name: "Players",
309
+ description: "Manage Player data.",
310
+ slug: "players"
311
+ },
312
+ {
313
+ name: "Lounges",
314
+ description: "Manage Lounge data.",
315
+ slug: "lounges"
316
+ }
317
+ ],
318
+ roles: [
319
+ {
320
+ name: "Compliance",
321
+ slug: "compliance",
322
+ root: true
323
+ },
324
+ {
325
+ name: "Players",
326
+ slug: "players",
327
+ featureSlugs: ["players"]
328
+ },
329
+ {
330
+ name: "Lounges",
331
+ slug: "lounges",
332
+ featureSlugs: ["lounges"]
333
+ }
334
+ ]
335
+ },
336
+ {
337
+ name: "Competitions",
338
+ description: "Management of competitions data and live events across Markets.",
339
+ slug: "competitions",
340
+ features: [
341
+ {
342
+ name: "Ma Esto",
343
+ description: "Manage football esports data for Ma Esto.",
344
+ slug: "fbl"
345
+ },
346
+ {
347
+ name: "Savanna FGC",
348
+ description: "Manage fighting games esports data for Savanna FGC.",
349
+ slug: "fgc"
350
+ },
351
+ {
352
+ name: "Hit List",
353
+ description: "Manage battle royale esports data for Hit List.",
354
+ slug: "bryl"
355
+ }
356
+ ],
357
+ roles: [
358
+ {
359
+ name: "Competitions",
360
+ slug: "competitions",
361
+ root: true
362
+ },
363
+ {
364
+ name: "Ma Esto",
365
+ slug: "fbl",
366
+ featureSlugs: ["fbl"]
367
+ },
368
+ {
369
+ name: "Savanna FGC",
370
+ slug: "fgc",
371
+ featureSlugs: ["fgc"]
372
+ },
373
+ {
374
+ name: "Hit List",
375
+ slug: "bryl",
376
+ featureSlugs: ["bryl"]
377
+ }
378
+ ]
379
+ },
380
+ {
381
+ name: "KLSM",
382
+ description: "Management of store products and tracking of orders and payments.",
383
+ slug: "commerce",
384
+ features: [
385
+ {
386
+ name: "Sections",
387
+ description: "Manage store sections.",
388
+ slug: "sections"
389
+ },
390
+ {
391
+ name: "Products",
392
+ description: "Manage store products.",
393
+ slug: "products"
394
+ },
395
+ {
396
+ name: "Bundles",
397
+ description: "Manage store bundles.",
398
+ slug: "bundles"
399
+ },
400
+ {
401
+ name: "Inventory",
402
+ description: "Manage store inventory.",
403
+ slug: "inventory"
404
+ },
405
+ {
406
+ name: "Orders",
407
+ description: "Manage store orders.",
408
+ slug: "orders"
409
+ }
410
+ ],
411
+ roles: [
412
+ {
413
+ name: "Commerce",
414
+ slug: "commerce",
415
+ root: true
416
+ },
417
+ {
418
+ name: "Storefront",
419
+ slug: "storefront",
420
+ featureSlugs: ["sections", "products", "bundles"]
421
+ },
422
+ {
423
+ name: "Warehouse",
424
+ slug: "warehouse",
425
+ featureSlugs: ["inventory", "orders"]
426
+ }
427
+ ]
428
+ },
429
+ {
430
+ name: "Staff",
431
+ description: "Management of staff authorisation.",
432
+ slug: "staff",
433
+ features: [
434
+ {
435
+ name: "Roles",
436
+ description: "Review and manage Backroom roles.",
437
+ slug: "roles"
438
+ },
439
+ {
440
+ name: "Users",
441
+ description: "Review and manage Backroom users.",
442
+ slug: "users"
443
+ }
444
+ ],
445
+ roles: [
446
+ {
447
+ name: "Human Resources",
448
+ slug: "hr",
449
+ root: true
450
+ }
451
+ ]
452
+ },
453
+ {
454
+ name: "Account",
455
+ description: "Review of access and notifications.",
456
+ slug: "account",
457
+ features: [
458
+ {
459
+ name: "Access",
460
+ description: "Review access to Backroom microservices.",
461
+ slug: "access"
462
+ },
463
+ {
464
+ name: "Notifications",
465
+ description: "Review and manage Backroom notifications.",
466
+ slug: "notifications"
467
+ }
468
+ ],
469
+ roles: null
470
+ }
471
+ ]
472
+ },
216
473
  /**
217
474
  * The minimum birth date (from today's date) for a user who is a minor, i.e. `YYYY-MM-DD`
218
475
  */
@@ -224,6 +481,15 @@ export const Utility = {
224
481
  tomorrow.setFullYear(tomorrow18YearsAgo);
225
482
  return tomorrow.toISOString().split("T")[0];
226
483
  })(),
484
+ /**
485
+ * Check if a page is active based on the slug and microservice.
486
+ * @param page - The current page object.
487
+ * @param slug - The slug of the page to check.
488
+ * @param microservice - The microservice to check against.
489
+ * @param base - The base path of the application; defaults to an empty string.
490
+ * @returns `true` if the page is active, `false` otherwise.
491
+ */
492
+ pageIsActive: (page, slug, microservice, base = "") => slug === microservice || page.url.pathname.startsWith(`${base === "." ? "" : base}/${slug}`),
227
493
  /**
228
494
  * Parses a `CustomError` object within a page/layout server load function and returns an error to be thrown.
229
495
  * @param {CustomError} error - The error object
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koloseum/utils",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "author": "Koloseum Technologies Limited",
5
5
  "type": "module",
6
6
  "description": "Utility logic for use across Koloseum web apps (TypeScript)",
@@ -36,7 +36,7 @@
36
36
  "validator": "^13.12.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@koloseum/types": "^0.1.11",
39
+ "@koloseum/types": "^0.1.12",
40
40
  "@playwright/test": "^1.50.1",
41
41
  "@types/sanitize-html": "^2.13.0",
42
42
  "@types/validator": "^13.12.2",