@koloseum/utils 0.2.26 → 0.2.28
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 +55 -2
- package/dist/utils.js +301 -13
- package/package.json +3 -2
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Database } from "@koloseum/types/database";
|
|
2
|
-
import type { CustomError, Microservice, MicroserviceGroup, MicroserviceObject, UserWithCustomMetadata } from "@koloseum/types/general";
|
|
2
|
+
import type { BrowserInfo, CustomError, Microservice, MicroserviceGroup, MicroserviceObject, UserWithCustomMetadata } from "@koloseum/types/general";
|
|
3
3
|
import type { BranchAddressObject, County, IdentityType, PronounsCheckboxes, PronounsItem, Sex, SocialMediaPlatform } from "@koloseum/types/public-auth";
|
|
4
4
|
import type { Page } from "@sveltejs/kit";
|
|
5
5
|
import type { SupabaseClient, FunctionInvokeOptions, PostgrestError } from "@supabase/supabase-js";
|
|
@@ -261,7 +261,7 @@ export declare const Utility: {
|
|
|
261
261
|
*/
|
|
262
262
|
sanitiseHtml: (input: string) => string;
|
|
263
263
|
/**
|
|
264
|
-
* Sends a welcome notification to a user.
|
|
264
|
+
* Sends a welcome notification to a new user.
|
|
265
265
|
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
266
266
|
* @param {UserWithCustomMetadata} user - The user to send the notification to
|
|
267
267
|
* @param {MicroserviceGroup} microserviceGroup - The microservice group the user belongs to
|
|
@@ -339,3 +339,56 @@ export declare const Cache: {
|
|
|
339
339
|
*/
|
|
340
340
|
setData: <T>(valkey: any, cachePrefix: string, key: string, data: T, ttl?: number) => Promise<void>;
|
|
341
341
|
};
|
|
342
|
+
export declare const Browser: {
|
|
343
|
+
/**
|
|
344
|
+
* Checks if a specific feature is supported by the browser.
|
|
345
|
+
* @param feature - The feature to check
|
|
346
|
+
* @param browserName - The name of the browser
|
|
347
|
+
* @param browserVersion - The version of the browser
|
|
348
|
+
* @returns `true` if the feature is supported, `false` otherwise
|
|
349
|
+
*/
|
|
350
|
+
checkFeatureSupport: (feature: string, browserName: string, browserVersion: number) => boolean;
|
|
351
|
+
/**
|
|
352
|
+
* Gets detailed browser information for debugging.
|
|
353
|
+
*/
|
|
354
|
+
getDetailedInfo: () => {
|
|
355
|
+
browser: string;
|
|
356
|
+
os: string;
|
|
357
|
+
platform: string;
|
|
358
|
+
engine: string;
|
|
359
|
+
userAgent: string;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Gets comprehensive browser information using Bowser.
|
|
363
|
+
*/
|
|
364
|
+
getInfo: () => BrowserInfo;
|
|
365
|
+
/**
|
|
366
|
+
* Gets specific browser recommendations based on the detected browser.
|
|
367
|
+
*/
|
|
368
|
+
getRecommendations: () => {
|
|
369
|
+
title: string;
|
|
370
|
+
message: string;
|
|
371
|
+
recommendations: string[];
|
|
372
|
+
critical: boolean;
|
|
373
|
+
};
|
|
374
|
+
/**
|
|
375
|
+
* Checks if the current browser is compatible with the application.
|
|
376
|
+
*/
|
|
377
|
+
isBrowserCompatible: () => boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Checks if the browser is Internet Explorer.
|
|
380
|
+
*/
|
|
381
|
+
isInternetExplorer: () => boolean;
|
|
382
|
+
/**
|
|
383
|
+
* Checks if the browser is iOS Safari.
|
|
384
|
+
*/
|
|
385
|
+
isIOSSafari: () => boolean;
|
|
386
|
+
/**
|
|
387
|
+
* Checks if the browser is a legacy version that needs updating.
|
|
388
|
+
*/
|
|
389
|
+
isLegacyBrowser: () => boolean;
|
|
390
|
+
/**
|
|
391
|
+
* Checks if the browser is an old version of Safari.
|
|
392
|
+
*/
|
|
393
|
+
isOldSafari: () => boolean;
|
|
394
|
+
};
|
package/dist/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from "uuid";
|
|
2
2
|
import { error as svelteError } from "@sveltejs/kit";
|
|
3
3
|
import { FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/supabase-js";
|
|
4
|
+
import Bowser from "bowser";
|
|
4
5
|
import validator from "validator";
|
|
5
6
|
/* HELPERS */
|
|
6
7
|
const parsePgInterval = (await import("postgres-interval")).default;
|
|
@@ -867,19 +868,23 @@ export const Utility = {
|
|
|
867
868
|
// Assign result of authorisation check
|
|
868
869
|
isAuthorised = data;
|
|
869
870
|
}
|
|
870
|
-
//
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
871
|
+
// If user has completed Player registration
|
|
872
|
+
if (roles.includes("player")) {
|
|
873
|
+
// Prepare person data
|
|
874
|
+
let personData = {};
|
|
875
|
+
if (user.app_metadata.person_data) {
|
|
876
|
+
const { first_name: firstName, last_name: lastName, pseudonym } = user.app_metadata.person_data;
|
|
877
|
+
personData = { firstName, lastName, phone: user.phone, pseudonym };
|
|
878
|
+
}
|
|
879
|
+
// Validate SuprSend subscriber
|
|
880
|
+
const { code, error: validationError } = await Utility.callEdgeFunction(false, supabase, `suprsend/validate-subscriber?user-id=${user.id}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: personData });
|
|
881
|
+
if (validationError)
|
|
882
|
+
return { error: Utility.customError(code, validationError) };
|
|
883
|
+
// Send welcome notification if not already sent
|
|
884
|
+
const { error: welcomeError } = await Utility.sendWelcomeNotification(supabase, user, microserviceGroup);
|
|
885
|
+
if (welcomeError)
|
|
886
|
+
return { error: welcomeError };
|
|
875
887
|
}
|
|
876
|
-
const { code, error: validationError } = await Utility.callEdgeFunction(false, supabase, `suprsend/validate-subscriber?user-id=${user.id}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: personData });
|
|
877
|
-
if (validationError)
|
|
878
|
-
return { error: Utility.customError(code, validationError) };
|
|
879
|
-
// Send welcome notification if needed
|
|
880
|
-
const { error: welcomeError } = await Utility.sendWelcomeNotification(supabase, user, microserviceGroup);
|
|
881
|
-
if (welcomeError)
|
|
882
|
-
return { error: welcomeError };
|
|
883
888
|
// Return result
|
|
884
889
|
return { isAuthorised };
|
|
885
890
|
},
|
|
@@ -1476,7 +1481,7 @@ export const Utility = {
|
|
|
1476
1481
|
*/
|
|
1477
1482
|
sanitiseHtml: (input) => typeof input !== "string" ? "" : sanitize(input, { allowedTags: [], allowedAttributes: {} }),
|
|
1478
1483
|
/**
|
|
1479
|
-
* Sends a welcome notification to a user.
|
|
1484
|
+
* Sends a welcome notification to a new user.
|
|
1480
1485
|
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
1481
1486
|
* @param {UserWithCustomMetadata} user - The user to send the notification to
|
|
1482
1487
|
* @param {MicroserviceGroup} microserviceGroup - The microservice group the user belongs to
|
|
@@ -1729,3 +1734,286 @@ export const Cache = {
|
|
|
1729
1734
|
}
|
|
1730
1735
|
}
|
|
1731
1736
|
};
|
|
1737
|
+
/* BROWSER COMPATIBILITY FUNCTIONS */
|
|
1738
|
+
export const Browser = {
|
|
1739
|
+
/**
|
|
1740
|
+
* Checks if a specific feature is supported by the browser.
|
|
1741
|
+
* @param feature - The feature to check
|
|
1742
|
+
* @param browserName - The name of the browser
|
|
1743
|
+
* @param browserVersion - The version of the browser
|
|
1744
|
+
* @returns `true` if the feature is supported, `false` otherwise
|
|
1745
|
+
*/
|
|
1746
|
+
checkFeatureSupport: (feature, browserName, browserVersion) => {
|
|
1747
|
+
// Feature support matrix based on browser versions
|
|
1748
|
+
const featureSupport = {
|
|
1749
|
+
optionalChaining: {
|
|
1750
|
+
Chrome: 80,
|
|
1751
|
+
Firefox: 74,
|
|
1752
|
+
Safari: 13.4,
|
|
1753
|
+
Edge: 80,
|
|
1754
|
+
Opera: 80
|
|
1755
|
+
},
|
|
1756
|
+
nullishCoalescing: {
|
|
1757
|
+
Chrome: 80,
|
|
1758
|
+
Firefox: 72,
|
|
1759
|
+
Safari: 13.4,
|
|
1760
|
+
Edge: 80,
|
|
1761
|
+
Opera: 80
|
|
1762
|
+
},
|
|
1763
|
+
fetch: {
|
|
1764
|
+
Chrome: 42,
|
|
1765
|
+
Firefox: 39,
|
|
1766
|
+
Safari: 10.1,
|
|
1767
|
+
Edge: 14,
|
|
1768
|
+
Opera: 29
|
|
1769
|
+
},
|
|
1770
|
+
es6Modules: {
|
|
1771
|
+
Chrome: 61,
|
|
1772
|
+
Firefox: 60,
|
|
1773
|
+
Safari: 10.1,
|
|
1774
|
+
Edge: 16,
|
|
1775
|
+
Opera: 48
|
|
1776
|
+
},
|
|
1777
|
+
asyncAwait: {
|
|
1778
|
+
Chrome: 55,
|
|
1779
|
+
Firefox: 52,
|
|
1780
|
+
Safari: 10.1,
|
|
1781
|
+
Edge: 14,
|
|
1782
|
+
Opera: 42
|
|
1783
|
+
}
|
|
1784
|
+
};
|
|
1785
|
+
const featureMatrix = featureSupport[feature];
|
|
1786
|
+
if (!featureMatrix)
|
|
1787
|
+
return true; // Unknown feature, assume supported
|
|
1788
|
+
const minVersion = featureMatrix[browserName];
|
|
1789
|
+
if (!minVersion)
|
|
1790
|
+
return true; // Unknown browser, assume supported
|
|
1791
|
+
return browserVersion >= minVersion;
|
|
1792
|
+
},
|
|
1793
|
+
/**
|
|
1794
|
+
* Gets detailed browser information for debugging.
|
|
1795
|
+
*/
|
|
1796
|
+
getDetailedInfo: () => {
|
|
1797
|
+
if (typeof window === "undefined") {
|
|
1798
|
+
return {
|
|
1799
|
+
browser: "Server-side rendering",
|
|
1800
|
+
os: "Unknown",
|
|
1801
|
+
platform: "Unknown",
|
|
1802
|
+
engine: "Unknown",
|
|
1803
|
+
userAgent: "Unknown"
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1807
|
+
return {
|
|
1808
|
+
browser: `${browser.getBrowserName()} ${browser.getBrowserVersion()}`,
|
|
1809
|
+
os: `${browser.getOSName()} ${browser.getOSVersion()}`,
|
|
1810
|
+
platform: browser.getPlatformType(),
|
|
1811
|
+
engine: browser.getEngineName(),
|
|
1812
|
+
userAgent: window.navigator.userAgent
|
|
1813
|
+
};
|
|
1814
|
+
},
|
|
1815
|
+
/**
|
|
1816
|
+
* Gets comprehensive browser information using Bowser.
|
|
1817
|
+
*/
|
|
1818
|
+
getInfo: () => {
|
|
1819
|
+
if (typeof window === "undefined") {
|
|
1820
|
+
return {
|
|
1821
|
+
name: "server",
|
|
1822
|
+
version: 0,
|
|
1823
|
+
isOldSafari: false,
|
|
1824
|
+
isIOS: false,
|
|
1825
|
+
supportsOptionalChaining: true,
|
|
1826
|
+
supportsNullishCoalescing: true,
|
|
1827
|
+
supportsFetch: true
|
|
1828
|
+
};
|
|
1829
|
+
}
|
|
1830
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1831
|
+
const browserName = browser.getBrowserName();
|
|
1832
|
+
const browserVersion = parseFloat(browser.getBrowserVersion() || "0");
|
|
1833
|
+
const osName = browser.getOSName();
|
|
1834
|
+
const isIOS = osName === "iOS";
|
|
1835
|
+
const isSafari = browserName === "Safari";
|
|
1836
|
+
const isOldSafari = isSafari && browserVersion < 13.4;
|
|
1837
|
+
return {
|
|
1838
|
+
name: browserName,
|
|
1839
|
+
version: browserVersion,
|
|
1840
|
+
isOldSafari,
|
|
1841
|
+
isIOS,
|
|
1842
|
+
supportsOptionalChaining: Browser.checkFeatureSupport("optionalChaining", browserName, browserVersion),
|
|
1843
|
+
supportsNullishCoalescing: Browser.checkFeatureSupport("nullishCoalescing", browserName, browserVersion),
|
|
1844
|
+
supportsFetch: Browser.checkFeatureSupport("fetch", browserName, browserVersion)
|
|
1845
|
+
};
|
|
1846
|
+
},
|
|
1847
|
+
/**
|
|
1848
|
+
* Gets specific browser recommendations based on the detected browser.
|
|
1849
|
+
*/
|
|
1850
|
+
getRecommendations: () => {
|
|
1851
|
+
if (typeof window === "undefined")
|
|
1852
|
+
return {
|
|
1853
|
+
title: "Browser compatibility issue",
|
|
1854
|
+
message: "Browser detection is not available on theserver.",
|
|
1855
|
+
recommendations: [],
|
|
1856
|
+
critical: false
|
|
1857
|
+
};
|
|
1858
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1859
|
+
const browserName = browser.getBrowserName();
|
|
1860
|
+
const browserVersion = browser.getBrowserVersion();
|
|
1861
|
+
// Internet Explorer
|
|
1862
|
+
if (browserName === "Internet Explorer") {
|
|
1863
|
+
return {
|
|
1864
|
+
title: "Unsupported browser",
|
|
1865
|
+
message: "Internet Explorer is not supported. Please use a modern browser.",
|
|
1866
|
+
recommendations: [
|
|
1867
|
+
"Download and install Microsoft Edge",
|
|
1868
|
+
"Use an alternative such as Chrome or Firefox (or Safari on Mac)"
|
|
1869
|
+
],
|
|
1870
|
+
critical: true
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
// Apple Safari
|
|
1874
|
+
if (browserName === "Safari" && parseFloat(browserVersion || "0") < 13.4) {
|
|
1875
|
+
return {
|
|
1876
|
+
title: "Browser compatibility issue",
|
|
1877
|
+
message: `You're using Safari ${browserVersion || "Unknown"}, which doesn't support modern web features.`,
|
|
1878
|
+
recommendations: [
|
|
1879
|
+
"Update to Safari 13.4 or later",
|
|
1880
|
+
"Use Chrome or Firefox as an alternative",
|
|
1881
|
+
"Update your iOS device to the latest version"
|
|
1882
|
+
],
|
|
1883
|
+
critical: true
|
|
1884
|
+
};
|
|
1885
|
+
}
|
|
1886
|
+
// Google Chrome
|
|
1887
|
+
if (browserName === "Chrome" && parseFloat(browserVersion || "0") < 80) {
|
|
1888
|
+
return {
|
|
1889
|
+
title: "Outdated browser",
|
|
1890
|
+
message: `You're using Chrome ${browserVersion || "Unknown"}, which may not support all features.`,
|
|
1891
|
+
recommendations: ["Update Chrome to version 80 or later", "Enable automatic updates in Chrome settings"],
|
|
1892
|
+
critical: false
|
|
1893
|
+
};
|
|
1894
|
+
}
|
|
1895
|
+
// Mozilla Firefox
|
|
1896
|
+
if (browserName === "Firefox" && parseFloat(browserVersion || "0") < 80) {
|
|
1897
|
+
return {
|
|
1898
|
+
title: "Outdated browser",
|
|
1899
|
+
message: `You're using Firefox ${browserVersion || "Unknown"}, which may not support all features.`,
|
|
1900
|
+
recommendations: ["Update Firefox to version 80 or later", "Enable automatic updates in Firefox settings"],
|
|
1901
|
+
critical: false
|
|
1902
|
+
};
|
|
1903
|
+
}
|
|
1904
|
+
// Microsoft Edge
|
|
1905
|
+
if (browserName === "Edge" && parseFloat(browserVersion || "0") < 80) {
|
|
1906
|
+
return {
|
|
1907
|
+
title: "Outdated browser",
|
|
1908
|
+
message: `You're using Edge ${browserVersion || "Unknown"}, which may not support all features.`,
|
|
1909
|
+
recommendations: ["Update Edge to version 80 or later", "Enable automatic updates in Edge settings"],
|
|
1910
|
+
critical: false
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
// For unknown or very old browsers
|
|
1914
|
+
if (browserName === "Unknown" || parseFloat(browserVersion || "0") < 50) {
|
|
1915
|
+
return {
|
|
1916
|
+
title: "Unrecognised browser",
|
|
1917
|
+
message: "Your browser may not be fully supported. For the best experience, please use a modern browser.",
|
|
1918
|
+
recommendations: ["Use Chrome, Firefox or Edge (latest version)", "Use Safari 13.4+ (on Mac/iOS)"],
|
|
1919
|
+
critical: true
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
// Default for modern browsers
|
|
1923
|
+
return {
|
|
1924
|
+
title: "Browser compatibility issue",
|
|
1925
|
+
message: "Your browser may not fully support this application.",
|
|
1926
|
+
recommendations: [
|
|
1927
|
+
"Update your browser to the latest version",
|
|
1928
|
+
"Clear your browser cache and cookies",
|
|
1929
|
+
"Disable browser extensions temporarily",
|
|
1930
|
+
"Try a different modern browser"
|
|
1931
|
+
],
|
|
1932
|
+
critical: false
|
|
1933
|
+
};
|
|
1934
|
+
},
|
|
1935
|
+
/**
|
|
1936
|
+
* Checks if the current browser is compatible with the application.
|
|
1937
|
+
*/
|
|
1938
|
+
isBrowserCompatible: () => {
|
|
1939
|
+
if (typeof window === "undefined")
|
|
1940
|
+
return true;
|
|
1941
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1942
|
+
const browserName = browser.getBrowserName();
|
|
1943
|
+
const browserVersion = parseFloat(browser.getBrowserVersion() || "0");
|
|
1944
|
+
// Define minimum supported versions
|
|
1945
|
+
const minVersions = {
|
|
1946
|
+
"Internet Explorer": 0, // Not supported at all
|
|
1947
|
+
Safari: 13.4,
|
|
1948
|
+
Chrome: 80,
|
|
1949
|
+
Firefox: 80,
|
|
1950
|
+
Edge: 80,
|
|
1951
|
+
Opera: 80
|
|
1952
|
+
};
|
|
1953
|
+
// Internet Explorer is never compatible
|
|
1954
|
+
if (browserName === "Internet Explorer") {
|
|
1955
|
+
return false;
|
|
1956
|
+
}
|
|
1957
|
+
// Check if browser version meets minimum requirements
|
|
1958
|
+
const minVersion = minVersions[browserName];
|
|
1959
|
+
if (minVersion && browserVersion < minVersion) {
|
|
1960
|
+
return false;
|
|
1961
|
+
}
|
|
1962
|
+
// Check for critical modern features
|
|
1963
|
+
return (Browser.checkFeatureSupport("optionalChaining", browserName, browserVersion) &&
|
|
1964
|
+
Browser.checkFeatureSupport("nullishCoalescing", browserName, browserVersion) &&
|
|
1965
|
+
Browser.checkFeatureSupport("fetch", browserName, browserVersion) &&
|
|
1966
|
+
Browser.checkFeatureSupport("es6Modules", browserName, browserVersion) &&
|
|
1967
|
+
Browser.checkFeatureSupport("asyncAwait", browserName, browserVersion));
|
|
1968
|
+
},
|
|
1969
|
+
/**
|
|
1970
|
+
* Checks if the browser is Internet Explorer.
|
|
1971
|
+
*/
|
|
1972
|
+
isInternetExplorer: () => {
|
|
1973
|
+
if (typeof window === "undefined")
|
|
1974
|
+
return false;
|
|
1975
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1976
|
+
return browser.getBrowserName() === "Internet Explorer";
|
|
1977
|
+
},
|
|
1978
|
+
/**
|
|
1979
|
+
* Checks if the browser is iOS Safari.
|
|
1980
|
+
*/
|
|
1981
|
+
isIOSSafari: () => {
|
|
1982
|
+
if (typeof window === "undefined")
|
|
1983
|
+
return false;
|
|
1984
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1985
|
+
return browser.getOSName() === "iOS" && browser.getBrowserName() === "Safari";
|
|
1986
|
+
},
|
|
1987
|
+
/**
|
|
1988
|
+
* Checks if the browser is a legacy version that needs updating.
|
|
1989
|
+
*/
|
|
1990
|
+
isLegacyBrowser: () => {
|
|
1991
|
+
if (typeof window === "undefined")
|
|
1992
|
+
return false;
|
|
1993
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
1994
|
+
const browserName = browser.getBrowserName();
|
|
1995
|
+
const browserVersion = parseFloat(browser.getBrowserVersion() || "0");
|
|
1996
|
+
// Legacy browser thresholds
|
|
1997
|
+
const legacyThresholds = {
|
|
1998
|
+
"Internet Explorer": 0, // All versions are legacy
|
|
1999
|
+
Safari: 13.4,
|
|
2000
|
+
Chrome: 80,
|
|
2001
|
+
Firefox: 80,
|
|
2002
|
+
Edge: 80,
|
|
2003
|
+
Opera: 80
|
|
2004
|
+
};
|
|
2005
|
+
const threshold = legacyThresholds[browserName];
|
|
2006
|
+
return threshold ? browserVersion < threshold : false;
|
|
2007
|
+
},
|
|
2008
|
+
/**
|
|
2009
|
+
* Checks if the browser is an old version of Safari.
|
|
2010
|
+
*/
|
|
2011
|
+
isOldSafari: () => {
|
|
2012
|
+
if (typeof window === "undefined")
|
|
2013
|
+
return false;
|
|
2014
|
+
const browser = Bowser.getParser(window.navigator.userAgent);
|
|
2015
|
+
const browserName = browser.getBrowserName();
|
|
2016
|
+
const browserVersion = parseFloat(browser.getBrowserVersion() || "0");
|
|
2017
|
+
return browserName === "Safari" && browserVersion < 13.4;
|
|
2018
|
+
}
|
|
2019
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koloseum/utils",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.28",
|
|
4
4
|
"author": "Koloseum Technologies Limited",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Utility logic for use across Koloseum web apps (TypeScript)",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@supabase/supabase-js": "^2.57.4",
|
|
33
33
|
"@sveltejs/kit": "^2.41.0",
|
|
34
|
+
"bowser": "^2.12.1",
|
|
34
35
|
"kenya-administrative-divisions": "^0.0.18",
|
|
35
36
|
"postgres-interval": "^4.0.2",
|
|
36
37
|
"sanitize-html": "^2.17.0",
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
"validator": "^13.15.15"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@koloseum/types": "^0.2.
|
|
42
|
+
"@koloseum/types": "^0.2.10",
|
|
42
43
|
"@playwright/test": "^1.55.0",
|
|
43
44
|
"@suprsend/web-components": "^0.4.0",
|
|
44
45
|
"@types/sanitize-html": "^2.16.0",
|