@abyss-project/console 1.0.73 → 1.0.76

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 (58) hide show
  1. package/dist/api/index.d.ts +1 -0
  2. package/dist/api/index.js +1 -0
  3. package/dist/api/internal-ticket-config.api.d.ts +10 -7
  4. package/dist/api/internal-ticket-config.api.js +42 -27
  5. package/dist/api/internal-ticket.api.d.ts +12 -5
  6. package/dist/api/internal-ticket.api.js +54 -19
  7. package/dist/api/report.admin.api.d.ts +5 -1
  8. package/dist/api/report.admin.api.js +11 -1
  9. package/dist/api/system-setting.admin.api.d.ts +4 -0
  10. package/dist/api/system-setting.admin.api.js +19 -0
  11. package/dist/index.d.ts +36 -10
  12. package/dist/index.js +37 -10
  13. package/dist/types/constants/index.d.ts +1 -0
  14. package/dist/types/constants/index.js +1 -0
  15. package/dist/types/constants/internal-ticket.constants.d.ts +3 -0
  16. package/dist/types/constants/internal-ticket.constants.js +6 -0
  17. package/dist/types/enum/internal-ticket.enum.d.ts +27 -5
  18. package/dist/types/enum/internal-ticket.enum.js +26 -3
  19. package/dist/types/interface/api/index.d.ts +2 -0
  20. package/dist/types/interface/api/index.js +2 -0
  21. package/dist/types/interface/api/requests/internal-ticket-config.request.d.ts +92 -29
  22. package/dist/types/interface/api/requests/internal-ticket.request.d.ts +67 -22
  23. package/dist/types/interface/api/requests/report.admin.request.d.ts +5 -0
  24. package/dist/types/interface/api/requests/system-setting.admin.request.d.ts +3 -0
  25. package/dist/types/interface/api/requests/system-setting.admin.request.js +2 -0
  26. package/dist/types/interface/api/responses/internal-ticket-config.response.d.ts +36 -24
  27. package/dist/types/interface/api/responses/internal-ticket.response.d.ts +50 -20
  28. package/dist/types/interface/api/responses/report.admin.response.d.ts +21 -0
  29. package/dist/types/interface/api/responses/system-setting.admin.response.d.ts +16 -0
  30. package/dist/types/interface/api/responses/system-setting.admin.response.js +2 -0
  31. package/dist/types/interface/index.d.ts +6 -0
  32. package/dist/types/interface/index.js +6 -0
  33. package/dist/types/interface/models/internal-ticket-artifact-rule.model.d.ts +9 -0
  34. package/dist/types/interface/models/internal-ticket-artifact-rule.model.js +2 -0
  35. package/dist/types/interface/models/internal-ticket-artifact-type.model.d.ts +16 -0
  36. package/dist/types/interface/models/internal-ticket-artifact-type.model.js +2 -0
  37. package/dist/types/interface/models/internal-ticket-artifact.model.d.ts +11 -0
  38. package/dist/types/interface/models/internal-ticket-artifact.model.js +2 -0
  39. package/dist/types/interface/models/internal-ticket-category.model.d.ts +1 -2
  40. package/dist/types/interface/models/internal-ticket-message.model.d.ts +0 -1
  41. package/dist/types/interface/models/internal-ticket-priority.model.d.ts +3 -5
  42. package/dist/types/interface/models/internal-ticket-section.model.d.ts +4 -0
  43. package/dist/types/interface/models/internal-ticket-tag.model.d.ts +14 -0
  44. package/dist/types/interface/models/internal-ticket-tag.model.js +2 -0
  45. package/dist/types/interface/models/internal-ticket-ticket-tag.model.d.ts +9 -0
  46. package/dist/types/interface/models/internal-ticket-ticket-tag.model.js +2 -0
  47. package/dist/types/interface/models/internal-ticket.model.d.ts +9 -3
  48. package/dist/types/interface/models/system-setting.model.d.ts +8 -0
  49. package/dist/types/interface/models/system-setting.model.js +2 -0
  50. package/dist/utils/index.d.ts +2 -0
  51. package/dist/utils/index.js +2 -0
  52. package/dist/utils/internal-ticket-status.utils.d.ts +9 -0
  53. package/dist/utils/internal-ticket-status.utils.js +25 -0
  54. package/dist/utils/mention.utils.d.ts +3 -0
  55. package/dist/utils/mention.utils.js +21 -0
  56. package/package.json +3 -1
  57. package/dist/utils/reference-resolver.utils.d.ts +0 -52
  58. package/dist/utils/reference-resolver.utils.js +0 -219
