@koloseum/utils 0.2.28 → 0.3.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.
- package/dist/client.d.ts +125 -0
- package/dist/client.js +680 -0
- package/dist/formatting.d.ts +125 -0
- package/dist/formatting.js +369 -0
- package/dist/general.d.ts +54 -0
- package/dist/general.js +88 -0
- package/dist/platform.d.ts +66 -0
- package/dist/platform.js +764 -0
- package/dist/server.d.ts +77 -0
- package/dist/server.js +300 -0
- package/package.json +25 -3
- package/dist/utils.d.ts +0 -394
- package/dist/utils.js +0 -2019
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Database } from "@koloseum/types/database";
|
|
2
|
+
import type { CustomError, Microservice, MicroserviceGroup, UserWithCustomMetadata } from "@koloseum/types/general";
|
|
3
|
+
import type { SupabaseClient, FunctionInvokeOptions, PostgrestError } from "@supabase/supabase-js";
|
|
4
|
+
export declare const Instance: {
|
|
5
|
+
/**
|
|
6
|
+
* Calls a Supabase Edge function.
|
|
7
|
+
* @param {boolean} browser - Whether the function is being called in the browser
|
|
8
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
9
|
+
* @param {string} path - The path to the Edge function
|
|
10
|
+
* @param {FunctionInvokeOptions} [options] - The options to use for the function invocation; defaults to `{ method: "GET" }`
|
|
11
|
+
* @returns The response from the Edge function
|
|
12
|
+
*/
|
|
13
|
+
callEdgeFunction: (browser: boolean, supabase: SupabaseClient<Database>, path: string, options?: FunctionInvokeOptions) => Promise<{
|
|
14
|
+
code: number;
|
|
15
|
+
data?: any;
|
|
16
|
+
error?: string;
|
|
17
|
+
context?: Record<string, any>;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Checks if a user is authorised to access a microservice.
|
|
21
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client.
|
|
22
|
+
* @param {UserWithCustomMetadata} user - The user to check.
|
|
23
|
+
* @param {Object} options - The options for the function.
|
|
24
|
+
* @param {MicroserviceGroup} options.microserviceGroup - The microservice group.
|
|
25
|
+
* @param {Microservice<MicroserviceGroup> | string} options.microservice - The microservice.
|
|
26
|
+
* @param {string} options.playersUrl - The URL to the Players microservice.
|
|
27
|
+
* @param {(role: string) => string} options.requestedPermission - A function that returns the requested permission for a given role.
|
|
28
|
+
* @returns {Promise<{ isAuthorised?: boolean; redirect?: { code: number; url: string }; error?: CustomError }>} The result of the function.
|
|
29
|
+
*/
|
|
30
|
+
isUserAuthorised: (supabase: SupabaseClient<Database>, user: UserWithCustomMetadata, options: {
|
|
31
|
+
microserviceGroup: MicroserviceGroup;
|
|
32
|
+
microservice: Microservice<MicroserviceGroup> | string;
|
|
33
|
+
playersUrl?: string;
|
|
34
|
+
requestedPermission?: (role: string) => string;
|
|
35
|
+
}) => Promise<{
|
|
36
|
+
isAuthorised?: boolean;
|
|
37
|
+
redirect?: {
|
|
38
|
+
code: number;
|
|
39
|
+
url: string;
|
|
40
|
+
};
|
|
41
|
+
error?: CustomError;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Sends a welcome notification to a new user.
|
|
45
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
46
|
+
* @param {UserWithCustomMetadata} user - The user to send the notification to
|
|
47
|
+
* @param {MicroserviceGroup} microserviceGroup - The microservice group the user belongs to
|
|
48
|
+
* @returns An object with an `error` if any has occurred
|
|
49
|
+
*/
|
|
50
|
+
sendWelcomeNotification: (supabase: SupabaseClient<Database>, user: UserWithCustomMetadata, microserviceGroup: MicroserviceGroup) => Promise<{
|
|
51
|
+
error?: CustomError;
|
|
52
|
+
}>;
|
|
53
|
+
};
|
|
54
|
+
export declare const Exception: {
|
|
55
|
+
/**
|
|
56
|
+
* Returns a custom error object.
|
|
57
|
+
* @param {number} code - The error code; defaults to `500` if not provided or invalid
|
|
58
|
+
* @param {string} message - The error message
|
|
59
|
+
* @returns An object with the error `code` and `message`
|
|
60
|
+
*/
|
|
61
|
+
customError: (code: number | undefined, message: string) => CustomError;
|
|
62
|
+
/**
|
|
63
|
+
* Parses a `CustomError` object within a page/layout server load function and returns an error to be thrown.
|
|
64
|
+
* @param {CustomError} error - The error object
|
|
65
|
+
* @returns A new `Error` object if the error is unexpected, or a Svelte error otherwise
|
|
66
|
+
*/
|
|
67
|
+
parseLoadError: (error: CustomError) => Error | never;
|
|
68
|
+
/**
|
|
69
|
+
* Parses a `PostgrestError` object and returns a custom error object if any has occurred.
|
|
70
|
+
* @param {PostgrestError | null} postgrestError - The `PostgrestError` object, or `null` if no error occurred
|
|
71
|
+
* @param {boolean} clientSafe - Whether to clamp 5xx errors down to 422 to prevent Sentry from capturing them as unhandled; defaults to `true`
|
|
72
|
+
* @returns An object with an `error` if any has occurred
|
|
73
|
+
*/
|
|
74
|
+
parsePostgrestError: (postgrestError: PostgrestError | null, clientSafe?: boolean) => {
|
|
75
|
+
error?: CustomError;
|
|
76
|
+
};
|
|
77
|
+
};
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { Status } from "./general.js";
|
|
2
|
+
import { error as svelteError } from "@sveltejs/kit";
|
|
3
|
+
import { FunctionsFetchError, FunctionsHttpError, FunctionsRelayError } from "@supabase/supabase-js";
|
|
4
|
+
/* INSTANCE HELPERS */
|
|
5
|
+
export const Instance = {
|
|
6
|
+
/**
|
|
7
|
+
* Calls a Supabase Edge function.
|
|
8
|
+
* @param {boolean} browser - Whether the function is being called in the browser
|
|
9
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
10
|
+
* @param {string} path - The path to the Edge function
|
|
11
|
+
* @param {FunctionInvokeOptions} [options] - The options to use for the function invocation; defaults to `{ method: "GET" }`
|
|
12
|
+
* @returns The response from the Edge function
|
|
13
|
+
*/
|
|
14
|
+
callEdgeFunction: async (browser, supabase, path, options = { method: "GET" }) => {
|
|
15
|
+
try {
|
|
16
|
+
// Only add Origin header in browser environment
|
|
17
|
+
if (browser)
|
|
18
|
+
options.headers = { ...options.headers, Origin: window.location.origin };
|
|
19
|
+
// Fetch response with additional options for better cross-origin handling
|
|
20
|
+
const { data, error } = await supabase.functions.invoke(path, options);
|
|
21
|
+
// Handle different error types
|
|
22
|
+
if (error) {
|
|
23
|
+
// Define context
|
|
24
|
+
const context = {};
|
|
25
|
+
// Define error code and message
|
|
26
|
+
const code = Number(error.context?.status) || 500;
|
|
27
|
+
let message = error.context?.statusText || Status.ERROR;
|
|
28
|
+
// Handle HTTP errors
|
|
29
|
+
if (error instanceof FunctionsHttpError) {
|
|
30
|
+
try {
|
|
31
|
+
// Get content type header safely
|
|
32
|
+
const contentType = error.context?.headers?.get("content-type") || "";
|
|
33
|
+
// If content type is JSON, get error data
|
|
34
|
+
if (contentType.includes("application/json")) {
|
|
35
|
+
try {
|
|
36
|
+
const errorData = await error.context.json();
|
|
37
|
+
message = errorData.message || message;
|
|
38
|
+
// Assign attempt ID to context if present
|
|
39
|
+
if (path.includes("verify-id") && errorData.attemptId)
|
|
40
|
+
context.attemptId = errorData.attemptId;
|
|
41
|
+
}
|
|
42
|
+
catch (jsonError) {
|
|
43
|
+
console.error("Failed to parse JSON error response:", jsonError);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// If content type is plain text, get error message
|
|
47
|
+
else if (contentType.includes("text/plain")) {
|
|
48
|
+
try {
|
|
49
|
+
message = await error.context.text();
|
|
50
|
+
}
|
|
51
|
+
catch (textError) {
|
|
52
|
+
console.error("Failed to parse text error response:", textError);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (parseError) {
|
|
57
|
+
console.error("Failed to parse error response:", parseError);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Handle relay and fetch errors
|
|
61
|
+
else if (error instanceof FunctionsRelayError || error instanceof FunctionsFetchError)
|
|
62
|
+
message = error.message;
|
|
63
|
+
// Return error
|
|
64
|
+
return { code: code, error: message, context };
|
|
65
|
+
}
|
|
66
|
+
// Return response
|
|
67
|
+
return { code: 200, data };
|
|
68
|
+
}
|
|
69
|
+
catch (unexpectedError) {
|
|
70
|
+
console.error("Unexpected error:", unexpectedError);
|
|
71
|
+
return { code: 500, error: Status.ERROR };
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* Checks if a user is authorised to access a microservice.
|
|
76
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client.
|
|
77
|
+
* @param {UserWithCustomMetadata} user - The user to check.
|
|
78
|
+
* @param {Object} options - The options for the function.
|
|
79
|
+
* @param {MicroserviceGroup} options.microserviceGroup - The microservice group.
|
|
80
|
+
* @param {Microservice<MicroserviceGroup> | string} options.microservice - The microservice.
|
|
81
|
+
* @param {string} options.playersUrl - The URL to the Players microservice.
|
|
82
|
+
* @param {(role: string) => string} options.requestedPermission - A function that returns the requested permission for a given role.
|
|
83
|
+
* @returns {Promise<{ isAuthorised?: boolean; redirect?: { code: number; url: string }; error?: CustomError }>} The result of the function.
|
|
84
|
+
*/
|
|
85
|
+
isUserAuthorised: async (supabase, user, options) => {
|
|
86
|
+
// Destructure options
|
|
87
|
+
const { microserviceGroup, microservice, playersUrl } = options;
|
|
88
|
+
// Return true if microservice group is public
|
|
89
|
+
if (microserviceGroup === "public")
|
|
90
|
+
return { isAuthorised: true };
|
|
91
|
+
// Validate user metadata and app metadata
|
|
92
|
+
if (!user.user_metadata || !user.app_metadata)
|
|
93
|
+
return { error: Exception.customError(400, "User metadata is required.") };
|
|
94
|
+
// Get user's roles and the role prefix
|
|
95
|
+
const roles = [];
|
|
96
|
+
const rolePrefix = microserviceGroup === "backroom" ? "backroom" : microserviceGroup.slice(0, -1);
|
|
97
|
+
for (const role of user.app_metadata.roles) {
|
|
98
|
+
if (role === "player") {
|
|
99
|
+
if (microserviceGroup === "players")
|
|
100
|
+
roles.push(role);
|
|
101
|
+
else
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (role.startsWith(`${rolePrefix}_`))
|
|
105
|
+
roles.push(role.replace(`${rolePrefix}_`, ""));
|
|
106
|
+
}
|
|
107
|
+
// Redirect to Players microservices if user does not have any roles for the microservice group
|
|
108
|
+
if (roles.length === 0 && microserviceGroup !== "players") {
|
|
109
|
+
// Return error if Players URL is not provided
|
|
110
|
+
if (!playersUrl)
|
|
111
|
+
return { error: Exception.customError(400, "Players URL is required.") };
|
|
112
|
+
// Redirect to Players microservices
|
|
113
|
+
return { redirect: { code: 307, url: playersUrl } };
|
|
114
|
+
}
|
|
115
|
+
// Destructure role
|
|
116
|
+
const [role] = roles;
|
|
117
|
+
// Define condition variables
|
|
118
|
+
const isPlayer = microserviceGroup === "players" && role === "player";
|
|
119
|
+
const isSuperuser = (microserviceGroup === "backroom" || microserviceGroup === "lounges") && role === "superuser";
|
|
120
|
+
let isAuthorised = false;
|
|
121
|
+
// Grant access if Player (accessing Players microservices), superuser, or account microservice
|
|
122
|
+
if (isPlayer || isSuperuser || microservice === "account")
|
|
123
|
+
isAuthorised = true;
|
|
124
|
+
// Evaluate access
|
|
125
|
+
else if (microserviceGroup !== "players") {
|
|
126
|
+
// Return error if requested permission is not provided
|
|
127
|
+
if (!options.requestedPermission)
|
|
128
|
+
return { error: Exception.customError(400, "Requested permission is required.") };
|
|
129
|
+
// Get user's role and requested app permission
|
|
130
|
+
const requestedPermission = options.requestedPermission(role);
|
|
131
|
+
// Check if user has the requested permission
|
|
132
|
+
const { data, error: isAuthorisedError } = await supabase
|
|
133
|
+
.schema("compliance")
|
|
134
|
+
.rpc("authorise", { requested_permission: requestedPermission });
|
|
135
|
+
if (isAuthorisedError)
|
|
136
|
+
return Exception.parsePostgrestError(isAuthorisedError);
|
|
137
|
+
// Assign result of authorisation check
|
|
138
|
+
isAuthorised = data;
|
|
139
|
+
}
|
|
140
|
+
// If user has completed Player registration
|
|
141
|
+
if (roles.includes("player")) {
|
|
142
|
+
// Prepare person data
|
|
143
|
+
let personData = {};
|
|
144
|
+
if (user.app_metadata.person_data) {
|
|
145
|
+
const { first_name: firstName, last_name: lastName, pseudonym } = user.app_metadata.person_data;
|
|
146
|
+
personData = { firstName, lastName, phone: user.phone, pseudonym };
|
|
147
|
+
}
|
|
148
|
+
// Validate SuprSend subscriber
|
|
149
|
+
const { code, error: validationError } = await Instance.callEdgeFunction(false, supabase, `suprsend/validate-subscriber?user-id=${user.id}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: personData });
|
|
150
|
+
if (validationError)
|
|
151
|
+
return { error: Exception.customError(code, validationError) };
|
|
152
|
+
// Send welcome notification if not already sent
|
|
153
|
+
const { error: welcomeError } = await Instance.sendWelcomeNotification(supabase, user, microserviceGroup);
|
|
154
|
+
if (welcomeError)
|
|
155
|
+
return { error: welcomeError };
|
|
156
|
+
}
|
|
157
|
+
// Return result
|
|
158
|
+
return { isAuthorised };
|
|
159
|
+
},
|
|
160
|
+
/**
|
|
161
|
+
* Sends a welcome notification to a new user.
|
|
162
|
+
* @param {SupabaseClient<Database>} supabase - The Supabase client
|
|
163
|
+
* @param {UserWithCustomMetadata} user - The user to send the notification to
|
|
164
|
+
* @param {MicroserviceGroup} microserviceGroup - The microservice group the user belongs to
|
|
165
|
+
* @returns An object with an `error` if any has occurred
|
|
166
|
+
*/
|
|
167
|
+
sendWelcomeNotification: async (supabase, user, microserviceGroup) => {
|
|
168
|
+
// Backroom
|
|
169
|
+
if (microserviceGroup === "backroom" && !user.user_metadata.backroom?.welcome_notification_sent) {
|
|
170
|
+
// Use atomic update with timestamp to prevent race conditions
|
|
171
|
+
const currentTime = new Date().toISOString();
|
|
172
|
+
const { data: updatedUser, error: updateError } = await supabase.auth.updateUser({
|
|
173
|
+
data: {
|
|
174
|
+
backroom: {
|
|
175
|
+
...user.user_metadata.backroom,
|
|
176
|
+
welcome_notification_sent: true,
|
|
177
|
+
welcome_notification_timestamp: currentTime
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
if (updateError)
|
|
182
|
+
return { error: Exception.customError(updateError.status ?? 500, updateError.message) };
|
|
183
|
+
// Only send notification if flag was successfully updated
|
|
184
|
+
const updatedBackroom = updatedUser.user?.user_metadata?.backroom;
|
|
185
|
+
if (updatedBackroom?.welcome_notification_sent === true &&
|
|
186
|
+
updatedBackroom?.welcome_notification_timestamp === currentTime) {
|
|
187
|
+
// Define SuprSend workflow body
|
|
188
|
+
const workflowBody = {
|
|
189
|
+
name: "welcome-to-backroom",
|
|
190
|
+
template: "welcome-to-backroom",
|
|
191
|
+
notification_category: "system",
|
|
192
|
+
users: [
|
|
193
|
+
{
|
|
194
|
+
distinct_id: user.id,
|
|
195
|
+
$skip_create: true
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
};
|
|
199
|
+
// Send welcome notification
|
|
200
|
+
const { code, error: workflowError } = await Instance.callEdgeFunction(false, supabase, `suprsend/trigger-workflow?user-id=${user.id}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: workflowBody });
|
|
201
|
+
// If notification fails, revert the flag and return error
|
|
202
|
+
if (workflowError) {
|
|
203
|
+
await supabase.auth.updateUser({
|
|
204
|
+
data: {
|
|
205
|
+
backroom: {
|
|
206
|
+
...user.user_metadata.backroom,
|
|
207
|
+
welcome_notification_sent: false,
|
|
208
|
+
welcome_notification_timestamp: undefined
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
return { error: Exception.customError(code, workflowError) };
|
|
213
|
+
}
|
|
214
|
+
// Update user object in memory
|
|
215
|
+
user.user_metadata.backroom = updatedBackroom;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Return empty object
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
/* EXCEPTION HELPERS */
|
|
223
|
+
export const Exception = {
|
|
224
|
+
/**
|
|
225
|
+
* Returns a custom error object.
|
|
226
|
+
* @param {number} code - The error code; defaults to `500` if not provided or invalid
|
|
227
|
+
* @param {string} message - The error message
|
|
228
|
+
* @returns An object with the error `code` and `message`
|
|
229
|
+
*/
|
|
230
|
+
customError: (code, message) => !code || code < 400 || code > 599 ? { code: 500, message: Status.ERROR } : { code, message },
|
|
231
|
+
/**
|
|
232
|
+
* Parses a `CustomError` object within a page/layout server load function and returns an error to be thrown.
|
|
233
|
+
* @param {CustomError} error - The error object
|
|
234
|
+
* @returns A new `Error` object if the error is unexpected, or a Svelte error otherwise
|
|
235
|
+
*/
|
|
236
|
+
parseLoadError: (error) => error.code === 500 ? new Error(error.message) : svelteError(error.code, { message: error.message }),
|
|
237
|
+
/**
|
|
238
|
+
* Parses a `PostgrestError` object and returns a custom error object if any has occurred.
|
|
239
|
+
* @param {PostgrestError | null} postgrestError - The `PostgrestError` object, or `null` if no error occurred
|
|
240
|
+
* @param {boolean} clientSafe - Whether to clamp 5xx errors down to 422 to prevent Sentry from capturing them as unhandled; defaults to `true`
|
|
241
|
+
* @returns An object with an `error` if any has occurred
|
|
242
|
+
*/
|
|
243
|
+
parsePostgrestError: (postgrestError, clientSafe = true) => {
|
|
244
|
+
// Return undefined if no error occurred
|
|
245
|
+
let error;
|
|
246
|
+
if (!postgrestError)
|
|
247
|
+
return { error };
|
|
248
|
+
// Get custom error code from hint
|
|
249
|
+
const customErrorCode = Number(postgrestError.hint);
|
|
250
|
+
// Clamp 5xx errors down to 422 to prevent Sentry from capturing them as unhandled; see https://koloseum-technologies.sentry.io/issues/6766267685/
|
|
251
|
+
let statusCode = clientSafe ? (customErrorCode >= 500 ? 422 : customErrorCode) : customErrorCode;
|
|
252
|
+
// Return custom error if hint is a number between 400 and 599
|
|
253
|
+
if (!isNaN(customErrorCode) && customErrorCode >= 400 && customErrorCode <= 599) {
|
|
254
|
+
error = Exception.customError(statusCode, postgrestError.message);
|
|
255
|
+
return { error };
|
|
256
|
+
}
|
|
257
|
+
// Map Postgrest error codes to custom error codes
|
|
258
|
+
const errorMap = [
|
|
259
|
+
{ code: "08", status: 503 },
|
|
260
|
+
{ code: "09", status: 500 },
|
|
261
|
+
{ code: "0L", status: 403 },
|
|
262
|
+
{ code: "0P", status: 403 },
|
|
263
|
+
{ code: "23503", status: 409 },
|
|
264
|
+
{ code: "23505", status: 409 },
|
|
265
|
+
{ code: "25006", status: 405 },
|
|
266
|
+
{ code: "25", status: 500 },
|
|
267
|
+
{ code: "28", status: 403 },
|
|
268
|
+
{ code: "2D", status: 500 },
|
|
269
|
+
{ code: "38", status: 500 },
|
|
270
|
+
{ code: "39", status: 500 },
|
|
271
|
+
{ code: "3B", status: 500 },
|
|
272
|
+
{ code: "40", status: 500 },
|
|
273
|
+
{ code: "53400", status: 500 },
|
|
274
|
+
{ code: "53", status: 503 },
|
|
275
|
+
{ code: "54", status: 500 },
|
|
276
|
+
{ code: "55", status: 500 },
|
|
277
|
+
{ code: "57", status: 500 },
|
|
278
|
+
{ code: "58", status: 500 },
|
|
279
|
+
{ code: "F0", status: 500 },
|
|
280
|
+
{ code: "HV", status: 500 },
|
|
281
|
+
{ code: "P0001", status: 400 },
|
|
282
|
+
{ code: "P0", status: 500 },
|
|
283
|
+
{ code: "XX", status: 500 },
|
|
284
|
+
{ code: "42883", status: 404 },
|
|
285
|
+
{ code: "42P01", status: 404 },
|
|
286
|
+
{ code: "42P17", status: 500 },
|
|
287
|
+
{ code: "42501", status: 403 }
|
|
288
|
+
];
|
|
289
|
+
// Return custom error if Postgrest error code is found
|
|
290
|
+
for (const { code, status } of errorMap)
|
|
291
|
+
if (postgrestError.code === code || postgrestError.code.startsWith(code)) {
|
|
292
|
+
statusCode = clientSafe ? (status >= 500 ? 422 : status) : status;
|
|
293
|
+
error = Exception.customError(statusCode, Status.ERROR);
|
|
294
|
+
return { error };
|
|
295
|
+
}
|
|
296
|
+
// Return generic error
|
|
297
|
+
error = Exception.customError(clientSafe ? 422 : 500, Status.ERROR);
|
|
298
|
+
return { error };
|
|
299
|
+
}
|
|
300
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koloseum/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"author": "Koloseum Technologies Limited",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Utility logic for use across Koloseum web apps (TypeScript)",
|
|
@@ -15,9 +15,31 @@
|
|
|
15
15
|
"type": "git",
|
|
16
16
|
"url": "git+https://github.com/koloseum-technologies/npm-utils.git"
|
|
17
17
|
},
|
|
18
|
-
"main": "./dist/utils.js",
|
|
19
18
|
"exports": {
|
|
20
|
-
"
|
|
19
|
+
"./client": "./dist/client.js",
|
|
20
|
+
"./formatting": "./dist/formatting.js",
|
|
21
|
+
"./general": "./dist/general.js",
|
|
22
|
+
"./platform": "./dist/platform.js",
|
|
23
|
+
"./server": "./dist/server.js"
|
|
24
|
+
},
|
|
25
|
+
"typesVersions": {
|
|
26
|
+
"*": {
|
|
27
|
+
"client": [
|
|
28
|
+
"./dist/client.d.ts"
|
|
29
|
+
],
|
|
30
|
+
"formatting": [
|
|
31
|
+
"./dist/formatting.d.ts"
|
|
32
|
+
],
|
|
33
|
+
"general": [
|
|
34
|
+
"./dist/general.d.ts"
|
|
35
|
+
],
|
|
36
|
+
"platform": [
|
|
37
|
+
"./dist/platform.d.ts"
|
|
38
|
+
],
|
|
39
|
+
"server": [
|
|
40
|
+
"./dist/server.d.ts"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
21
43
|
},
|
|
22
44
|
"files": [
|
|
23
45
|
"./dist/**/*"
|