@juki-team/commons 0.1.47 → 0.1.48

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.
Files changed (191) hide show
  1. package/dist/{types/constants → constants}/commons.d.ts +1 -1
  2. package/dist/constants/commons.js +648 -0
  3. package/dist/{types/constants → constants}/contest.d.ts +1 -1
  4. package/dist/constants/contest.js +28 -0
  5. package/dist/{types/constants → constants}/course.d.ts +1 -1
  6. package/dist/constants/course.js +12 -0
  7. package/dist/constants/date.js +23 -0
  8. package/dist/constants/email.js +34 -0
  9. package/dist/{types/constants → constants}/entity.d.ts +1 -1
  10. package/dist/constants/entity.js +18 -0
  11. package/dist/{types/constants → constants}/file.d.ts +1 -1
  12. package/dist/constants/file.js +45 -0
  13. package/dist/constants/index.d.ts +18 -0
  14. package/dist/constants/index.js +18 -0
  15. package/dist/{types/constants → constants}/judge.d.ts +1 -1
  16. package/dist/constants/judge.js +225 -0
  17. package/dist/{types/constants → constants}/organization.d.ts +1 -1
  18. package/dist/constants/organization.js +24 -0
  19. package/dist/{types/constants → constants}/problem.d.ts +1 -1
  20. package/dist/constants/problem.js +69 -0
  21. package/dist/constants/routing.js +7 -0
  22. package/dist/{types/constants → constants}/services.d.ts +1 -1
  23. package/dist/constants/services.js +157 -0
  24. package/dist/{types/constants → constants}/system.d.ts +1 -1
  25. package/dist/constants/system.js +9 -0
  26. package/dist/{types/constants → constants}/teams.d.ts +1 -1
  27. package/dist/constants/teams.js +17 -0
  28. package/dist/constants/time.js +9 -0
  29. package/dist/{types/constants → constants}/user.d.ts +2 -2
  30. package/dist/constants/user.js +40 -0
  31. package/dist/{types/constants → constants}/websocket.d.ts +1 -1
  32. package/dist/constants/websocket.js +56 -0
  33. package/dist/{types/constants → constants}/worksheet.d.ts +1 -1
  34. package/dist/constants/worksheet.js +66 -0
  35. package/dist/{types/dto → dto}/class.d.ts +3 -3
  36. package/dist/dto/class.js +1 -0
  37. package/dist/{types/dto → dto}/code.d.ts +1 -1
  38. package/dist/dto/code.js +1 -0
  39. package/dist/{types/dto → dto}/comments.d.ts +1 -1
  40. package/dist/dto/comments.js +1 -0
  41. package/dist/{types/dto → dto}/contest.d.ts +4 -4
  42. package/dist/dto/contest.js +7 -0
  43. package/dist/{types/dto → dto}/course.d.ts +4 -4
  44. package/dist/dto/course.js +1 -0
  45. package/dist/{types/dto → dto}/entity.d.ts +2 -2
  46. package/dist/dto/entity.js +5 -0
  47. package/dist/{types/dto → dto}/excalidraw.d.ts +3 -3
  48. package/dist/dto/excalidraw.js +1 -0
  49. package/dist/{types/dto → dto}/file.d.ts +2 -2
  50. package/dist/dto/file.js +1 -0
  51. package/dist/dto/image.js +1 -0
  52. package/dist/dto/index.d.ts +25 -0
  53. package/dist/dto/index.js +25 -0
  54. package/dist/{types/dto → dto}/judge.d.ts +1 -1
  55. package/dist/dto/judge.js +1 -0
  56. package/dist/{types/dto → dto}/markdown.d.ts +3 -3
  57. package/dist/dto/markdown.js +1 -0
  58. package/dist/{types/dto → dto}/mermaid.d.ts +3 -3
  59. package/dist/dto/mermaid.js +1 -0
  60. package/dist/{types/dto → dto}/organization.d.ts +3 -3
  61. package/dist/dto/organization.js +1 -0
  62. package/dist/{types/dto → dto}/problem.d.ts +3 -3
  63. package/dist/dto/problem.js +1 -0
  64. package/dist/{types/dto → dto}/scoreboard.d.ts +2 -2
  65. package/dist/dto/scoreboard.js +1 -0
  66. package/dist/{types/dto → dto}/session.d.ts +2 -2
  67. package/dist/dto/session.js +1 -0
  68. package/dist/{types/dto → dto}/socket.d.ts +3 -3
  69. package/dist/dto/socket.js +1 -0
  70. package/dist/{types/dto → dto}/statistics.d.ts +1 -1
  71. package/dist/dto/statistics.js +1 -0
  72. package/dist/{types/dto → dto}/submission.d.ts +3 -3
  73. package/dist/dto/submission.js +1 -0
  74. package/dist/{types/dto → dto}/system.d.ts +1 -1
  75. package/dist/dto/system.js +1 -0
  76. package/dist/dto/url.js +1 -0
  77. package/dist/{types/dto → dto}/user.d.ts +3 -3
  78. package/dist/dto/user.js +1 -0
  79. package/dist/{types/dto → dto}/virtual-user.d.ts +1 -1
  80. package/dist/dto/virtual-user.js +1 -0
  81. package/dist/{types/dto → dto}/worksheet-submissions.d.ts +3 -3
  82. package/dist/dto/worksheet-submissions.js +1 -0
  83. package/dist/{types/dto → dto}/worksheet.d.ts +3 -3
  84. package/dist/dto/worksheet.js +1 -0
  85. package/dist/{types/helpers → helpers}/class.d.ts +1 -1
  86. package/dist/helpers/class.js +10 -0
  87. package/dist/helpers/comments.js +4 -0
  88. package/dist/{types/helpers → helpers}/commons.d.ts +1 -1
  89. package/dist/helpers/commons.js +187 -0
  90. package/dist/{types/helpers → helpers}/contest.d.ts +1 -1
  91. package/dist/helpers/contest.js +21 -0
  92. package/dist/helpers/date.js +181 -0
  93. package/dist/{types/helpers → helpers}/document.d.ts +2 -2
  94. package/dist/helpers/document.js +51 -0
  95. package/dist/{types/helpers → helpers}/errors.d.ts +1 -1
  96. package/dist/helpers/errors.js +17 -0
  97. package/dist/helpers/file.js +4 -0
  98. package/dist/helpers/index.d.ts +17 -0
  99. package/dist/helpers/index.js +17 -0
  100. package/dist/helpers/interval.js +24 -0
  101. package/dist/{types/helpers → helpers}/judging.d.ts +1 -1
  102. package/dist/helpers/judging.js +124 -0
  103. package/dist/helpers/number.js +2 -0
  104. package/dist/helpers/object.js +33 -0
  105. package/dist/{types/helpers → helpers}/responses.d.ts +2 -2
  106. package/dist/helpers/responses.js +95 -0
  107. package/dist/{types/helpers → helpers}/socket.d.ts +2 -2
  108. package/dist/helpers/socket.js +279 -0
  109. package/dist/{types/helpers → helpers}/time.d.ts +1 -1
  110. package/dist/helpers/time.js +69 -0
  111. package/dist/{types/helpers → helpers}/user.d.ts +1 -1
  112. package/dist/helpers/user.js +14 -0
  113. package/dist/{types/helpers → helpers}/worksheet.d.ts +1 -1
  114. package/dist/helpers/worksheet.js +107 -0
  115. package/dist/index.d.ts +4 -0
  116. package/dist/index.js +4 -0
  117. package/dist/types/account.js +10 -0
  118. package/dist/types/{types/class.d.ts → class.d.ts} +2 -2
  119. package/dist/types/class.js +7 -0
  120. package/dist/types/comments.js +1 -0
  121. package/dist/types/{types/commons.d.ts → commons.d.ts} +1 -1
  122. package/dist/types/commons.js +69 -0
  123. package/dist/types/{types/contest.d.ts → contest.d.ts} +4 -4
  124. package/dist/types/contest.js +27 -0
  125. package/dist/types/{types/course.d.ts → course.d.ts} +1 -1
  126. package/dist/types/course.js +1 -0
  127. package/dist/types/entity.js +50 -0
  128. package/dist/types/{types/excalidraw.d.ts → excalidraw.d.ts} +1 -1
  129. package/dist/types/excalidraw.js +1 -0
  130. package/dist/types/{types/file.d.ts → file.d.ts} +2 -2
  131. package/dist/types/file.js +19 -0
  132. package/dist/types/{types/group.d.ts → group.d.ts} +1 -1
  133. package/dist/types/group.js +5 -0
  134. package/dist/types/index.d.ts +27 -4
  135. package/dist/types/index.js +27 -0
  136. package/dist/types/{types/judge.d.ts → judge.d.ts} +2 -2
  137. package/dist/types/judge.js +49 -0
  138. package/dist/types/{types/markdown.d.ts → markdown.d.ts} +1 -1
  139. package/dist/types/markdown.js +1 -0
  140. package/dist/types/{types/mermaid.d.ts → mermaid.d.ts} +1 -1
  141. package/dist/types/mermaid.js +1 -0
  142. package/dist/types/notification.js +8 -0
  143. package/dist/types/organization.js +14 -0
  144. package/dist/types/{types/prisma.d.ts → prisma.d.ts} +1 -1
  145. package/dist/types/prisma.js +106 -0
  146. package/dist/types/{types/problems.d.ts → problems.d.ts} +3 -3
  147. package/dist/types/problems.js +28 -0
  148. package/dist/types/scoreboard.js +1 -0
  149. package/dist/types/{types/services.d.ts → services.d.ts} +1 -1
  150. package/dist/types/services.js +152 -0
  151. package/dist/types/{types/sheet.d.ts → sheet.d.ts} +2 -2
  152. package/dist/types/sheet.js +16 -0
  153. package/dist/types/{types/socket.d.ts → socket.d.ts} +1 -1
  154. package/dist/types/socket.js +76 -0
  155. package/dist/types/submission.js +1 -0
  156. package/dist/types/system.js +1 -0
  157. package/dist/types/{types/teams.d.ts → teams.d.ts} +2 -2
  158. package/dist/types/teams.js +1 -0
  159. package/dist/types/{types/users.d.ts → users.d.ts} +2 -2
  160. package/dist/types/users.js +23 -0
  161. package/dist/types/virtual-user.js +8 -0
  162. package/dist/types/{types/worksheet.d.ts → worksheet.d.ts} +3 -3
  163. package/dist/types/worksheet.js +11 -0
  164. package/package.json +8 -11
  165. package/dist/cjs/index.cjs +0 -3700
  166. package/dist/esm/index.js +0 -3420
  167. package/dist/types/constants/index.d.ts +0 -18
  168. package/dist/types/dto/index.d.ts +0 -25
  169. package/dist/types/helpers/index.d.ts +0 -17
  170. package/dist/types/types/index.d.ts +0 -27
  171. /package/dist/{types/constants → constants}/date.d.ts +0 -0
  172. /package/dist/{types/constants → constants}/email.d.ts +0 -0
  173. /package/dist/{types/constants → constants}/routing.d.ts +0 -0
  174. /package/dist/{types/constants → constants}/time.d.ts +0 -0
  175. /package/dist/{types/dto → dto}/image.d.ts +0 -0
  176. /package/dist/{types/dto → dto}/url.d.ts +0 -0
  177. /package/dist/{types/helpers → helpers}/comments.d.ts +0 -0
  178. /package/dist/{types/helpers → helpers}/date.d.ts +0 -0
  179. /package/dist/{types/helpers → helpers}/file.d.ts +0 -0
  180. /package/dist/{types/helpers → helpers}/interval.d.ts +0 -0
  181. /package/dist/{types/helpers → helpers}/number.d.ts +0 -0
  182. /package/dist/{types/helpers → helpers}/object.d.ts +0 -0
  183. /package/dist/types/{types/account.d.ts → account.d.ts} +0 -0
  184. /package/dist/types/{types/comments.d.ts → comments.d.ts} +0 -0
  185. /package/dist/types/{types/entity.d.ts → entity.d.ts} +0 -0
  186. /package/dist/types/{types/notification.d.ts → notification.d.ts} +0 -0
  187. /package/dist/types/{types/organization.d.ts → organization.d.ts} +0 -0
  188. /package/dist/types/{types/scoreboard.d.ts → scoreboard.d.ts} +0 -0
  189. /package/dist/types/{types/submission.d.ts → submission.d.ts} +0 -0
  190. /package/dist/types/{types/system.d.ts → system.d.ts} +0 -0
  191. /package/dist/types/{types/virtual-user.d.ts → virtual-user.d.ts} +0 -0
