@oneuptime/common 9.2.16 → 9.2.18

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 (133) hide show
  1. package/Models/DatabaseModels/CodeRepository.ts +664 -0
  2. package/Models/DatabaseModels/Index.ts +8 -0
  3. package/Models/DatabaseModels/LlmLog.ts +818 -0
  4. package/Models/DatabaseModels/LlmProvider.ts +21 -0
  5. package/Models/DatabaseModels/Project.ts +206 -0
  6. package/Models/DatabaseModels/ServiceCatalogCodeRepository.ts +549 -0
  7. package/Server/API/AIBillingAPI.ts +126 -0
  8. package/Server/API/AlertAPI.ts +139 -0
  9. package/Server/API/GitHubAPI.ts +360 -0
  10. package/Server/API/IncidentAPI.ts +258 -0
  11. package/Server/API/ScheduledMaintenanceAPI.ts +164 -0
  12. package/Server/EnvironmentConfig.ts +44 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1765580181582-MigrationName.ts +79 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1765633554715-MigrationName.ts +75 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1765801357168-MigrationName.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1765810218488-MigrationName.ts +69 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1765830758857-MigrationName.ts +111 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1765834537501-MigrationName.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  20. package/Server/Services/AIBillingService.ts +247 -0
  21. package/Server/Services/AIService.ts +238 -0
  22. package/Server/Services/CodeRepositoryService.ts +10 -0
  23. package/Server/Services/IncidentService.ts +88 -0
  24. package/Server/Services/Index.ts +2 -0
  25. package/Server/Services/LlmLogService.ts +14 -0
  26. package/Server/Services/LlmProviderService.ts +58 -0
  27. package/Server/Services/ServiceCatalogCodeRepositoryService.ts +55 -0
  28. package/Server/Utils/AI/AlertAIContextBuilder.ts +264 -0
  29. package/Server/Utils/AI/IncidentAIContextBuilder.ts +710 -0
  30. package/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.ts +345 -0
  31. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +226 -0
  32. package/Server/Utils/LLM/LLMService.ts +276 -0
  33. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +166 -0
  34. package/Server/Utils/Workspace/Slack/Slack.ts +134 -0
  35. package/Server/Utils/Workspace/Workspace.ts +126 -0
  36. package/Tests/Types/Domain.test.ts +24 -3
  37. package/Types/CodeRepository/CodeRepositoryType.ts +1 -1
  38. package/Types/Domain.ts +21 -24
  39. package/Types/LlmLogStatus.ts +7 -0
  40. package/Types/Permission.ts +87 -0
  41. package/Types/ServiceCatalog/CodeRepositoryImprovementAction.ts +9 -0
  42. package/UI/Components/AI/AILoader.tsx +95 -0
  43. package/UI/Components/AI/GenerateFromAIModal.tsx +432 -0
  44. package/UI/Components/Modal/Modal.tsx +6 -1
  45. package/build/dist/Models/DatabaseModels/CodeRepository.js +689 -0
  46. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -0
  47. package/build/dist/Models/DatabaseModels/Index.js +7 -0
  48. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  49. package/build/dist/Models/DatabaseModels/LlmLog.js +856 -0
  50. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -0
  51. package/build/dist/Models/DatabaseModels/LlmProvider.js +22 -0
  52. package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
  53. package/build/dist/Models/DatabaseModels/Project.js +220 -0
  54. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  55. package/build/dist/Models/DatabaseModels/ServiceCatalogCodeRepository.js +565 -0
  56. package/build/dist/Models/DatabaseModels/ServiceCatalogCodeRepository.js.map +1 -0
  57. package/build/dist/Server/API/AIBillingAPI.js +58 -0
  58. package/build/dist/Server/API/AIBillingAPI.js.map +1 -0
  59. package/build/dist/Server/API/AlertAPI.js +94 -0
  60. package/build/dist/Server/API/AlertAPI.js.map +1 -0
  61. package/build/dist/Server/API/GitHubAPI.js +207 -0
  62. package/build/dist/Server/API/GitHubAPI.js.map +1 -0
  63. package/build/dist/Server/API/IncidentAPI.js +171 -1
  64. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  65. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +103 -0
  66. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -0
  67. package/build/dist/Server/EnvironmentConfig.js +31 -0
  68. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  69. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765580181582-MigrationName.js +34 -0
  70. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765580181582-MigrationName.js.map +1 -0
  71. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765633554715-MigrationName.js +32 -0
  72. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765633554715-MigrationName.js.map +1 -0
  73. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765801357168-MigrationName.js +38 -0
  74. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765801357168-MigrationName.js.map +1 -0
  75. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765810218488-MigrationName.js +30 -0
  76. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765810218488-MigrationName.js.map +1 -0
  77. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765830758857-MigrationName.js +44 -0
  78. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765830758857-MigrationName.js.map +1 -0
  79. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765834537501-MigrationName.js +22 -0
  80. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1765834537501-MigrationName.js.map +1 -0
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  83. package/build/dist/Server/Services/AIBillingService.js +187 -0
  84. package/build/dist/Server/Services/AIBillingService.js.map +1 -0
  85. package/build/dist/Server/Services/AIService.js +184 -0
  86. package/build/dist/Server/Services/AIService.js.map +1 -0
  87. package/build/dist/Server/Services/CodeRepositoryService.js +9 -0
  88. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -0
  89. package/build/dist/Server/Services/IncidentService.js +60 -0
  90. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  91. package/build/dist/Server/Services/Index.js +2 -0
  92. package/build/dist/Server/Services/Index.js.map +1 -1
  93. package/build/dist/Server/Services/LlmLogService.js +13 -0
  94. package/build/dist/Server/Services/LlmLogService.js.map +1 -0
  95. package/build/dist/Server/Services/LlmProviderService.js +65 -0
  96. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  97. package/build/dist/Server/Services/ServiceCatalogCodeRepositoryService.js +54 -0
  98. package/build/dist/Server/Services/ServiceCatalogCodeRepositoryService.js.map +1 -0
  99. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +238 -0
  100. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -0
  101. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +597 -0
  102. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -0
  103. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js +311 -0
  104. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js.map +1 -0
  105. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +163 -0
  106. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  107. package/build/dist/Server/Utils/LLM/LLMService.js +225 -0
  108. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -0
  109. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +110 -0
  110. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  111. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +89 -0
  112. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  113. package/build/dist/Server/Utils/Workspace/Workspace.js +80 -0
  114. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
  115. package/build/dist/Tests/Types/Domain.test.js +19 -3
  116. package/build/dist/Tests/Types/Domain.test.js.map +1 -1
  117. package/build/dist/Types/CodeRepository/CodeRepositoryType.js +1 -1
  118. package/build/dist/Types/CodeRepository/CodeRepositoryType.js.map +1 -1
  119. package/build/dist/Types/Domain.js +18 -16
  120. package/build/dist/Types/Domain.js.map +1 -1
  121. package/build/dist/Types/LlmLogStatus.js +8 -0
  122. package/build/dist/Types/LlmLogStatus.js.map +1 -0
  123. package/build/dist/Types/Permission.js +74 -0
  124. package/build/dist/Types/Permission.js.map +1 -1
  125. package/build/dist/Types/ServiceCatalog/CodeRepositoryImprovementAction.js +10 -0
  126. package/build/dist/Types/ServiceCatalog/CodeRepositoryImprovementAction.js.map +1 -0
  127. package/build/dist/UI/Components/AI/AILoader.js +64 -0
  128. package/build/dist/UI/Components/AI/AILoader.js.map +1 -0
  129. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +320 -0
  130. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -0
  131. package/build/dist/UI/Components/Modal/Modal.js +6 -1
  132. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  133. package/package.json +1 -1