@@ -6,6 +6,26 @@ export interface WorkflowExecutionsByPeriod {
6
6
  failed: number;
7
7
  cancelled: number;
8
8
  }
9
+ export interface InternalTicketReportMetrics {
10
+ total: number;
11
+ waitingReview: number;
12
+ waitingAssignee: number;
13
+ inProgress: number;
14
+ resolved: number;
15
+ closed: number;
16
+ archived: number;
17
+ avgResolutionMs: number | null;
18
+ ticketsBySection: Array<{
19
+ sectionId: string;
20
+ sectionName: string;
21
+ count: number;
22
+ }>;
23
+ ticketsByPriority: Array<{
24
+ priorityId: string;
25
+ priorityName: string;
26
+ count: number;
27
+ }>;
28
+ }
9
29
  export interface WorkflowReportMetrics {
10
30
  totalWorkflows: number;
11
31
  activeWorkflows: number;
@@ -75,6 +95,7 @@ export interface WorkflowReportMetrics {
75
95
  total: number;
76
96
  verified: number;
77
97
  };
98
+ internalTicketMetrics: InternalTicketReportMetrics;
78
99
  }
79
100
  export interface GetReportAdminResponse {
80
101
  data: {
@@ -0,0 +1,16 @@
1
+ import { ISystemSetting } from '../../models/system-setting.model';
2
+ export interface GetSystemSettingAdminResponse {
3
+ data: {
4
+ systemSetting: ISystemSetting;
5
+ };
6
+ }
7
+ export interface ListSystemSettingsAdminResponse {
8
+ data: {
9
+ systemSettings: ISystemSetting[];
10
+ };
11
+ }
12
+ export interface UpdateSystemSettingAdminResponse {
13
+ data: {
14
+ systemSetting: ISystemSetting;
15
+ };
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -30,3 +30,9 @@ export * from './models/internal-ticket-activity.model';
30
30
  export * from './models/internal-ticket-follower.model';
31
31
  export * from './models/internal-ticket-section.model';
32
32
  export * from './models/internal-ticket-assignee.model';
33
+ export * from './models/internal-ticket-tag.model';
34
+ export * from './models/internal-ticket-ticket-tag.model';
35
+ export * from './models/internal-ticket-artifact-type.model';
36
+ export * from './models/internal-ticket-artifact-rule.model';
37
+ export * from './models/internal-ticket-artifact.model';
38
+ export * from './models/system-setting.model';
@@ -46,3 +46,9 @@ __exportStar(require("./models/internal-ticket-activity.model"), exports);
46
46
  __exportStar(require("./models/internal-ticket-follower.model"), exports);
47
47
  __exportStar(require("./models/internal-ticket-section.model"), exports);
48
48
  __exportStar(require("./models/internal-ticket-assignee.model"), exports);
49
+ __exportStar(require("./models/internal-ticket-tag.model"), exports);
50
+ __exportStar(require("./models/internal-ticket-ticket-tag.model"), exports);
51
+ __exportStar(require("./models/internal-ticket-artifact-type.model"), exports);
52
+ __exportStar(require("./models/internal-ticket-artifact-rule.model"), exports);
53
+ __exportStar(require("./models/internal-ticket-artifact.model"), exports);
54
+ __exportStar(require("./models/system-setting.model"), exports);
@@ -0,0 +1,9 @@
1
+ export type ArtifactRuleConditionType = 'ALWAYS' | 'TAG' | 'CATEGORY' | 'PRIORITY';
2
+ export interface IInternalTicketArtifactRule {
3
+ id: string;
4
+ internalTicketArtifactTypeId: string;
5
+ conditionType: ArtifactRuleConditionType;
6
+ conditionId: string | null;
7
+ createdAt?: Date;
8
+ updatedAt?: Date;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,16 @@
1
+ import { IInternalTicketSection } from './internal-ticket-section.model';
2
+ import { IInternalTicketArtifactRule } from './internal-ticket-artifact-rule.model';
3
+ export interface IInternalTicketArtifactType {
4
+ id: string;
5
+ internalTicketSectionId: string;
6
+ name: string;
7
+ description: string | null;
8
+ color: string | null;
9
+ order: number;
10
+ isEnabled: boolean;
11
+ archivedAt: Date | null;
12
+ createdAt?: Date;
13
+ updatedAt?: Date;
14
+ internalTicketSection?: IInternalTicketSection;
15
+ internalTicketArtifactRule?: IInternalTicketArtifactRule[];
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import { IInternalTicketArtifactType } from './internal-ticket-artifact-type.model';
2
+ export interface IInternalTicketArtifact {
3
+ id: string;
4
+ internalTicketId: string;
5
+ internalTicketArtifactTypeId: string | null;
6
+ label: string;
7
+ value: string;
8
+ createdAt?: Date;
9
+ updatedAt?: Date;
10
+ internalTicketArtifactType?: IInternalTicketArtifactType;
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -2,8 +2,7 @@ import { IInternalTicket } from './internal-ticket.model';
2
2
  import { IInternalTicketSection } from './internal-ticket-section.model';
3
3
  export interface IInternalTicketCategory {
4
4
  id: string;
5
- projectId: string;
6
- sectionId: string;
5
+ internalTicketSectionId: string;
7
6
  name: string;
8
7
  color: string | null;
9
8
  description: string | null;
@@ -7,7 +7,6 @@ export interface IInternalTicketMessage {
7
7
  userId: string;
8
8
  content: string;
9
9
  replyToMessageId: string | null;
10
- mentionedUserIds: string[];
11
10
  createdAt?: Date;
12
11
  updatedAt?: Date;
13
12
  internalTicket?: IInternalTicket;
@@ -2,13 +2,11 @@ import { IInternalTicket } from './internal-ticket.model';
2
2
  import { IInternalTicketSection } from './internal-ticket-section.model';
3
3
  export interface IInternalTicketPriority {
4
4
  id: string;
5
- projectId: string;
6
- sectionId: string;
5
+ internalTicketSectionId: string;
7
6
  name: string;
8
- label: string | null;
9
7
  color: string | null;
10
- level: number;
11
- isDefault: boolean;
8
+ description: string | null;
9
+ order: number;
12
10
  isEnabled: boolean;
13
11
  requirePriorityReason: boolean;
14
12
  archivedAt: Date | null;
@@ -1,5 +1,7 @@
1
1
  import { IInternalTicketCategory } from './internal-ticket-category.model';
2
2
  import { IInternalTicketPriority } from './internal-ticket-priority.model';
3
+ import { IInternalTicketTag } from './internal-ticket-tag.model';
4
+ import { IInternalTicketArtifactType } from './internal-ticket-artifact-type.model';
3
5
  import { IInternalTicket } from './internal-ticket.model';
4
6
  export interface IInternalTicketSection {
5
7
  id: string;
@@ -14,5 +16,7 @@ export interface IInternalTicketSection {
14
16
  updatedAt?: Date;
15
17
  internalTicketCategory?: IInternalTicketCategory[];
16
18
  internalTicketPriority?: IInternalTicketPriority[];
19
+ internalTicketTag?: IInternalTicketTag[];
20
+ internalTicketArtifactType?: IInternalTicketArtifactType[];
17
21
  internalTicket?: IInternalTicket[];
18
22
  }
@@ -0,0 +1,14 @@
1
+ import { IInternalTicketSection } from './internal-ticket-section.model';
2
+ export interface IInternalTicketTag {
3
+ id: string;
4
+ internalTicketSectionId: string;
5
+ name: string;
6
+ color: string | null;
7
+ description: string | null;
8
+ order: number;
9
+ isEnabled: boolean;
10
+ archivedAt: Date | null;
11
+ createdAt?: Date;
12
+ updatedAt?: Date;
13
+ internalTicketSection?: IInternalTicketSection;
14
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { IInternalTicketTag } from './internal-ticket-tag.model';
2
+ export interface IInternalTicketTicketTag {
3
+ id: string;
4
+ internalTicketId: string;
5
+ internalTicketTagId: string;
6
+ createdAt?: Date;
7
+ updatedAt?: Date;
8
+ internalTicketTag?: IInternalTicketTag;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -7,19 +7,23 @@ import { IInternalTicketAttachment } from './internal-ticket-attachment.model';
7
7
  import { IInternalTicketFollower } from './internal-ticket-follower.model';
8
8
  import { IInternalTicketPriority } from './internal-ticket-priority.model';
9
9
  import { IInternalTicketSection } from './internal-ticket-section.model';
10
+ import { IInternalTicketTicketTag } from './internal-ticket-ticket-tag.model';
11
+ import { IInternalTicketArtifact } from './internal-ticket-artifact.model';
10
12
  export interface IInternalTicket {
11
13
  id: string;
12
14
  projectId: string;
13
- sectionId: string;
15
+ internalTicketSectionId: string;
14
16
  title: string;
15
17
  description: string;
16
18
  status: InternalTicketStatus;
17
- priorityId: string | null;
18
- categoryId: string | null;
19
+ internalTicketPriorityId: string | null;
20
+ internalTicketCategoryId: string | null;
19
21
  createdByUserId: string;
20
22
  assignedToUserId: string | null;
21
23
  priorityCheckedAt: Date | null;
22
24
  priorityReason: string | null;
25
+ reviewedAt: Date | null;
26
+ resolvedAt: Date | null;
23
27
  archivedAt: Date | null;
24
28
  closedAt: Date | null;
25
29
  createdAt?: Date;
@@ -32,4 +36,6 @@ export interface IInternalTicket {
32
36
  internalTicketAttachment?: IInternalTicketAttachment[];
33
37
  internalTicketFollower?: IInternalTicketFollower[];
34
38
  internalTicketAssignee?: IInternalTicketAssignee[];
39
+ internalTicketTicketTag?: IInternalTicketTicketTag[];
40
+ internalTicketArtifact?: IInternalTicketArtifact[];
35
41
  }
@@ -0,0 +1,8 @@
1
+ export interface ISystemSetting {
2
+ id: string;
3
+ key: string;
4
+ value: Record<string, unknown>;
5
+ description: string | null;
6
+ createdAt?: Date;
7
+ updatedAt?: Date;
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,5 @@
1
1
  export * from './error.utils';
2
2
  export * from './ip-address-validator.utils';
3
3
  export * from './cidr.util';
4
+ export * from './mention.utils';
5
+ export * from './internal-ticket-status.utils';
@@ -17,3 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./error.utils"), exports);
18
18
  __exportStar(require("./ip-address-validator.utils"), exports);
19
19
  __exportStar(require("./cidr.util"), exports);
20
+ __exportStar(require("./mention.utils"), exports);
21
+ __exportStar(require("./internal-ticket-status.utils"), exports);
@@ -0,0 +1,9 @@
1
+ import { InternalTicketStatus, InternalTicketStatusReason } from '../types/enum/internal-ticket.enum';
2
+ import { IInternalTicket } from '../types/interface/models/internal-ticket.model';
3
+ type TicketStatusInput = Pick<IInternalTicket, 'archivedAt' | 'closedAt' | 'resolvedAt' | 'reviewedAt' | 'assignedToUserId' | 'internalTicketAssignee'>;
4
+ export type ComputedTicketStatus = {
5
+ status: InternalTicketStatus;
6
+ reason: InternalTicketStatusReason;
7
+ };
8
+ export declare function computeInternalTicketStatus(ticket: TicketStatusInput): ComputedTicketStatus;
9
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computeInternalTicketStatus = void 0;
4
+ const internal_ticket_enum_1 = require("../types/enum/internal-ticket.enum");
5
+ function computeInternalTicketStatus(ticket) {
6
+ var _a;
7
+ if (ticket.archivedAt) {
8
+ return { status: internal_ticket_enum_1.InternalTicketStatus.ARCHIVED, reason: internal_ticket_enum_1.InternalTicketStatusReason.TICKET_ARCHIVED };
9
+ }
10
+ if (ticket.closedAt) {
11
+ return { status: internal_ticket_enum_1.InternalTicketStatus.CLOSED, reason: internal_ticket_enum_1.InternalTicketStatusReason.TICKET_CLOSED };
12
+ }
13
+ if (ticket.resolvedAt) {
14
+ return { status: internal_ticket_enum_1.InternalTicketStatus.RESOLVED, reason: internal_ticket_enum_1.InternalTicketStatusReason.TICKET_RESOLVED };
15
+ }
16
+ if (!ticket.reviewedAt) {
17
+ return { status: internal_ticket_enum_1.InternalTicketStatus.WAITING_REVIEW, reason: internal_ticket_enum_1.InternalTicketStatusReason.NOT_REVIEWED };
18
+ }
19
+ const hasAssignees = !!ticket.assignedToUserId || ((_a = ticket.internalTicketAssignee) !== null && _a !== void 0 ? _a : []).length > 0;
20
+ if (!hasAssignees) {
21
+ return { status: internal_ticket_enum_1.InternalTicketStatus.WAITING_ASSIGNEE, reason: internal_ticket_enum_1.InternalTicketStatusReason.NO_ASSIGNEE };
22
+ }
23
+ return { status: internal_ticket_enum_1.InternalTicketStatus.IN_PROGRESS, reason: internal_ticket_enum_1.InternalTicketStatusReason.HAS_ASSIGNEE };
24
+ }
25
+ exports.computeInternalTicketStatus = computeInternalTicketStatus;
@@ -0,0 +1,3 @@
1
+ export declare function extractMentionedUserIds(content: string): string[];
2
+ export declare function formatMentionsForDisplay(content: string): string;
3
+ export declare function hasMentions(content: string): boolean;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasMentions = exports.formatMentionsForDisplay = exports.extractMentionedUserIds = void 0;
4
+ function extractMentionedUserIds(content) {
5
+ const mentionRegex = /<@([a-f0-9-]+)\|[^>]+>/g;
6
+ const mentionedUserIds = [];
7
+ let match;
8
+ while ((match = mentionRegex.exec(content)) !== null) {
9
+ mentionedUserIds.push(match[1]);
10
+ }
11
+ return [...new Set(mentionedUserIds)];
12
+ }
13
+ exports.extractMentionedUserIds = extractMentionedUserIds;
14
+ function formatMentionsForDisplay(content) {
15
+ return content.replace(/<@[a-f0-9-]+\|([^>]+)>/g, '@$1');
16
+ }
17
+ exports.formatMentionsForDisplay = formatMentionsForDisplay;
18
+ function hasMentions(content) {
19
+ return /<@[a-f0-9-]+\|[^>]+>/.test(content);
20
+ }
21
+ exports.hasMentions = hasMentions;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abyss-project/console",
3
- "version": "1.0.73",
3
+ "version": "1.0.76",
4
4
  "description": "Core package to interact with AbyssConsole",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -38,6 +38,7 @@
38
38
  "eslint-plugin-promise": "^5.1.0",
39
39
  "prettier": "2.3.1",
40
40
  "sequelize-cli": "^6.2.0",
41
+ "tsc-watch": "^7.2.0",
41
42
  "typescript": "5.4.2"
42
43
  },
43
44
  "scripts": {
@@ -45,6 +46,7 @@
45
46
  "lint:check": "eslint \"{src,apps,libs,test,core}/**/*.ts\" --max-warnings 0",
46
47
  "tsc": "tsc",
47
48
  "build": "tsc",
49
+ "dev": "tsc-watch --onSuccess 'yalc push'",
48
50
  "prepublish": "tsc"
49
51
  }
50
52
  }
@@ -1,52 +0,0 @@
1
- export interface IReferenceResolver<T = any> {
2
- type: string;
3
- resolve: (id: string) => Promise<T> | T;
4
- }
5
- export interface IResolvedReference<T = any> {
6
- type: string;
7
- id: string;
8
- reference: string;
9
- value: T;
10
- resolvedValue: string;
11
- }
12
- export interface IValidationResult {
13
- valid: boolean;
14
- missingReferences: Array<{
15
- type: string;
16
- id: string;
17
- reference: string;
18
- }>;
19
- }
20
- export declare class ReferenceResolverUtils {
21
- private static resolvers;
22
- static registerResolver<T>(resolver: IReferenceResolver<T>): void;
23
- static unregisterResolver(type: string): void;
24
- static clearResolvers(): void;
25
- static hasReferences(value: string): boolean;
26
- static extractReferences(value: string): Array<{
27
- type: string;
28
- id: string;
29
- reference: string;
30
- }>;
31
- static extractReferencesFromArray(values: string[]): Array<{
32
- type: string;
33
- id: string;
34
- reference: string;
35
- }>;
36
- static extractReferencesFromObject(obj: any): Array<{
37
- type: string;
38
- id: string;
39
- reference: string;
40
- }>;
41
- private static uniqueReferences;
42
- static resolveString(value: string): Promise<string>;
43
- static resolveArray(values: string[]): Promise<string[]>;
44
- static resolveObject<T>(obj: T): Promise<T>;
45
- static validateReferences(value: any): Promise<IValidationResult>;
46
- static getResolutionInfo(value: string): Promise<IResolvedReference[]>;
47
- static resolveObjectWithTypes<T>(obj: T, types: string[]): Promise<T>;
48
- }
49
- export declare function resolveReferences<T>(value: T): Promise<T>;
50
- export declare function createResolver<T>(type: string, resolveFn: (id: string) => Promise<T> | T): IReferenceResolver<T>;
51
- export declare function createMapResolver<T>(type: string, map: Map<string, T>): IReferenceResolver<T>;
52
- export declare function createAsyncResolver<T>(type: string, fetchFn: (id: string) => Promise<T>): IReferenceResolver<T>;
@@ -1,219 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createAsyncResolver = exports.createMapResolver = exports.createResolver = exports.resolveReferences = exports.ReferenceResolverUtils = void 0;
4
- const REFERENCE_PATTERN = /@(\w+):([a-zA-Z0-9-_]+)/g;
5
- class ReferenceResolverUtils {
6
- static registerResolver(resolver) {
7
- this.resolvers.set(resolver.type, resolver);
8
- }
9
- static unregisterResolver(type) {
10
- this.resolvers.delete(type);
11
- }
12
- static clearResolvers() {
13
- this.resolvers.clear();
14
- }
15
- static hasReferences(value) {
16
- const pattern = new RegExp(REFERENCE_PATTERN);
17
- return pattern.test(value);
18
- }
19
- static extractReferences(value) {
20
- const pattern = new RegExp(REFERENCE_PATTERN);
21
- const matches = value.matchAll(pattern);
22
- return Array.from(matches, (m) => ({
23
- type: m[1],
24
- id: m[2],
25
- reference: m[0],
26
- }));
27
- }
28
- static extractReferencesFromArray(values) {
29
- const allRefs = values.flatMap((value) => this.extractReferences(value));
30
- return this.uniqueReferences(allRefs);
31
- }
32
- static extractReferencesFromObject(obj) {
33
- const refs = [];
34
- const traverse = (value) => {
35
- if (typeof value === 'string' && this.hasReferences(value)) {
36
- refs.push(...this.extractReferences(value));
37
- }
38
- else if (Array.isArray(value)) {
39
- value.forEach(traverse);
40
- }
41
- else if (value && typeof value === 'object') {
42
- Object.values(value).forEach(traverse);
43
- }
44
- };
45
- traverse(obj);
46
- return this.uniqueReferences(refs);
47
- }
48
- static uniqueReferences(refs) {
49
- const seen = new Set();
50
- return refs.filter((ref) => {
51
- const key = `${ref.type}:${ref.id}`;
52
- if (seen.has(key))
53
- return false;
54
- seen.add(key);
55
- return true;
56
- });
57
- }
58
- static async resolveString(value) {
59
- const references = this.extractReferences(value);
60
- let resolved = value;
61
- for (const ref of references) {
62
- const resolver = this.resolvers.get(ref.type);
63
- if (!resolver) {
64
- throw new Error(`No resolver registered for type: ${ref.type}`);
65
- }
66
- const resolvedValue = await resolver.resolve(ref.id);
67
- if (resolvedValue === null || resolvedValue === undefined) {
68
- throw new Error(`Reference not found: ${ref.reference}`);
69
- }
70
- const stringValue = typeof resolvedValue === 'object'
71
- ? resolvedValue.value || JSON.stringify(resolvedValue)
72
- : String(resolvedValue);
73
- resolved = resolved.replace(ref.reference, stringValue);
74
- }
75
- return resolved;
76
- }
77
- static async resolveArray(values) {
78
- const resolved = await Promise.all(values.map(async (value) => {
79
- if (this.hasReferences(value)) {
80
- return await this.resolveString(value);
81
- }
82
- return value;
83
- }));
84
- return resolved.flat();
85
- }
86
- static async resolveObject(obj) {
87
- const resolve = async (value) => {
88
- if (typeof value === 'string' && this.hasReferences(value)) {
89
- return await this.resolveString(value);
90
- }
91
- else if (Array.isArray(value)) {
92
- return await Promise.all(value.map(resolve));
93
- }
94
- else if (value && typeof value === 'object') {
95
- const resolved = {};
96
- for (const [key, val] of Object.entries(value)) {
97
- resolved[key] = await resolve(val);
98
- }
99
- return resolved;
100
- }
101
- return value;
102
- };
103
- return await resolve(obj);
104
- }
105
- static async validateReferences(value) {
106
- const references = typeof value === 'string'
107
- ? this.extractReferences(value)
108
- : this.extractReferencesFromObject(value);
109
- const missingReferences = [];
110
- for (const ref of references) {
111
- const resolver = this.resolvers.get(ref.type);
112
- if (!resolver) {
113
- missingReferences.push(ref);
114
- continue;
115
- }
116
- try {
117
- const resolved = await resolver.resolve(ref.id);
118
- if (resolved === null || resolved === undefined) {
119
- missingReferences.push(ref);
120
- }
121
- }
122
- catch {
123
- missingReferences.push(ref);
124
- }
125
- }
126
- return {
127
- valid: missingReferences.length === 0,
128
- missingReferences,
129
- };
130
- }
131
- static async getResolutionInfo(value) {
132
- const references = this.extractReferences(value);
133
- const results = [];
134
- for (const ref of references) {
135
- const resolver = this.resolvers.get(ref.type);
136
- if (!resolver) {
137
- throw new Error(`No resolver registered for type: ${ref.type}`);
138
- }
139
- const resolvedValue = await resolver.resolve(ref.id);
140
- if (resolvedValue === null || resolvedValue === undefined) {
141
- throw new Error(`Reference not found: ${ref.reference}`);
142
- }
143
- const stringValue = typeof resolvedValue === 'object'
144
- ? resolvedValue.value || JSON.stringify(resolvedValue)
145
- : String(resolvedValue);
146
- results.push({
147
- type: ref.type,
148
- id: ref.id,
149
- reference: ref.reference,
150
- value: resolvedValue,
151
- resolvedValue: stringValue,
152
- });
153
- }
154
- return results;
155
- }
156
- static async resolveObjectWithTypes(obj, types) {
157
- const typeSet = new Set(types);
158
- const resolve = async (value) => {
159
- if (typeof value === 'string' && this.hasReferences(value)) {
160
- const references = this.extractReferences(value);
161
- let resolved = value;
162
- for (const ref of references) {
163
- if (!typeSet.has(ref.type))
164
- continue;
165
- const resolver = this.resolvers.get(ref.type);
166
- if (!resolver)
167
- continue;
168
- const resolvedValue = await resolver.resolve(ref.id);
169
- if (resolvedValue === null || resolvedValue === undefined)
170
- continue;
171
- const stringValue = typeof resolvedValue === 'object'
172
- ? resolvedValue.value || JSON.stringify(resolvedValue)
173
- : String(resolvedValue);
174
- resolved = resolved.replace(ref.reference, stringValue);
175
- }
176
- return resolved;
177
- }
178
- else if (Array.isArray(value)) {
179
- return await Promise.all(value.map(resolve));
180
- }
181
- else if (value && typeof value === 'object') {
182
- const resolved = {};
183
- for (const [key, val] of Object.entries(value)) {
184
- resolved[key] = await resolve(val);
185
- }
186
- return resolved;
187
- }
188
- return value;
189
- };
190
- return await resolve(obj);
191
- }
192
- }
193
- exports.ReferenceResolverUtils = ReferenceResolverUtils;
194
- ReferenceResolverUtils.resolvers = new Map();
195
- async function resolveReferences(value) {
196
- return ReferenceResolverUtils.resolveObject(value);
197
- }
198
- exports.resolveReferences = resolveReferences;
199
- function createResolver(type, resolveFn) {
200
- return {
201
- type,
202
- resolve: resolveFn,
203
- };
204
- }
205
- exports.createResolver = createResolver;
206
- function createMapResolver(type, map) {
207
- return createResolver(type, (id) => {
208
- const value = map.get(id);
209
- if (value === undefined) {
210
- throw new Error(`${type} not found: ${id}`);
211
- }
212
- return value;
213
- });
214
- }
215
- exports.createMapResolver = createMapResolver;
216
- function createAsyncResolver(type, fetchFn) {
217
- return createResolver(type, fetchFn);
218
- }
219
- exports.createAsyncResolver = createAsyncResolver;