@@ -0,0 +1,17 @@
1
+ import { ERROR } from '../constants/services.js';
2
+ export class JkError extends Error {
3
+ code;
4
+ data;
5
+ constructor(code, custom) {
6
+ const message = custom?.message || ERROR[code].message;
7
+ super(message);
8
+ this.message = message;
9
+ this.code = code;
10
+ if (custom?.stack) {
11
+ this.stack = custom.stack;
12
+ }
13
+ if (custom?.data) {
14
+ this.data = custom.data;
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,4 @@
1
+ export function removeExtension(fileName) {
2
+ const i = fileName.lastIndexOf('.');
3
+ return i !== -1 ? fileName.substring(0, i) : fileName;
4
+ }
@@ -0,0 +1,17 @@
1
+ export * from './class.js';
2
+ export * from './comments.js';
3
+ export * from './commons.js';
4
+ export * from './contest.js';
5
+ export * from './date.js';
6
+ export * from './document.js';
7
+ export * from './errors.js';
8
+ export * from './file.js';
9
+ export * from './interval.js';
10
+ export * from './judging.js';
11
+ export * from './number.js';
12
+ export * from './object.js';
13
+ export * from './responses.js';
14
+ export * from './socket.js';
15
+ export * from './time.js';
16
+ export * from './user.js';
17
+ export * from './worksheet.js';
@@ -0,0 +1,17 @@
1
+ export * from './class.js';
2
+ export * from './comments.js';
3
+ export * from './commons.js';
4
+ export * from './contest.js';
5
+ export * from './date.js';
6
+ export * from './document.js';
7
+ export * from './errors.js';
8
+ export * from './file.js';
9
+ export * from './interval.js';
10
+ export * from './judging.js';
11
+ export * from './number.js';
12
+ export * from './object.js';
13
+ export * from './responses.js';
14
+ export * from './socket.js';
15
+ export * from './time.js';
16
+ export * from './user.js';
17
+ export * from './worksheet.js';
@@ -0,0 +1,24 @@
1
+ // https://dev.to/jsmccrumb/asynchronous-setinterval-4j69
2
+ const asyncIntervals = [];
3
+ const runAsyncInterval = async (cb, interval, intervalIndex) => {
4
+ await cb();
5
+ if (asyncIntervals[intervalIndex]) {
6
+ setTimeout(() => runAsyncInterval(cb, interval, intervalIndex), interval);
7
+ }
8
+ };
9
+ export const setAsyncInterval = (cb, interval) => {
10
+ if (cb && typeof cb === 'function') {
11
+ const intervalIndex = asyncIntervals.length;
12
+ asyncIntervals.push(true);
13
+ void runAsyncInterval(cb, interval, intervalIndex);
14
+ return intervalIndex;
15
+ }
16
+ else {
17
+ throw new Error('Callback must be a function');
18
+ }
19
+ };
20
+ export const clearAsyncInterval = (intervalIndex) => {
21
+ if (asyncIntervals[intervalIndex]) {
22
+ asyncIntervals[intervalIndex] = false;
23
+ }
24
+ };
@@ -1,4 +1,4 @@
1
- import { CodeEditorTestCase, DataLog, ProblemVerdict, SubmissionTestCase, TestCaseVerdict } from '../types';
1
+ import { CodeEditorTestCase, DataLog, ProblemVerdict, SubmissionTestCase, TestCaseVerdict } from '../types/index.js';
2
2
  export declare const getDataOfTestCase: (testCase: SubmissionTestCase, timeLimit: number, memoryLimit: number) => {
3
3
  compilationError: boolean;
4
4
  timeUsed: number;
@@ -0,0 +1,124 @@
1
+ import { ProblemVerdict, SubmissionRunStatus, } from '../types/index.js';
2
+ export const getDataOfTestCase = (testCase, timeLimit, memoryLimit) => {
3
+ const { timeUsed, memoryUsed, exitCode } = getDataLog(testCase?.log);
4
+ const timeLimitExceeded = timeUsed > timeLimit;
5
+ const memoryLimitExceeded = memoryUsed > memoryLimit;
6
+ const runtimeError = exitCode !== 0;
7
+ const compilationError = testCase?.status === SubmissionRunStatus.COMPILATION_ERROR;
8
+ return {
9
+ compilationError,
10
+ timeUsed,
11
+ timeLimitExceeded: timeLimitExceeded,
12
+ memoryUsed,
13
+ memoryLimitExceeded: memoryLimitExceeded,
14
+ exitCode,
15
+ runtimeError,
16
+ failed: !!testCase?.log && (timeLimitExceeded || memoryLimitExceeded || runtimeError),
17
+ };
18
+ };
19
+ export const getVerdictFromTestCase = (testCaseValue, timeLimit, memoryLimit) => {
20
+ const { compilationError, timeLimitExceeded, memoryLimitExceeded, runtimeError, timeUsed, memoryUsed, exitCode, } = getDataOfTestCase(testCaseValue, timeLimit, memoryLimit);
21
+ return {
22
+ verdict: compilationError
23
+ ? ProblemVerdict.CE
24
+ : timeLimitExceeded
25
+ ? ProblemVerdict.TLE
26
+ : memoryLimitExceeded
27
+ ? ProblemVerdict.MLE
28
+ : runtimeError
29
+ ? ProblemVerdict.RE
30
+ : testCaseValue.out === testCaseValue.testOut
31
+ ? ProblemVerdict.AC
32
+ : testCaseValue.withPE && testCaseValue.out.split(' ').join('').split('\n').join('') === testCaseValue.testOut.split(' ').join('').split('\n').join('')
33
+ ? ProblemVerdict.PE
34
+ : !testCaseValue.withPE && testCaseValue.out.split(' ').join('').split('\n').join('') === testCaseValue.testOut.split(' ').join('').split('\n').join('')
35
+ ? ProblemVerdict.AC
36
+ : ProblemVerdict.WA,
37
+ timeUsed,
38
+ memoryUsed,
39
+ exitCode,
40
+ };
41
+ };
42
+ export const mergeVerdicts = (first, second) => {
43
+ let verdict = first.verdict;
44
+ if (second.verdict === ProblemVerdict.RE) {
45
+ verdict = ProblemVerdict.RE;
46
+ }
47
+ else if (second.verdict === ProblemVerdict.TLE && verdict != ProblemVerdict.RE) {
48
+ verdict = ProblemVerdict.TLE;
49
+ }
50
+ else if (second.verdict === ProblemVerdict.MLE
51
+ && verdict !== ProblemVerdict.TLE
52
+ && verdict !== ProblemVerdict.RE) {
53
+ verdict = ProblemVerdict.MLE;
54
+ }
55
+ else if (second.verdict === ProblemVerdict.WA
56
+ && verdict !== ProblemVerdict.MLE
57
+ && verdict !== ProblemVerdict.TLE
58
+ && verdict !== ProblemVerdict.RE) {
59
+ verdict = ProblemVerdict.WA;
60
+ }
61
+ else if (second.verdict === ProblemVerdict.PE
62
+ && verdict !== ProblemVerdict.WA
63
+ && verdict !== ProblemVerdict.MLE
64
+ && verdict !== ProblemVerdict.TLE
65
+ && verdict !== ProblemVerdict.RE) {
66
+ verdict = ProblemVerdict.PE;
67
+ }
68
+ else if (second.verdict === ProblemVerdict.PA
69
+ && verdict !== ProblemVerdict.PE
70
+ && verdict !== ProblemVerdict.WA
71
+ && verdict !== ProblemVerdict.MLE
72
+ && verdict !== ProblemVerdict.TLE
73
+ && verdict !== ProblemVerdict.RE) {
74
+ verdict = ProblemVerdict.PA;
75
+ }
76
+ else if (second.verdict === ProblemVerdict.AC
77
+ && verdict !== ProblemVerdict.PA
78
+ && verdict !== ProblemVerdict.PE
79
+ && verdict !== ProblemVerdict.WA
80
+ && verdict !== ProblemVerdict.MLE
81
+ && verdict !== ProblemVerdict.TLE
82
+ && verdict !== ProblemVerdict.RE) {
83
+ verdict = ProblemVerdict.AC;
84
+ }
85
+ return {
86
+ timeUsed: Math.max(first.timeUsed, second.timeUsed),
87
+ memoryUsed: Math.max(first.memoryUsed, second.memoryUsed),
88
+ exitCode: first.exitCode || second.exitCode,
89
+ verdict,
90
+ };
91
+ };
92
+ export const getDataLog = (log) => {
93
+ const lines = log?.split?.('\n') || [];
94
+ let timeUsed = 0;
95
+ let memoryUsed = 0;
96
+ let exitCode = -1;
97
+ if (lines.length > 4) {
98
+ for (const line of lines) {
99
+ if (line.startsWith('time:')) {
100
+ timeUsed = +line.split(':')[1];
101
+ if (Number.isNaN(timeUsed)) {
102
+ timeUsed = 0;
103
+ }
104
+ timeUsed *= 1000;
105
+ }
106
+ else if (line.startsWith('max-rss:')) {
107
+ memoryUsed = parseInt(line.split(':')[1], 10); // en KB
108
+ }
109
+ else if (line.startsWith('exitcode:')) {
110
+ exitCode = parseInt(line.split(':')[1], 10);
111
+ }
112
+ }
113
+ }
114
+ else if (lines.length >= 3) {
115
+ timeUsed = +lines[0];
116
+ memoryUsed = +lines[1];
117
+ exitCode = +lines[2];
118
+ }
119
+ return {
120
+ timeUsed: Number.isNaN(timeUsed) ? 0 : timeUsed,
121
+ memoryUsed: Number.isNaN(memoryUsed) ? 0 : memoryUsed,
122
+ exitCode: Number.isNaN(exitCode) ? -1 : exitCode,
123
+ };
124
+ };
@@ -0,0 +1,2 @@
1
+ export const padStart = (n, maxLength, fillString = '0') => `${n}`.padStart(maxLength, fillString);
2
+ export const padEnd = (n, maxLength, fillString = '0') => `${n}`.padEnd(maxLength, fillString);
@@ -0,0 +1,33 @@
1
+ export function memorySizeOf(obj) {
2
+ let bytes = 0;
3
+ function sizeOf(obj) {
4
+ if (obj !== null && obj !== undefined) {
5
+ switch (typeof obj) {
6
+ case "number":
7
+ bytes += 8;
8
+ break;
9
+ case "string":
10
+ bytes += obj.length * 2;
11
+ break;
12
+ case "boolean":
13
+ bytes += 4;
14
+ break;
15
+ case "object":
16
+ const objClass = Object.prototype.toString.call(obj).slice(8, -1);
17
+ if (objClass === "Object" || objClass === "Array") {
18
+ for (const key in obj) {
19
+ if (!obj.hasOwnProperty(key))
20
+ continue;
21
+ bytes += key.length * 2;
22
+ sizeOf(obj[key]);
23
+ }
24
+ }
25
+ else
26
+ bytes += obj.toString().length * 2;
27
+ break;
28
+ }
29
+ }
30
+ return bytes;
31
+ }
32
+ return sizeOf(obj);
33
+ }
@@ -1,5 +1,5 @@
1
- import { JkError } from './errors';
2
- import { ContentResponse, ContentsMeta, ContentsResponse, ErrorResponse } from '../types';
1
+ import { JkError } from './errors.js';
2
+ import { ContentResponse, ContentsMeta, ContentsResponse, ErrorResponse } from '../types/index.js';
3
3
  export declare function toJkError(err: any): JkError;
4
4
  export declare function errorsResponse(message: string, ...errors: JkError[]): ErrorResponse;
5
5
  export declare function contentResponse<T>(message: string, content: T): ContentResponse<T>;
@@ -0,0 +1,95 @@
1
+ import { ERROR } from '../constants/index.js';
2
+ import { JkError } from './errors.js';
3
+ import { ErrorCode } from '../types/index.js';
4
+ import { consoleError, isStringJson } from './commons.js';
5
+ export function toJkError(err) {
6
+ const error = new Error();
7
+ let code = err?.code;
8
+ if (!(code in ErrorCode)) {
9
+ code = ErrorCode.ERR500;
10
+ }
11
+ return new JkError(code, {
12
+ message: err?.message || error.message,
13
+ stack: err?.stack || error.stack,
14
+ data: err?.data || null,
15
+ });
16
+ }
17
+ export function errorsResponse(message, ...errors) {
18
+ return {
19
+ success: false,
20
+ message: message,
21
+ errors: errors.map(error => ({
22
+ code: error.code,
23
+ message: error.message,
24
+ detail: error.stack || new Error().stack || '',
25
+ data: error.data,
26
+ })),
27
+ };
28
+ }
29
+ export function contentResponse(message, content) {
30
+ return {
31
+ success: true,
32
+ message,
33
+ content,
34
+ };
35
+ }
36
+ export function contentsResponse(message, contents, meta) {
37
+ return {
38
+ success: true,
39
+ message,
40
+ contents,
41
+ meta,
42
+ };
43
+ }
44
+ export const cleanRequest = (responseText) => {
45
+ if (!isStringJson(responseText)) {
46
+ // this occurs when the endpoint don't exits or server is down
47
+ const response = {
48
+ success: false,
49
+ message: ERROR[ErrorCode.ERR9999].message,
50
+ errors: [{ code: ErrorCode.ERR9999, detail: '', message: ERROR[ErrorCode.ERR9999].message }],
51
+ };
52
+ consoleError({ message: 'response is not string json, success false on cleaning request', responseText, response });
53
+ // jukiApiManager.reportError({ message: 'success false on cleaning request', responseText, response });
54
+ return response;
55
+ }
56
+ const responseJson = JSON.parse(responseText);
57
+ if (typeof responseJson.success === 'boolean') {
58
+ if (responseJson.success === true && typeof responseJson.message === 'string' && responseJson.content) { // V1
59
+ return {
60
+ success: true,
61
+ message: responseJson.message,
62
+ content: responseJson.content,
63
+ };
64
+ }
65
+ else if (responseJson.success === true && typeof responseJson.message === 'string' && Array.isArray(responseJson.contents) && responseJson.meta) { // V1
66
+ return {
67
+ success: true,
68
+ message: responseJson.message,
69
+ contents: responseJson.contents,
70
+ meta: responseJson.meta,
71
+ };
72
+ }
73
+ else if (responseJson.success === false && typeof responseJson.message === 'string' && Array.isArray(responseJson.errors)) { // V1
74
+ const response = {
75
+ success: false,
76
+ message: responseJson.message,
77
+ errors: responseJson.errors,
78
+ };
79
+ consoleError({ message: 'success false on cleaning request', responseText, response });
80
+ // jukiApiManager.reportError({ message: 'success false on cleaning request', responseText, response });
81
+ return response;
82
+ }
83
+ }
84
+ const response = {
85
+ success: false,
86
+ message: ERROR[ErrorCode.ERR9998].message,
87
+ errors: [{ code: ErrorCode.ERR9998, detail: '', message: ERROR[ErrorCode.ERR9998].message }],
88
+ };
89
+ consoleError({ message: 'success false on cleaning request', responseText, response });
90
+ // jukiApiManager.reportError({ message: 'success false on cleaning request', responseText, response });
91
+ return response;
92
+ };
93
+ export const getDefaultMeta = (contents, sort) => {
94
+ return { sort: sort ?? [], page: 1, size: contents.length, totalElements: contents.length, filter: {} };
95
+ };
@@ -1,5 +1,5 @@
1
- import { CodeRunStatusWebSocketResponseEventDto, ContestChangesWebSocketResponseEventDto, ProblemCrawledWebSocketResponseEventDto, SendDataEc2InstancesListWebSocketResponseEventDto, SendDataEcsTaskDefinitionListWebSocketResponseEventDto, SendDataEcsTasksListWebSocketResponseEventDto, SendDataRunCommandWebSocketResponseEventDto, SendDataSsmSessionsListWebSocketResponseEventDto, SendDataWebSocketResponseEventDto, SubmissionJudgingWebSocketResponseEventDto, SubmissionRunStatusWebSocketResponseEventDto, SubmissionsCrawlWebSocketResponseEventDto, SubmissionsJudgingScope, SubscribeCodeRunStatusWebSocketEventDto, SubscribeContestChangesWebSocketEventDto, SubscribeGetDataWebSocketEventDto, SubscribeProblemCrawledWebSocketEventDto, SubscribeSubmissionRunStatusWebSocketEventDto, SubscribeSubmissionsCrawlWebSocketEventDto, SubscribeSubmissionsJudgingWebSocketEventDto, SubscribeUserNotificationWebsocketEventDto, UnsubscribeCodeRunStatusWebSocketEventDto, UnsubscribeContestChangesWebSocketEventDto, UnsubscribeGetDataWebSocketEventDto, UnsubscribeProblemCrawledWebSocketEventDto, UnsubscribeSubmissionRunStatusWebSocketEventDto, UnsubscribeSubmissionsCrawlWebSocketEventDto, UnsubscribeSubmissionsJudgingWebSocketEventDto, UnsubscribeUserNotificationWebSocketEventDto, UserMessageWebSocketResponseEventDto, UserNotificationContestClarificationWebSocketResponseEventDto, UserNotificationSubmissionWebSocketResponseEventDto, UserNotificationWebSocketResponseEventDto, WebSocketChannelsMessageDto, WebSocketResponseEventDto, WebSocketSubscribeEventDto, WebSocketUnsubscribeEventDto } from '../dto';
2
- import { ClientId, WebSocketResponseEvent, WebSocketResponseEventKey } from '../types';
1
+ import { CodeRunStatusWebSocketResponseEventDto, ContestChangesWebSocketResponseEventDto, ProblemCrawledWebSocketResponseEventDto, SendDataEc2InstancesListWebSocketResponseEventDto, SendDataEcsTaskDefinitionListWebSocketResponseEventDto, SendDataEcsTasksListWebSocketResponseEventDto, SendDataRunCommandWebSocketResponseEventDto, SendDataSsmSessionsListWebSocketResponseEventDto, SendDataWebSocketResponseEventDto, SubmissionJudgingWebSocketResponseEventDto, SubmissionRunStatusWebSocketResponseEventDto, SubmissionsCrawlWebSocketResponseEventDto, SubmissionsJudgingScope, SubscribeCodeRunStatusWebSocketEventDto, SubscribeContestChangesWebSocketEventDto, SubscribeGetDataWebSocketEventDto, SubscribeProblemCrawledWebSocketEventDto, SubscribeSubmissionRunStatusWebSocketEventDto, SubscribeSubmissionsCrawlWebSocketEventDto, SubscribeSubmissionsJudgingWebSocketEventDto, SubscribeUserNotificationWebsocketEventDto, UnsubscribeCodeRunStatusWebSocketEventDto, UnsubscribeContestChangesWebSocketEventDto, UnsubscribeGetDataWebSocketEventDto, UnsubscribeProblemCrawledWebSocketEventDto, UnsubscribeSubmissionRunStatusWebSocketEventDto, UnsubscribeSubmissionsCrawlWebSocketEventDto, UnsubscribeSubmissionsJudgingWebSocketEventDto, UnsubscribeUserNotificationWebSocketEventDto, UserMessageWebSocketResponseEventDto, UserNotificationContestClarificationWebSocketResponseEventDto, UserNotificationSubmissionWebSocketResponseEventDto, UserNotificationWebSocketResponseEventDto, WebSocketChannelsMessageDto, WebSocketResponseEventDto, WebSocketSubscribeEventDto, WebSocketUnsubscribeEventDto } from '../dto/index.js';
2
+ import { ClientId, WebSocketResponseEvent, WebSocketResponseEventKey } from '../types/index.js';
3
3
  export declare const isWebsocketSubscription: (event: any) => event is WebSocketSubscribeEventDto | WebSocketUnsubscribeEventDto;
4
4
  export declare const isSubscribeCodeRunStatusWebSocketEventDto: (event: any) => event is SubscribeCodeRunStatusWebSocketEventDto;
5
5
  export declare const isUnsubscribeCodeRunStatusWebSocketEventDto: (event: any) => event is UnsubscribeCodeRunStatusWebSocketEventDto;
@@ -0,0 +1,279 @@
1
+ import { CHANNEL_CONTEST, CHANNEL_PROBLEM, CHANNEL_SUBMISSION, CHANNEL_USER_ROLE, } from '../constants/websocket.js';
2
+ import { ContestChannelRole, ProblemChannelRole, ProblemVerdict, SubmissionRunStatus, UserChannelRole, WebSocketResponseEvent, WebSocketSubscriptionEvent, } from '../types/index.js';
3
+ import { join } from './commons.js';
4
+ export const isWebsocketSubscription = (event) => {
5
+ return Object.values(WebSocketSubscriptionEvent).includes(event?.event)
6
+ && typeof event?.clientId === 'string' && !!event.clientId;
7
+ };
8
+ // CHANNEL_PUBLISH_SUBSCRIPTIONS
9
+ export const isSubscribeCodeRunStatusWebSocketEventDto = (event) => {
10
+ return isWebsocketSubscription(event)
11
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_CODE_RUN_STATUS
12
+ && typeof event?.runId === 'string' && !!event.runId;
13
+ };
14
+ export const isUnsubscribeCodeRunStatusWebSocketEventDto = (event) => {
15
+ return isWebsocketSubscription(event)
16
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_CODE_RUN_STATUS
17
+ && typeof event?.runId === 'string' && !!event.runId;
18
+ };
19
+ export const isSubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
20
+ return isWebsocketSubscription(event)
21
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSION_RUN_STATUS
22
+ && typeof event?.submitId === 'string' && !!event.submitId;
23
+ };
24
+ export const isUnsubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
25
+ return isWebsocketSubscription(event)
26
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSION_RUN_STATUS
27
+ && typeof event?.submitId === 'string' && !!event.submitId;
28
+ };
29
+ export const isSubscribeGetDataWebSocketEventDto = (event) => {
30
+ return isWebsocketSubscription(event)
31
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_GET_DATA;
32
+ };
33
+ export const isUnsubscribeGetDataWebSocketEventDto = (event) => {
34
+ return isWebsocketSubscription(event)
35
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_GET_DATA;
36
+ };
37
+ export const isSubscribeProblemCrawledWebSocketEventDto = (event) => {
38
+ return isWebsocketSubscription(event)
39
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_PROBLEM_CRAWLED;
40
+ };
41
+ export const isUnsubscribeProblemCrawledWebSocketEventDto = (event) => {
42
+ return isWebsocketSubscription(event)
43
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_PROBLEM_CRAWLED;
44
+ };
45
+ export const isSubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
46
+ return isWebsocketSubscription(event)
47
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_CRAWL;
48
+ };
49
+ export const isUnsubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
50
+ return isWebsocketSubscription(event)
51
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_CRAWL;
52
+ };
53
+ export const isSubscribeContestChangesWebSocketEventDto = (event) => {
54
+ return isWebsocketSubscription(event)
55
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_CONTEST_CHANGES;
56
+ };
57
+ export const isUnsubscribeContestChangesWebSocketEventDto = (event) => {
58
+ return isWebsocketSubscription(event)
59
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_CONTEST_CHANGES;
60
+ };
61
+ export const isSubscribeUserNotificationWebSocketEventDto = (event) => {
62
+ return isWebsocketSubscription(event)
63
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_USER_NOTIFICATION;
64
+ };
65
+ export const isUnsubscribeUserNotificationWebSocketEventDto = (event) => {
66
+ return isWebsocketSubscription(event)
67
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_USER_NOTIFICATION;
68
+ };
69
+ const isNonEmptyString = (value) => typeof value === 'string' && !!value;
70
+ /**
71
+ * Exactly one of `problemKey` / `contestKey` / `userKey` is set.
72
+ */
73
+ export const isSubmissionsJudgingScope = (scope) => {
74
+ return [scope?.problemKey, scope?.contestKey, scope?.userKey].filter(isNonEmptyString).length === 1;
75
+ };
76
+ export const isSubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
77
+ return isWebsocketSubscription(event)
78
+ && event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_JUDGING
79
+ && isSubmissionsJudgingScope(event);
80
+ };
81
+ export const isUnsubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
82
+ return isWebsocketSubscription(event)
83
+ && event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_JUDGING
84
+ && isSubmissionsJudgingScope(event);
85
+ };
86
+ // is WebSocketResponseEventDto, CHANNEL_SUBSCRIBE_CLIENT
87
+ export const isWebSocketResponseEventDto = (event) => {
88
+ return Object.values(WebSocketResponseEvent).includes(event?.event)
89
+ && typeof event?.key === 'string'
90
+ && typeof event?.connectionId === 'string'
91
+ && typeof event?.createdAt === 'number' && !!event.createdAt;
92
+ };
93
+ export const isCodeRunStatusMessageWebSocketResponseEventDto = (event) => {
94
+ return isWebSocketResponseEventDto(event)
95
+ && event?.event === WebSocketResponseEvent.CODE_RUN_STATUS
96
+ && typeof event?.runId === 'string' && !!event.runId
97
+ && event?.status in SubmissionRunStatus;
98
+ };
99
+ export const isSubmissionRunStatusMessageWebSocketResponseEventDto = (event) => {
100
+ return isWebSocketResponseEventDto(event)
101
+ && event?.event === WebSocketResponseEvent.SUBMISSION_RUN_STATUS
102
+ && typeof event?.submitId === 'string' && !!event.submitId
103
+ && event?.status in SubmissionRunStatus
104
+ && event?.verdict in ProblemVerdict
105
+ && typeof event?.points === 'number';
106
+ };
107
+ export const isSubmissionJudgingWebSocketResponseEventDto = (event) => {
108
+ return isWebSocketResponseEventDto(event)
109
+ && event?.event === WebSocketResponseEvent.SUBMISSION_JUDGING
110
+ && isNonEmptyString(event?.submitId)
111
+ && isNonEmptyString(event?.problemKey)
112
+ && (event?.contestKey === null || isNonEmptyString(event?.contestKey))
113
+ && isNonEmptyString(event?.userKey)
114
+ && typeof event?.judging === 'boolean'
115
+ && event?.status in SubmissionRunStatus
116
+ && event?.verdict in ProblemVerdict
117
+ && typeof event?.points === 'number';
118
+ };
119
+ export const isUserMessageWebSocketResponseEventDto = (event) => {
120
+ return isWebSocketResponseEventDto(event)
121
+ && event?.event === WebSocketResponseEvent.USER_MESSAGE
122
+ && typeof event?.user?.nickname === 'string' && !!event.user?.nickname
123
+ && typeof event?.user?.imageUrl === 'string' && !!event.user?.imageUrl
124
+ && typeof event?.user?.organization?.key === 'string' && !!event.user?.organization?.key
125
+ && !!event?.content;
126
+ };
127
+ export const isSendDataWebSocketResponseEventDto = (event) => {
128
+ return [
129
+ WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST,
130
+ WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST,
131
+ WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST,
132
+ WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST,
133
+ WebSocketResponseEvent.SEND_DATA_RUN_COMMAND,
134
+ ].includes(event?.event)
135
+ && typeof event?.dataId === 'string' && !!event.dataId
136
+ && !!event?.content;
137
+ };
138
+ export const isSendDataEcsTaskDefinitionListWebSocketResponseEventDto = (event) => {
139
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
140
+ && event?.event === WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST;
141
+ };
142
+ export const isSendDataEc2InstancesListWebSocketResponseEventDto = (event) => {
143
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
144
+ && event?.event === WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST;
145
+ };
146
+ export const isSendDataEcsTasksListWebSocketResponseEventDto = (event) => {
147
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
148
+ && event?.event === WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST;
149
+ };
150
+ export const isSendDataSsmSessionsListWebSocketResponseEventDto = (event) => {
151
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
152
+ && event?.event === WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST;
153
+ };
154
+ export const isSendDataRunCommandWebSocketResponseEventDto = (event) => {
155
+ return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
156
+ && event?.event === WebSocketResponseEvent.SEND_DATA_RUN_COMMAND;
157
+ };
158
+ export const isProblemCrawledWebSocketResponseEventDto = (event) => {
159
+ return isWebSocketResponseEventDto(event)
160
+ && event?.event === WebSocketResponseEvent.PROBLEM_CRAWLED
161
+ && !!event?.content;
162
+ };
163
+ export const isSubmissionsCrawlWebSocketResponseEventDto = (event) => {
164
+ return isWebSocketResponseEventDto(event)
165
+ && event?.event === WebSocketResponseEvent.SUBMISSIONS_CRAWL
166
+ && !!event?.content;
167
+ };
168
+ export const isContestChangesWebSocketResponseEventDto = (event) => {
169
+ return isWebSocketResponseEventDto(event)
170
+ && event?.event === WebSocketResponseEvent.CONTEST_CHANGES
171
+ && !!event?.content;
172
+ };
173
+ export const isUserNotificationWebSocketResponseEventDto = (event) => {
174
+ return [
175
+ WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION,
176
+ WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION,
177
+ ].includes(event?.event)
178
+ && !!event?.content;
179
+ };
180
+ export const isUserNotificationSubmissionWebSocketResponseEventDto = (event) => {
181
+ return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
182
+ && event?.event === WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION;
183
+ };
184
+ export const isUserNotificationContestClarificationWebSocketResponseEventDto = (event) => {
185
+ return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
186
+ && event?.event === WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION;
187
+ };
188
+ // generic
189
+ export const getWebSocketResponseEventKey = (event, clientId, id) => {
190
+ return `${event}-${clientId}-${id}`;
191
+ };
192
+ export const isWebSocketChannelsMessageDto = (message) => {
193
+ return Array.isArray(message?.channels)
194
+ && message.channels.every((channel) => typeof channel === 'string' && !!channel)
195
+ && Object.values(WebSocketResponseEvent).includes(message?.event?.event);
196
+ };
197
+ /**
198
+ * Key used by the client to dispatch a response received on a TOPIC channel to its subscribers.
199
+ * It is the same key that `getKeyWebSocketEventDto` (base-ui) computes for the subscription.
200
+ * Returns null when the response is not addressed to this client.
201
+ */
202
+ export const getWebSocketResponseEventKeyOfResponse = (response, clientId) => {
203
+ if (isCodeRunStatusMessageWebSocketResponseEventDto(response)) {
204
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.CODE_RUN_STATUS, clientId, response.runId);
205
+ }
206
+ if (isSubmissionRunStatusMessageWebSocketResponseEventDto(response)) {
207
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSION_RUN_STATUS, clientId, response.submitId);
208
+ }
209
+ if (isSendDataWebSocketResponseEventDto(response)) {
210
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.SEND_DATA_, clientId, response.dataId);
211
+ }
212
+ if (isContestChangesWebSocketResponseEventDto(response)) {
213
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.CONTEST_CHANGES, clientId, response.content.contestKey);
214
+ }
215
+ if (isProblemCrawledWebSocketResponseEventDto(response)) {
216
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.PROBLEM_CRAWLED, clientId, response.content.problemKey);
217
+ }
218
+ if (isSubmissionsCrawlWebSocketResponseEventDto(response)) {
219
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSIONS_CRAWL, clientId, join([response.content.contestKey, response.content.problemKeys]));
220
+ }
221
+ if (isUserNotificationWebSocketResponseEventDto(response)) {
222
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.USER_NOTIFICATION_, clientId, '*');
223
+ }
224
+ if (isSubmissionJudgingWebSocketResponseEventDto(response)) {
225
+ // one key for every table: the same event is published on several channels (problem / contest / user) and the
226
+ // client deduplicates it, so it is dispatched once; each table filters by the submissions it lists
227
+ return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSION_JUDGING, clientId, '*');
228
+ }
229
+ return null;
230
+ };
231
+ /**
232
+ * TOPIC channel that the client has to attach to receive the events of a subscription,
233
+ * or null when the events arrive by the private channels (session / user) the client is always attached to.
234
+ * Ably rejects the attach if the token has no capability for the channel.
235
+ */
236
+ export const getChannelOfWebSocketSubscribeEvent = (event) => {
237
+ if (isSubscribeSubmissionRunStatusWebSocketEventDto(event)) {
238
+ return CHANNEL_SUBMISSION(event.submitId);
239
+ }
240
+ // SUBSCRIBE_PROBLEM_CRAWLED: the event arrives by the private user channel of who requested the crawl
241
+ if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
242
+ return CHANNEL_CONTEST(event.contestKey, ContestChannelRole.SPECTATORS);
243
+ }
244
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event)) {
245
+ // the judging start/end is published on the spectators channel when it is visible to everyone; the hidden ones
246
+ // (frozen / quiet contests) arrive by the role channels of the contest (managers) and the private user channel
247
+ if ('problemKey' in event && event.problemKey) {
248
+ return CHANNEL_PROBLEM(event.problemKey, ProblemChannelRole.SPECTATORS);
249
+ }
250
+ if ('contestKey' in event && event.contestKey) {
251
+ return CHANNEL_CONTEST(event.contestKey, ContestChannelRole.SPECTATORS);
252
+ }
253
+ if ('userKey' in event && event.userKey) {
254
+ return CHANNEL_USER_ROLE(event.userKey, UserChannelRole.SPECTATORS);
255
+ }
256
+ }
257
+ return null;
258
+ };
259
+ /**
260
+ * Contest whose role channels the client needs (the API grants them when the token is requested with this contest).
261
+ */
262
+ export const getContestKeyOfWebSocketSubscribeEvent = (event) => {
263
+ if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
264
+ return event.contestKey;
265
+ }
266
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'contestKey' in event && event.contestKey) {
267
+ return event.contestKey;
268
+ }
269
+ return null;
270
+ };
271
+ /**
272
+ * Problem whose role channels the client needs (the API grants them when the token is requested with this problem).
273
+ */
274
+ export const getProblemKeyOfWebSocketSubscribeEvent = (event) => {
275
+ if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'problemKey' in event && event.problemKey) {
276
+ return event.problemKey;
277
+ }
278
+ return null;
279
+ };
@@ -1,2 +1,2 @@
1
- import { SplitTime } from '../types';
1
+ import { SplitTime } from '../types/index.js';
2
2
  export declare function splitTime(timeRemaining: number): [SplitTime, SplitTime, SplitTime, SplitTime, SplitTime, SplitTime];