@@ -17,6 +17,16 @@ import WorkspaceUserAuthToken from "../../../Models/DatabaseModels/WorkspaceUser
17
17
  import WorkspaceUserAuthTokenService from "../../Services/WorkspaceUserAuthTokenService";
18
18
  import UserService from "../../Services/UserService";
19
19
  import CaptureSpan from "../Telemetry/CaptureSpan";
20
+ import OneUptimeDate from "../../../Types/Date";
21
+
22
+ export interface WorkspaceChannelMessage {
23
+ messageId: string;
24
+ text: string;
25
+ userId?: string;
26
+ username?: string;
27
+ timestamp: Date;
28
+ isBot: boolean;
29
+ }
20
30
 
21
31
  export default class WorkspaceUtil {
22
32
  @CaptureSpan()
@@ -236,4 +246,120 @@ export default class WorkspaceUtil {
236
246
 
237
247
  return result;
238
248
  }
249
+
250
+ @CaptureSpan()
251
+ public static async getChannelMessages(params: {
252
+ channelId: string;
253
+ authToken: string;
254
+ projectId: ObjectID;
255
+ workspaceType: WorkspaceType;
256
+ teamId?: string;
257
+ limit?: number;
258
+ oldestTimestamp?: Date;
259
+ }): Promise<Array<WorkspaceChannelMessage>> {
260
+ switch (params.workspaceType) {
261
+ case WorkspaceType.Slack: {
262
+ const slackParams: {
263
+ channelId: string;
264
+ authToken: string;
265
+ limit?: number;
266
+ oldestTimestamp?: Date;
267
+ } = {
268
+ channelId: params.channelId,
269
+ authToken: params.authToken,
270
+ };
271
+
272
+ if (params.limit !== undefined) {
273
+ slackParams.limit = params.limit;
274
+ }
275
+
276
+ if (params.oldestTimestamp) {
277
+ slackParams.oldestTimestamp = params.oldestTimestamp;
278
+ }
279
+
280
+ return await SlackWorkspace.getChannelMessages(slackParams);
281
+ }
282
+ case WorkspaceType.MicrosoftTeams: {
283
+ if (!params.teamId) {
284
+ logger.error(
285
+ "Team ID is required for Microsoft Teams channel messages",
286
+ );
287
+ return [];
288
+ }
289
+
290
+ const teamsParams: {
291
+ channelId: string;
292
+ teamId: string;
293
+ projectId: ObjectID;
294
+ limit?: number;
295
+ oldestTimestamp?: Date;
296
+ } = {
297
+ channelId: params.channelId,
298
+ teamId: params.teamId,
299
+ projectId: params.projectId,
300
+ };
301
+
302
+ if (params.limit !== undefined) {
303
+ teamsParams.limit = params.limit;
304
+ }
305
+
306
+ if (params.oldestTimestamp) {
307
+ teamsParams.oldestTimestamp = params.oldestTimestamp;
308
+ }
309
+
310
+ return await MicrosoftTeamsUtil.getChannelMessages(teamsParams);
311
+ }
312
+ default:
313
+ logger.debug(
314
+ `Unsupported workspace type for channel messages: ${params.workspaceType}`,
315
+ );
316
+ return [];
317
+ }
318
+ }
319
+
320
+ @CaptureSpan()
321
+ public static formatMessagesAsContext(
322
+ messages: Array<WorkspaceChannelMessage>,
323
+ options?: {
324
+ includeTimestamp?: boolean;
325
+ includeUsername?: boolean;
326
+ maxLength?: number;
327
+ },
328
+ ): string {
329
+ const includeTimestamp: boolean = options?.includeTimestamp ?? true;
330
+ const includeUsername: boolean = options?.includeUsername ?? true;
331
+ const maxLength: number = options?.maxLength || 50000;
332
+
333
+ let context: string = "";
334
+
335
+ for (const msg of messages) {
336
+ let line: string = "";
337
+
338
+ if (includeTimestamp) {
339
+ const dateStr: string = OneUptimeDate.getDateAsFormattedString(
340
+ msg.timestamp,
341
+ );
342
+ line += `[${dateStr}] `;
343
+ }
344
+
345
+ if (includeUsername && msg.username) {
346
+ line += `${msg.username}: `;
347
+ } else if (includeUsername && msg.userId) {
348
+ line += `User ${msg.userId}: `;
349
+ }
350
+
351
+ line += msg.text;
352
+ line += "\n";
353
+
354
+ // Check if adding this line would exceed max length
355
+ if (context.length + line.length > maxLength) {
356
+ context += "\n... (messages truncated due to length)";
357
+ break;
358
+ }
359
+
360
+ context += line;
361
+ }
362
+
363
+ return context.trim();
364
+ }
239
365
  }
@@ -13,22 +13,43 @@ describe("class Domain", () => {
13
13
  expect(new Domain("example.ac").domain).toBe("example.ac");
14
14
  });
15
15
  test("new Domain() should throw the BadDataException if domain is invalid", () => {
16
+ // No dot in domain
16
17
  expect(() => {
17
18
  return new Domain("example");
18
19
  }).toThrowError(BadDataException);
19
20
  expect(() => {
20
21
  new Domain("example");
21
22
  }).toThrowError(BadDataException);
23
+
24
+ // Invalid characters
22
25
  expect(() => {
23
26
  new Domain("example@com");
24
27
  }).toThrowError(BadDataException);
25
28
 
29
+ // TLD with numbers (invalid - TLD must be letters only)
30
+ expect(() => {
31
+ new Domain("example.c0m");
32
+ }).toThrowError(BadDataException);
33
+
34
+ // Single letter TLD (invalid - TLD must be at least 2 characters)
26
35
  expect(() => {
27
- new Domain("example.invalid");
36
+ new Domain("example.c");
28
37
  }).toThrowError(BadDataException);
38
+
39
+ // Domain starting with hyphen
40
+ expect(() => {
41
+ new Domain("-example.com");
42
+ }).toThrowError(BadDataException);
43
+
44
+ // Domain ending with hyphen before TLD
45
+ expect(() => {
46
+ new Domain("example-.com");
47
+ }).toThrowError(BadDataException);
48
+
49
+ // Mutation to invalid domain
29
50
  expect(() => {
30
- const validDomain: Domain = new Domain("example.valid");
31
- validDomain.domain = "example.invalid";
51
+ const validDomain: Domain = new Domain("example.com");
52
+ validDomain.domain = "invalid";
32
53
  }).toThrowError(BadDataException);
33
54
  });
34
55
  test("Domain.domain should be mutable", () => {
@@ -1,6 +1,6 @@
1
1
  enum CodeRepositoryType {
2
2
  GitHub = "GitHub",
3
- // GitLab = 'GitLab',
3
+ GitLab = "GitLab",
4
4
  }
5
5
 
6
6
  export default CodeRepositoryType;
package/Types/Domain.ts CHANGED
@@ -18,33 +18,30 @@ export default class Domain extends DatabaseProperty {
18
18
  }
19
19
 
20
20
  public static isValidDomain(domain: string): boolean {
21
- if (!domain.includes(".")) {
21
+ /*
22
+ * Regex-based domain validation
23
+ * - Each label (part between dots) must be 1-63 characters
24
+ * - Labels can contain alphanumeric characters and hyphens
25
+ * - Labels cannot start or end with a hyphen
26
+ * - TLD must be at least 2 characters and contain only letters
27
+ * - Total length should not exceed 253 characters
28
+ */
29
+
30
+ if (!domain || domain.length > 253) {
22
31
  return false;
23
32
  }
24
33
 
25
- const firstTLDs: Array<string> =
26
- "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|be|bf|bg|bh|bi|bj|bm|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|cr|cu|cv|cw|cx|cz|de|dj|dk|dm|do|dz|ec|ee|eg|es|et|eu|fi|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|im|in|io|iq|ir|is|it|je|jo|jp|kg|ki|km|kn|kp|kr|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|na|nc|ne|nf|ng|nl|no|nr|nu|nz|om|pa|pe|pf|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|yt".split(
27
- "|",
28
- );
29
- const secondTLDs: Array<string> =
30
- "ac|academy|accountant|accountants|actor|adult|aero|ag|agency|ai|airforce|am|amsterdam|apartments|app|archi|army|art|asia|associates|at|attorney|au|auction|auto|autos|baby|band|bar|barcelona|bargains|basketball|bayern|be|beauty|beer|berlin|best|bet|bid|bike|bingo|bio|biz|biz.pl|black|blog|blue|boats|boston|boutique|broker|build|builders|business|buzz|bz|ca|cab|cafe|camera|camp|capital|car|cards|care|careers|cars|casa|cash|casino|catering|cc|center|ceo|ch|charity|chat|cheap|church|city|cl|claims|cleaning|clinic|clothing|cloud|club|cn|co|co.in|co.jp|co.kr|co.nz|co.uk|co.za|coach|codes|coffee|college|com|com.ag|com.au|com.br|com.bz|com.cn|com.co|com.es|com.ky|com.mx|com.pe|com.ph|com.pl|com.ru|com.tw|community|company|computer|condos|construction|consulting|contact|contractors|cooking|cool|country|coupons|courses|credit|creditcard|cricket|cruises|cymru|cz|dance|date|dating|de|deals|degree|delivery|democrat|dental|dentist|design|dev|diamonds|digital|direct|directory|discount|dk|doctor|dog|domains|download|earth|education|email|energy|engineer|engineering|enterprises|equipment|es|estate|eu|events|exchange|expert|exposed|express|fail|faith|family|fan|fans|farm|fashion|film|finance|financial|firm.in|fish|fishing|fit|fitness|flights|florist|fm|football|forsale|foundation|fr|fun|fund|furniture|futbol|fyi|gallery|games|garden|gay|gen.in|gg|gifts|gives|giving|glass|global|gmbh|gold|golf|graphics|gratis|green|gripe|group|gs|guide|guru|hair|haus|health|healthcare|hockey|holdings|holiday|homes|horse|hospital|host|house|idv.tw|immo|immobilien|in|inc|ind.in|industries|info|info.pl|ink|institute|insure|international|investments|io|irish|ist|istanbul|it|jetzt|jewelry|jobs|jp|kaufen|kids|kim|kitchen|kiwi|kr|ky|la|land|lat|law|lawyer|lease|legal|lgbt|life|lighting|limited|limo|live|llc|llp|loan|loans|london|love|ltd|ltda|luxury|maison|makeup|management|market|marketing|mba|me|me.uk|media|melbourne|memorial|men|menu|miami|mobi|moda|moe|money|monster|mortgage|motorcycles|movie|ms|music|mx|nagoya|name|navy|ne.kr|net|net.ag|net.au|net.br|net.bz|net.cn|net.co|net.in|net.ky|net.nz|net.pe|net.ph|net.pl|net.ru|network|news|ninja|nl|no|nom.co|nom.es|nom.pe|nrw|nyc|okinawa|one|onl|online|org|org.ag|org.au|org.cn|org.es|org.in|org.ky|org.nz|org.pe|org.ph|org.pl|org.ru|org.uk|organic|page|paris|partners|parts|party|pe|pet|ph|photography|photos|pictures|pink|pizza|pl|place|plumbing|plus|poker|porn|press|pro|productions|promo|properties|protection|pub|pw|quebec|quest|racing|re.kr|realestate|recipes|red|rehab|reise|reisen|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rich|rip|rocks|rodeo|rugby|run|ryukyu|sale|salon|sarl|school|schule|science|se|security|services|sex|sg|sh|shiksha|shoes|shop|shopping|show|singles|site|ski|skin|soccer|social|software|solar|solutions|space|storage|store|stream|studio|study|style|supplies|supply|support|surf|surgery|sydney|systems|tax|taxi|team|tech|technology|tel|tennis|theater|theatre|tickets|tienda|tips|tires|today|tokyo|tools|tours|town|toys|trade|trading|training|travel|tube|tv|tw|uk|university|uno|us|vacations|vc|vegas|ventures|vet|viajes|video|villas|vin|vip|vision|vodka|vote|voto|voyage|wales|watch|web|webcam|website|wedding|wiki|win|wine|work|works|world|ws|wtf|xxx|xyz|yachts|yoga|yokohama|zone|移动|dev|com|edu|gov|net|mil|org|nom|sch|sbs|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc|za|ovh|lol|africa|top|coop".split(
31
- "|",
32
- );
33
-
34
- const parts: Array<string> = domain.split(".");
35
- const lastItem: string = parts[parts.length - 1] as string;
36
- const beforeLastItem: string = parts[parts.length - 2] as string;
37
-
38
- if (firstTLDs.includes(lastItem)) {
39
- if (secondTLDs.includes(beforeLastItem)) {
40
- return true;
41
- }
42
- return true;
43
- } else if (secondTLDs.includes(lastItem)) {
44
- return true;
45
- }
46
-
47
- return false;
34
+ /*
35
+ * Domain validation regex:
36
+ * ^ - start of string
37
+ * (?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+ - one or more labels followed by dot
38
+ * [a-zA-Z]{2,63} - TLD: 2-63 letters only
39
+ * $ - end of string
40
+ */
41
+ const domainRegex: RegExp =
42
+ /^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,63}$/;
43
+
44
+ return domainRegex.test(domain);
48
45
  }
49
46
 
50
47
  public constructor(domain: string) {
@@ -0,0 +1,7 @@
1
+ enum LlmLogStatus {
2
+ Success = "Success",
3
+ Error = "Error",
4
+ InsufficientBalance = "Insufficient Balance",
5
+ }
6
+
7
+ export default LlmLogStatus;
@@ -147,6 +147,7 @@ enum Permission {
147
147
  ReadCallLog = "ReadCallLog",
148
148
  ReadPushLog = "ReadPushLog",
149
149
  ReadWorkspaceNotificationLog = "ReadWorkspaceNotificationLog",
150
+ ReadLlmLog = "ReadLlmLog",
150
151
 
151
152
  CreateIncidentOwnerTeam = "CreateIncidentOwnerTeam",
152
153
  DeleteIncidentOwnerTeam = "DeleteIncidentOwnerTeam",
@@ -624,6 +625,17 @@ enum Permission {
624
625
  EditServiceCatalogTelemetryService = "EditServiceCatalogTelemetryService",
625
626
  ReadServiceCatalogTelemetryService = "ReadServiceCatalogTelemetryService",
626
627
 
628
+ CreateServiceCatalogCodeRepository = "CreateServiceCatalogCodeRepository",
629
+ DeleteServiceCatalogCodeRepository = "DeleteServiceCatalogCodeRepository",
630
+ EditServiceCatalogCodeRepository = "EditServiceCatalogCodeRepository",
631
+ ReadServiceCatalogCodeRepository = "ReadServiceCatalogCodeRepository",
632
+
633
+ // Code Repository
634
+ CreateCodeRepository = "CreateCodeRepository",
635
+ DeleteCodeRepository = "DeleteCodeRepository",
636
+ EditCodeRepository = "EditCodeRepository",
637
+ ReadCodeRepository = "ReadCodeRepository",
638
+
627
639
  CreateProbeOwnerTeam = "CreateProbeOwnerTeam",
628
640
  DeleteProbeOwnerTeam = "DeleteProbeOwnerTeam",
629
641
  EditProbeOwnerTeam = "EditProbeOwnerTeam",
@@ -3132,6 +3144,14 @@ export class PermissionHelper {
3132
3144
  isAccessControlPermission: false,
3133
3145
  },
3134
3146
 
3147
+ {
3148
+ permission: Permission.ReadLlmLog,
3149
+ title: "Read LLM Log",
3150
+ description: "This permission can read LLM Logs of this project.",
3151
+ isAssignableToTenant: true,
3152
+ isAccessControlPermission: false,
3153
+ },
3154
+
3135
3155
  {
3136
3156
  permission: Permission.CreateMonitorProbe,
3137
3157
  title: "Create Monitor Probe",
@@ -3417,6 +3437,73 @@ export class PermissionHelper {
3417
3437
  isAccessControlPermission: false,
3418
3438
  },
3419
3439
 
3440
+ {
3441
+ permission: Permission.CreateServiceCatalogCodeRepository,
3442
+ title: "Create Service Catalog Code Repository",
3443
+ description:
3444
+ "This permission can create Service Catalog Code Repository in this project.",
3445
+ isAssignableToTenant: true,
3446
+ isAccessControlPermission: false,
3447
+ },
3448
+ {
3449
+ permission: Permission.DeleteServiceCatalogCodeRepository,
3450
+ title: "Delete Service Catalog Code Repository",
3451
+ description:
3452
+ "This permission can delete Service Catalog Code Repository of this project.",
3453
+ isAssignableToTenant: true,
3454
+ isAccessControlPermission: false,
3455
+ },
3456
+ {
3457
+ permission: Permission.EditServiceCatalogCodeRepository,
3458
+ title: "Edit Service Catalog Code Repository",
3459
+ description:
3460
+ "This permission can edit Service Catalog Code Repository of this project.",
3461
+ isAssignableToTenant: true,
3462
+ isAccessControlPermission: false,
3463
+ },
3464
+ {
3465
+ permission: Permission.ReadServiceCatalogCodeRepository,
3466
+ title: "Read Service Catalog Code Repository",
3467
+ description:
3468
+ "This permission can read Service Catalog Code Repository of this project.",
3469
+ isAssignableToTenant: true,
3470
+ isAccessControlPermission: false,
3471
+ },
3472
+
3473
+ // Code Repository Permissions
3474
+ {
3475
+ permission: Permission.CreateCodeRepository,
3476
+ title: "Create Code Repository",
3477
+ description:
3478
+ "This permission can create Code Repositories in this project.",
3479
+ isAssignableToTenant: true,
3480
+ isAccessControlPermission: true,
3481
+ },
3482
+ {
3483
+ permission: Permission.DeleteCodeRepository,
3484
+ title: "Delete Code Repository",
3485
+ description:
3486
+ "This permission can delete Code Repositories of this project.",
3487
+ isAssignableToTenant: true,
3488
+ isAccessControlPermission: true,
3489
+ },
3490
+ {
3491
+ permission: Permission.EditCodeRepository,
3492
+ title: "Edit Code Repository",
3493
+ description:
3494
+ "This permission can edit Code Repositories of this project.",
3495
+ isAssignableToTenant: true,
3496
+ isAccessControlPermission: true,
3497
+ },
3498
+ {
3499
+ permission: Permission.ReadCodeRepository,
3500
+ title: "Read Code Repository",
3501
+ description:
3502
+ "This permission can read Code Repositories of this project.",
3503
+ isAssignableToTenant: true,
3504
+ isAccessControlPermission: true,
3505
+ },
3506
+
3420
3507
  {
3421
3508
  permission: Permission.CreateTelemetryServiceTraces,
3422
3509
  title: "Create Telemetry Service Traces",
@@ -0,0 +1,9 @@
1
+ enum CodeRepositoryImprovementAction {
2
+ FixExceptions = "Fix Exceptions",
3
+ ImproveLogs = "Improve Logs",
4
+ ImproveSpans = "Improve Spans",
5
+ ImproveMetrics = "Improve Metrics",
6
+ FixPerformanceIssues = "Fix Performance Issues",
7
+ }
8
+
9
+ export default CodeRepositoryImprovementAction;
@@ -0,0 +1,95 @@
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useEffect,
5
+ useState,
6
+ } from "react";
7
+
8
+ const loadingStages: Array<string> = ["Analyzing", "Processing", "Generating"];
9
+
10
+ const AILoader: FunctionComponent = (): ReactElement => {
11
+ const [stageIndex, setStageIndex] = useState<number>(0);
12
+ const [dots, setDots] = useState<string>("");
13
+
14
+ // Cycle through stages
15
+ useEffect(() => {
16
+ const interval: NodeJS.Timeout = setInterval(() => {
17
+ setStageIndex((prev: number) => {
18
+ return (prev + 1) % loadingStages.length;
19
+ });
20
+ }, 2500);
21
+
22
+ return () => {
23
+ clearInterval(interval);
24
+ };
25
+ }, []);
26
+
27
+ // Animate dots
28
+ useEffect(() => {
29
+ const interval: NodeJS.Timeout = setInterval(() => {
30
+ setDots((prev: string) => {
31
+ return prev.length >= 3 ? "" : prev + ".";
32
+ });
33
+ }, 400);
34
+
35
+ return () => {
36
+ clearInterval(interval);
37
+ };
38
+ }, []);
39
+
40
+ return (
41
+ <div className="py-8 px-4">
42
+ <div className="flex items-center justify-center gap-3">
43
+ {/* Pulsing AI indicator */}
44
+ <div className="relative">
45
+ <div
46
+ className="w-2 h-2 bg-indigo-600 rounded-full"
47
+ style={{
48
+ animation: "aiPulse 1.5s ease-in-out infinite",
49
+ }}
50
+ />
51
+ <div
52
+ className="absolute inset-0 w-2 h-2 bg-indigo-600 rounded-full"
53
+ style={{
54
+ animation: "aiPing 1.5s ease-out infinite",
55
+ }}
56
+ />
57
+ </div>
58
+
59
+ {/* Status text */}
60
+ <span className="text-sm text-gray-600 font-medium min-w-[100px]">
61
+ {loadingStages[stageIndex]}
62
+ <span className="inline-block w-4 text-left">{dots}</span>
63
+ </span>
64
+ </div>
65
+
66
+ {/* CSS for animations */}
67
+ <style>
68
+ {`
69
+ @keyframes aiPulse {
70
+ 0%, 100% {
71
+ opacity: 1;
72
+ transform: scale(1);
73
+ }
74
+ 50% {
75
+ opacity: 0.7;
76
+ transform: scale(1.1);
77
+ }
78
+ }
79
+ @keyframes aiPing {
80
+ 0% {
81
+ opacity: 0.6;
82
+ transform: scale(1);
83
+ }
84
+ 100% {
85
+ opacity: 0;
86
+ transform: scale(2.5);
87
+ }
88
+ }
89
+ `}
90
+ </style>
91
+ </div>
92
+ );
93
+ };
94
+
95
+ export default AILoader;