@sonisoft/now-sdk-ext-core 2.2.1 → 2.5.1

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 (98) hide show
  1. package/dist/comm/http/RequestHandler.js +7 -11
  2. package/dist/comm/http/RequestHandler.js.map +1 -1
  3. package/dist/comm/http/TableAPIRequest.js +3 -10
  4. package/dist/comm/http/TableAPIRequest.js.map +1 -1
  5. package/dist/index.d.ts +28 -0
  6. package/dist/index.js +28 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/sn/BackgroundScriptExecutor.d.ts +34 -0
  9. package/dist/sn/BackgroundScriptExecutor.js +96 -0
  10. package/dist/sn/BackgroundScriptExecutor.js.map +1 -1
  11. package/dist/sn/aggregate/AggregateModels.d.ts +89 -0
  12. package/dist/sn/aggregate/AggregateModels.js +5 -0
  13. package/dist/sn/aggregate/AggregateModels.js.map +1 -0
  14. package/dist/sn/aggregate/AggregateQuery.d.ts +50 -0
  15. package/dist/sn/aggregate/AggregateQuery.js +144 -0
  16. package/dist/sn/aggregate/AggregateQuery.js.map +1 -0
  17. package/dist/sn/application/ApplicationManager.d.ts +58 -1
  18. package/dist/sn/application/ApplicationManager.js +202 -11
  19. package/dist/sn/application/ApplicationManager.js.map +1 -1
  20. package/dist/sn/application/StoreApplicationModels.d.ts +99 -0
  21. package/dist/sn/application/StoreApplicationModels.js +2 -0
  22. package/dist/sn/application/StoreApplicationModels.js.map +1 -0
  23. package/dist/sn/attachment/AttachmentManager.d.ts +32 -0
  24. package/dist/sn/attachment/AttachmentManager.js +87 -0
  25. package/dist/sn/attachment/AttachmentManager.js.map +1 -0
  26. package/dist/sn/attachment/AttachmentModels.d.ts +28 -0
  27. package/dist/sn/attachment/AttachmentModels.js +2 -0
  28. package/dist/sn/attachment/AttachmentModels.js.map +1 -0
  29. package/dist/sn/batch/BatchModels.d.ts +90 -0
  30. package/dist/sn/batch/BatchModels.js +5 -0
  31. package/dist/sn/batch/BatchModels.js.map +1 -0
  32. package/dist/sn/batch/BatchOperations.d.ts +40 -0
  33. package/dist/sn/batch/BatchOperations.js +169 -0
  34. package/dist/sn/batch/BatchOperations.js.map +1 -0
  35. package/dist/sn/batch/QueryBatchModels.d.ts +93 -0
  36. package/dist/sn/batch/QueryBatchModels.js +5 -0
  37. package/dist/sn/batch/QueryBatchModels.js.map +1 -0
  38. package/dist/sn/batch/QueryBatchOperations.d.ts +41 -0
  39. package/dist/sn/batch/QueryBatchOperations.js +195 -0
  40. package/dist/sn/batch/QueryBatchOperations.js.map +1 -0
  41. package/dist/sn/cmdb/CMDBModels.d.ts +141 -0
  42. package/dist/sn/cmdb/CMDBModels.js +5 -0
  43. package/dist/sn/cmdb/CMDBModels.js.map +1 -0
  44. package/dist/sn/cmdb/CMDBRelationships.d.ts +60 -0
  45. package/dist/sn/cmdb/CMDBRelationships.js +286 -0
  46. package/dist/sn/cmdb/CMDBRelationships.js.map +1 -0
  47. package/dist/sn/discovery/DiscoveryModels.d.ts +160 -0
  48. package/dist/sn/discovery/DiscoveryModels.js +5 -0
  49. package/dist/sn/discovery/DiscoveryModels.js.map +1 -0
  50. package/dist/sn/discovery/InstanceDiscovery.d.ts +45 -0
  51. package/dist/sn/discovery/InstanceDiscovery.js +163 -0
  52. package/dist/sn/discovery/InstanceDiscovery.js.map +1 -0
  53. package/dist/sn/health/HealthModels.d.ts +124 -0
  54. package/dist/sn/health/HealthModels.js +5 -0
  55. package/dist/sn/health/HealthModels.js.map +1 -0
  56. package/dist/sn/health/InstanceHealth.d.ts +58 -0
  57. package/dist/sn/health/InstanceHealth.js +221 -0
  58. package/dist/sn/health/InstanceHealth.js.map +1 -0
  59. package/dist/sn/schema/SchemaDiscovery.d.ts +68 -0
  60. package/dist/sn/schema/SchemaDiscovery.js +346 -0
  61. package/dist/sn/schema/SchemaDiscovery.js.map +1 -0
  62. package/dist/sn/schema/SchemaModels.d.ts +277 -0
  63. package/dist/sn/schema/SchemaModels.js +5 -0
  64. package/dist/sn/schema/SchemaModels.js.map +1 -0
  65. package/dist/sn/scope/ScopeManager.d.ts +51 -0
  66. package/dist/sn/scope/ScopeManager.js +182 -0
  67. package/dist/sn/scope/ScopeManager.js.map +1 -0
  68. package/dist/sn/scope/ScopeModels.d.ts +72 -0
  69. package/dist/sn/scope/ScopeModels.js +5 -0
  70. package/dist/sn/scope/ScopeModels.js.map +1 -0
  71. package/dist/sn/scriptsync/ScriptSync.d.ts +38 -0
  72. package/dist/sn/scriptsync/ScriptSync.js +266 -0
  73. package/dist/sn/scriptsync/ScriptSync.js.map +1 -0
  74. package/dist/sn/scriptsync/ScriptSyncModels.d.ts +55 -0
  75. package/dist/sn/scriptsync/ScriptSyncModels.js +8 -0
  76. package/dist/sn/scriptsync/ScriptSyncModels.js.map +1 -0
  77. package/dist/sn/scriptsync/ScriptWatcher.d.ts +30 -0
  78. package/dist/sn/scriptsync/ScriptWatcher.js +74 -0
  79. package/dist/sn/scriptsync/ScriptWatcher.js.map +1 -0
  80. package/dist/sn/task/TaskModels.d.ts +85 -0
  81. package/dist/sn/task/TaskModels.js +5 -0
  82. package/dist/sn/task/TaskModels.js.map +1 -0
  83. package/dist/sn/task/TaskOperations.d.ts +63 -0
  84. package/dist/sn/task/TaskOperations.js +195 -0
  85. package/dist/sn/task/TaskOperations.js.map +1 -0
  86. package/dist/sn/updateset/UpdateSetManager.d.ts +78 -0
  87. package/dist/sn/updateset/UpdateSetManager.js +396 -0
  88. package/dist/sn/updateset/UpdateSetManager.js.map +1 -0
  89. package/dist/sn/updateset/UpdateSetModels.d.ts +188 -0
  90. package/dist/sn/updateset/UpdateSetModels.js +5 -0
  91. package/dist/sn/updateset/UpdateSetModels.js.map +1 -0
  92. package/dist/sn/workflow/WorkflowManager.d.ts +81 -0
  93. package/dist/sn/workflow/WorkflowManager.js +388 -0
  94. package/dist/sn/workflow/WorkflowManager.js.map +1 -0
  95. package/dist/sn/workflow/WorkflowModels.d.ts +242 -0
  96. package/dist/sn/workflow/WorkflowModels.js +5 -0
  97. package/dist/sn/workflow/WorkflowModels.js.map +1 -0
  98. package/package.json +5 -5
@@ -0,0 +1,51 @@
1
+ import { ServiceNowInstance } from "../ServiceNowInstance.js";
2
+ import { ApplicationRecord, SetCurrentApplicationResult, ListApplicationsOptions } from './ScopeModels.js';
3
+ /**
4
+ * ScopeManager provides operations for managing ServiceNow application scopes.
5
+ * Supports setting/getting the current application, listing applications,
6
+ * and retrieving application details.
7
+ */
8
+ export declare class ScopeManager {
9
+ private static readonly UI_APP_PATH;
10
+ private static readonly UI_CONCOURSEPICKER_CURRENT_PATH;
11
+ private static readonly SYS_SCOPE_TABLE;
12
+ private _logger;
13
+ private _req;
14
+ private _tableAPI;
15
+ private _instance;
16
+ constructor(instance: ServiceNowInstance);
17
+ /**
18
+ * Set the current application scope.
19
+ * Validates the sys_id, retrieves the previous scope, performs the PUT,
20
+ * and verifies the change.
21
+ *
22
+ * @param appSysId The sys_id of the application to set as current (32-char hex)
23
+ * @returns Result of the operation including previous scope and verification
24
+ * @throws Error if appSysId is invalid or the application is not found
25
+ */
26
+ setCurrentApplication(appSysId: string): Promise<SetCurrentApplicationResult>;
27
+ /**
28
+ * Get the current application scope.
29
+ * Uses GET /api/now/ui/concoursepicker/current
30
+ *
31
+ * @returns The current ApplicationRecord or null
32
+ */
33
+ getCurrentApplication(): Promise<ApplicationRecord | null>;
34
+ /**
35
+ * List applications from the sys_scope table.
36
+ * Uses Table API GET on sys_scope.
37
+ *
38
+ * @param options Optional query and limit options
39
+ * @returns Array of ApplicationRecord
40
+ */
41
+ listApplications(options?: ListApplicationsOptions): Promise<ApplicationRecord[]>;
42
+ /**
43
+ * Get a specific application by sys_id.
44
+ * Uses Table API GET on sys_scope with sys_id filter.
45
+ *
46
+ * @param sysId The sys_id of the application to retrieve
47
+ * @returns The ApplicationRecord or null if not found
48
+ * @throws Error if sysId is empty or the API call fails
49
+ */
50
+ getApplication(sysId: string): Promise<ApplicationRecord | null>;
51
+ }
@@ -0,0 +1,182 @@
1
+ import { Logger } from "../../util/Logger.js";
2
+ import { ServiceNowRequest } from "../../comm/http/ServiceNowRequest.js";
3
+ import { TableAPIRequest } from "../../comm/http/TableAPIRequest.js";
4
+ /**
5
+ * ScopeManager provides operations for managing ServiceNow application scopes.
6
+ * Supports setting/getting the current application, listing applications,
7
+ * and retrieving application details.
8
+ */
9
+ export class ScopeManager {
10
+ static UI_APP_PATH = '/api/now/ui/concoursepicker/application';
11
+ static UI_CONCOURSEPICKER_CURRENT_PATH = '/api/now/ui/concoursepicker/current';
12
+ static SYS_SCOPE_TABLE = 'sys_scope';
13
+ _logger = new Logger("ScopeManager");
14
+ _req;
15
+ _tableAPI;
16
+ _instance;
17
+ constructor(instance) {
18
+ this._instance = instance;
19
+ this._req = new ServiceNowRequest(instance);
20
+ this._tableAPI = new TableAPIRequest(instance);
21
+ }
22
+ /**
23
+ * Set the current application scope.
24
+ * Validates the sys_id, retrieves the previous scope, performs the PUT,
25
+ * and verifies the change.
26
+ *
27
+ * @param appSysId The sys_id of the application to set as current (32-char hex)
28
+ * @returns Result of the operation including previous scope and verification
29
+ * @throws Error if appSysId is invalid or the application is not found
30
+ */
31
+ async setCurrentApplication(appSysId) {
32
+ if (!appSysId || appSysId.trim().length === 0) {
33
+ throw new Error('Application sys_id is required');
34
+ }
35
+ // Validate 32-character hexadecimal sys_id
36
+ const hexPattern = /^[0-9a-fA-F]{32}$/;
37
+ if (!hexPattern.test(appSysId.trim())) {
38
+ throw new Error('Application sys_id must be a 32-character hexadecimal string');
39
+ }
40
+ this._logger.info(`Setting current application to: ${appSysId}`);
41
+ const warnings = [];
42
+ // Get the target application details
43
+ const appQuery = {
44
+ sysparm_query: `sys_id=${appSysId}`,
45
+ sysparm_limit: 1
46
+ };
47
+ const appResp = await this._tableAPI.get(ScopeManager.SYS_SCOPE_TABLE, appQuery);
48
+ if (!appResp || appResp.status !== 200 || !appResp.bodyObject?.result || appResp.bodyObject.result.length === 0) {
49
+ throw new Error(`Application '${appSysId}' not found`);
50
+ }
51
+ const targetApp = appResp.bodyObject.result[0];
52
+ // Get the current application (previous scope)
53
+ let previousScope;
54
+ try {
55
+ const currentApp = await this.getCurrentApplication();
56
+ if (currentApp) {
57
+ previousScope = {
58
+ sys_id: currentApp.sys_id,
59
+ name: currentApp.name
60
+ };
61
+ }
62
+ }
63
+ catch (err) {
64
+ warnings.push(`Could not retrieve previous scope: ${err instanceof Error ? err.message : String(err)}`);
65
+ }
66
+ // PUT to concoursepicker to change the application
67
+ const putRequest = {
68
+ method: 'PUT',
69
+ path: ScopeManager.UI_APP_PATH,
70
+ headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
71
+ query: null,
72
+ body: null,
73
+ json: { app_id: appSysId }
74
+ };
75
+ const putResp = await this._req.put(putRequest);
76
+ if (putResp.status !== 200) {
77
+ throw new Error(`Failed to set current application. Status: ${putResp.status}`);
78
+ }
79
+ // Verify the change by getting the current application again
80
+ let verified = false;
81
+ try {
82
+ const verifyApp = await this.getCurrentApplication();
83
+ if (verifyApp && verifyApp.sys_id === appSysId) {
84
+ verified = true;
85
+ }
86
+ else {
87
+ warnings.push('Scope change could not be verified — current app does not match target');
88
+ }
89
+ }
90
+ catch (err) {
91
+ warnings.push(`Verification failed: ${err instanceof Error ? err.message : String(err)}`);
92
+ }
93
+ this._logger.info(`Set current application to: ${targetApp.name} (${targetApp.scope || 'unknown scope'})`);
94
+ return {
95
+ success: true,
96
+ application: targetApp.name,
97
+ scope: (targetApp.scope || ''),
98
+ sysId: appSysId,
99
+ previousScope,
100
+ verified,
101
+ warnings
102
+ };
103
+ }
104
+ /**
105
+ * Get the current application scope.
106
+ * Uses GET /api/now/ui/concoursepicker/current
107
+ *
108
+ * @returns The current ApplicationRecord or null
109
+ */
110
+ async getCurrentApplication() {
111
+ this._logger.info('Getting current application');
112
+ const request = {
113
+ method: 'GET',
114
+ path: ScopeManager.UI_CONCOURSEPICKER_CURRENT_PATH,
115
+ headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
116
+ query: null,
117
+ body: null
118
+ };
119
+ const resp = await this._req.get(request);
120
+ if (resp.status === 200 && resp.bodyObject?.result?.currentApplication) {
121
+ const current = resp.bodyObject.result.currentApplication;
122
+ this._logger.info(`Current application: ${current.name}`);
123
+ return {
124
+ sys_id: current.sysId,
125
+ name: current.name,
126
+ scope: current.scopeName
127
+ };
128
+ }
129
+ throw new Error(`Failed to get current application. Status: ${resp.status}`);
130
+ }
131
+ /**
132
+ * List applications from the sys_scope table.
133
+ * Uses Table API GET on sys_scope.
134
+ *
135
+ * @param options Optional query and limit options
136
+ * @returns Array of ApplicationRecord
137
+ */
138
+ async listApplications(options = {}) {
139
+ const { encodedQuery, limit = 100 } = options;
140
+ this._logger.info(`Listing applications with query: ${encodedQuery || 'none'}`);
141
+ const query = {
142
+ sysparm_limit: limit
143
+ };
144
+ if (encodedQuery) {
145
+ query.sysparm_query = encodedQuery;
146
+ }
147
+ const response = await this._tableAPI.get(ScopeManager.SYS_SCOPE_TABLE, query);
148
+ if (response.status === 200 && response.bodyObject?.result) {
149
+ this._logger.info(`Retrieved ${response.bodyObject.result.length} applications`);
150
+ return response.bodyObject.result;
151
+ }
152
+ throw new Error(`Failed to list applications. Status: ${response.status}`);
153
+ }
154
+ /**
155
+ * Get a specific application by sys_id.
156
+ * Uses Table API GET on sys_scope with sys_id filter.
157
+ *
158
+ * @param sysId The sys_id of the application to retrieve
159
+ * @returns The ApplicationRecord or null if not found
160
+ * @throws Error if sysId is empty or the API call fails
161
+ */
162
+ async getApplication(sysId) {
163
+ if (!sysId || sysId.trim().length === 0) {
164
+ throw new Error('Application sys_id is required');
165
+ }
166
+ this._logger.info(`Getting application: ${sysId}`);
167
+ const query = {
168
+ sysparm_query: `sys_id=${sysId}`,
169
+ sysparm_limit: 1
170
+ };
171
+ const response = await this._tableAPI.get(ScopeManager.SYS_SCOPE_TABLE, query);
172
+ if (response.status === 200 && response.bodyObject?.result) {
173
+ if (response.bodyObject.result.length > 0) {
174
+ this._logger.info(`Found application: ${response.bodyObject.result[0].name}`);
175
+ return response.bodyObject.result[0];
176
+ }
177
+ return null;
178
+ }
179
+ throw new Error(`Failed to get application '${sysId}'. Status: ${response.status}`);
180
+ }
181
+ }
182
+ //# sourceMappingURL=ScopeManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScopeManager.js","sourceRoot":"","sources":["../../../src/sn/scope/ScopeManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * A record from the sys_scope table.
3
+ */
4
+ export interface ApplicationRecord {
5
+ /** System ID */
6
+ sys_id: string;
7
+ /** Application name */
8
+ name: string;
9
+ /** Application scope (e.g., "x_myapp") */
10
+ scope?: string;
11
+ /** Application version */
12
+ version?: string;
13
+ /** Whether the application is active */
14
+ active?: string;
15
+ /** Additional fields */
16
+ [key: string]: unknown;
17
+ }
18
+ /**
19
+ * Result of setting the current application scope.
20
+ */
21
+ export interface SetCurrentApplicationResult {
22
+ /** Whether the operation was successful */
23
+ success: boolean;
24
+ /** Application name */
25
+ application: string;
26
+ /** Application scope */
27
+ scope: string;
28
+ /** Application sys_id */
29
+ sysId: string;
30
+ /** The previously active scope before the change */
31
+ previousScope?: {
32
+ sys_id?: string;
33
+ name?: string;
34
+ };
35
+ /** Whether the scope change was verified */
36
+ verified: boolean;
37
+ /** Any warnings generated during the operation */
38
+ warnings: string[];
39
+ }
40
+ /**
41
+ * Options for listing applications.
42
+ */
43
+ export interface ListApplicationsOptions {
44
+ /** Encoded query string for filtering */
45
+ encodedQuery?: string;
46
+ /** Maximum number of records to return */
47
+ limit?: number;
48
+ }
49
+ /**
50
+ * Response wrapper for multiple application records.
51
+ */
52
+ export interface ApplicationResponse {
53
+ result: ApplicationRecord[];
54
+ }
55
+ /**
56
+ * Response wrapper for a single application record.
57
+ */
58
+ export interface ApplicationSingleResponse {
59
+ result: ApplicationRecord;
60
+ }
61
+ /**
62
+ * Response from GET /api/now/ui/concoursepicker/current for the current application.
63
+ */
64
+ export interface CurrentApplicationResponse {
65
+ result: {
66
+ currentApplication: {
67
+ name: string;
68
+ scopeName: string;
69
+ sysId: string;
70
+ };
71
+ };
72
+ }
@@ -0,0 +1,5 @@
1
+ // ============================================================
2
+ // Application/Scope Record Types
3
+ // ============================================================
4
+ export {};
5
+ //# sourceMappingURL=ScopeModels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScopeModels.js","sourceRoot":"","sources":["../../../src/sn/scope/ScopeModels.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,iCAAiC;AACjC,+DAA+D"}
@@ -0,0 +1,38 @@
1
+ import { ServiceNowInstance } from "../ServiceNowInstance.js";
2
+ import { SyncScriptOptions, SyncResult, SyncAllOptions, SyncAllResult, ParsedFileName } from './ScriptSyncModels.js';
3
+ /**
4
+ * ScriptSync provides bidirectional synchronization between local files
5
+ * and ServiceNow script records (Script Includes, Business Rules, etc.).
6
+ */
7
+ export declare class ScriptSync {
8
+ private _logger;
9
+ private _req;
10
+ private _tableAPI;
11
+ private _instance;
12
+ constructor(instance: ServiceNowInstance);
13
+ /**
14
+ * Pull a script from ServiceNow and write it to a local file.
15
+ * Queries the appropriate table by name and writes the script field to filePath.
16
+ */
17
+ pullScript(options: SyncScriptOptions): Promise<SyncResult>;
18
+ /**
19
+ * Push a local file to ServiceNow by updating the script field on the matching record.
20
+ * Reads the file from filePath, queries the table by name to find the sys_id,
21
+ * then updates the script field via TableAPIRequest.put().
22
+ */
23
+ pushScript(options: SyncScriptOptions): Promise<SyncResult>;
24
+ /**
25
+ * Sync all scripts in a directory. Reads filenames, parses them to determine
26
+ * script name and type, and pushes each to ServiceNow.
27
+ */
28
+ syncAllScripts(options: SyncAllOptions): Promise<SyncAllResult>;
29
+ /**
30
+ * Parse a filename in the format "{name}.{type}.js" to extract the script name and type.
31
+ * Valid types are keys of SCRIPT_TYPES.
32
+ */
33
+ static parseFileName(fileName: string): ParsedFileName;
34
+ /**
35
+ * Generate a filename in the format "{name}.{type}.js".
36
+ */
37
+ static generateFileName(scriptName: string, scriptType: string): string;
38
+ }
@@ -0,0 +1,266 @@
1
+ import * as fs from 'fs';
2
+ import { Logger } from "../../util/Logger.js";
3
+ import { ServiceNowRequest } from "../../comm/http/ServiceNowRequest.js";
4
+ import { TableAPIRequest } from "../../comm/http/TableAPIRequest.js";
5
+ import { SCRIPT_TYPES } from './ScriptSyncModels.js';
6
+ /**
7
+ * ScriptSync provides bidirectional synchronization between local files
8
+ * and ServiceNow script records (Script Includes, Business Rules, etc.).
9
+ */
10
+ export class ScriptSync {
11
+ _logger = new Logger("ScriptSync");
12
+ _req;
13
+ _tableAPI;
14
+ _instance;
15
+ constructor(instance) {
16
+ this._instance = instance;
17
+ this._req = new ServiceNowRequest(instance);
18
+ this._tableAPI = new TableAPIRequest(instance);
19
+ }
20
+ /**
21
+ * Pull a script from ServiceNow and write it to a local file.
22
+ * Queries the appropriate table by name and writes the script field to filePath.
23
+ */
24
+ async pullScript(options) {
25
+ const { scriptName, scriptType, filePath } = options;
26
+ const timestamp = new Date().toISOString();
27
+ const config = SCRIPT_TYPES[scriptType];
28
+ if (!config) {
29
+ return {
30
+ scriptName,
31
+ scriptType,
32
+ filePath,
33
+ direction: 'pull',
34
+ success: false,
35
+ message: `Unknown script type: ${scriptType}`,
36
+ error: `Unknown script type: ${scriptType}`,
37
+ timestamp
38
+ };
39
+ }
40
+ try {
41
+ this._logger.info(`Pulling ${config.label} '${scriptName}' from table '${config.table}'`);
42
+ const query = {
43
+ sysparm_query: `${config.nameField}=${scriptName}`,
44
+ sysparm_limit: 1
45
+ };
46
+ const response = await this._tableAPI.get(config.table, query);
47
+ if (response.status !== 200 || !response.bodyObject?.result || response.bodyObject.result.length === 0) {
48
+ return {
49
+ scriptName,
50
+ scriptType,
51
+ filePath,
52
+ direction: 'pull',
53
+ success: false,
54
+ message: `Script '${scriptName}' not found in ${config.table}`,
55
+ error: `Script not found`,
56
+ timestamp
57
+ };
58
+ }
59
+ const record = response.bodyObject.result[0];
60
+ const scriptContent = record[config.scriptField] || '';
61
+ fs.writeFileSync(filePath, scriptContent, 'utf-8');
62
+ this._logger.info(`Successfully pulled '${scriptName}' to ${filePath}`);
63
+ return {
64
+ scriptName,
65
+ scriptType,
66
+ filePath,
67
+ direction: 'pull',
68
+ success: true,
69
+ sysId: record.sys_id,
70
+ message: `Successfully pulled ${config.label} '${scriptName}'`,
71
+ timestamp
72
+ };
73
+ }
74
+ catch (error) {
75
+ const err = error;
76
+ this._logger.error(`Error pulling script '${scriptName}': ${err.message}`);
77
+ return {
78
+ scriptName,
79
+ scriptType,
80
+ filePath,
81
+ direction: 'pull',
82
+ success: false,
83
+ message: `Failed to pull ${config.label} '${scriptName}'`,
84
+ error: err.message,
85
+ timestamp
86
+ };
87
+ }
88
+ }
89
+ /**
90
+ * Push a local file to ServiceNow by updating the script field on the matching record.
91
+ * Reads the file from filePath, queries the table by name to find the sys_id,
92
+ * then updates the script field via TableAPIRequest.put().
93
+ */
94
+ async pushScript(options) {
95
+ const { scriptName, scriptType, filePath } = options;
96
+ const timestamp = new Date().toISOString();
97
+ const config = SCRIPT_TYPES[scriptType];
98
+ if (!config) {
99
+ return {
100
+ scriptName,
101
+ scriptType,
102
+ filePath,
103
+ direction: 'push',
104
+ success: false,
105
+ message: `Unknown script type: ${scriptType}`,
106
+ error: `Unknown script type: ${scriptType}`,
107
+ timestamp
108
+ };
109
+ }
110
+ try {
111
+ this._logger.info(`Pushing '${scriptName}' to ${config.table}`);
112
+ const scriptContent = fs.readFileSync(filePath, 'utf-8');
113
+ const query = {
114
+ sysparm_query: `${config.nameField}=${scriptName}`,
115
+ sysparm_limit: 1
116
+ };
117
+ const response = await this._tableAPI.get(config.table, query);
118
+ if (response.status !== 200 || !response.bodyObject?.result || response.bodyObject.result.length === 0) {
119
+ return {
120
+ scriptName,
121
+ scriptType,
122
+ filePath,
123
+ direction: 'push',
124
+ success: false,
125
+ message: `Script '${scriptName}' not found in ${config.table}`,
126
+ error: `Script not found`,
127
+ timestamp
128
+ };
129
+ }
130
+ const record = response.bodyObject.result[0];
131
+ const sysId = record.sys_id;
132
+ const body = {};
133
+ body[config.scriptField] = scriptContent;
134
+ const putResponse = await this._tableAPI.put(config.table, sysId, body);
135
+ if (!putResponse || (putResponse.status !== 200 && putResponse.status !== 201)) {
136
+ return {
137
+ scriptName,
138
+ scriptType,
139
+ filePath,
140
+ direction: 'push',
141
+ success: false,
142
+ sysId,
143
+ message: `Failed to update ${config.label} '${scriptName}'`,
144
+ error: `Update failed with status: ${putResponse?.status ?? 'unknown'}`,
145
+ timestamp
146
+ };
147
+ }
148
+ this._logger.info(`Successfully pushed '${scriptName}' to ${config.table} (sys_id: ${sysId})`);
149
+ return {
150
+ scriptName,
151
+ scriptType,
152
+ filePath,
153
+ direction: 'push',
154
+ success: true,
155
+ sysId,
156
+ message: `Successfully pushed ${config.label} '${scriptName}'`,
157
+ timestamp
158
+ };
159
+ }
160
+ catch (error) {
161
+ const err = error;
162
+ this._logger.error(`Error pushing script '${scriptName}': ${err.message}`);
163
+ return {
164
+ scriptName,
165
+ scriptType,
166
+ filePath,
167
+ direction: 'push',
168
+ success: false,
169
+ message: `Failed to push ${config.label} '${scriptName}'`,
170
+ error: err.message,
171
+ timestamp
172
+ };
173
+ }
174
+ }
175
+ /**
176
+ * Sync all scripts in a directory. Reads filenames, parses them to determine
177
+ * script name and type, and pushes each to ServiceNow.
178
+ */
179
+ async syncAllScripts(options) {
180
+ const { directory } = options;
181
+ const scriptTypes = options.scriptTypes || Object.keys(SCRIPT_TYPES);
182
+ const timestamp = new Date().toISOString();
183
+ const scripts = [];
184
+ try {
185
+ const files = fs.readdirSync(directory);
186
+ const validFiles = [];
187
+ for (const fileName of files) {
188
+ const parsed = ScriptSync.parseFileName(fileName);
189
+ if (parsed.isValid && parsed.scriptType && scriptTypes.includes(parsed.scriptType)) {
190
+ validFiles.push({ fileName, parsed });
191
+ }
192
+ }
193
+ for (const { fileName, parsed } of validFiles) {
194
+ const filePath = `${directory}/${fileName}`;
195
+ const result = await this.pushScript({
196
+ scriptName: parsed.scriptName,
197
+ scriptType: parsed.scriptType,
198
+ filePath
199
+ });
200
+ scripts.push(result);
201
+ }
202
+ const synced = scripts.filter(s => s.success).length;
203
+ const failed = scripts.filter(s => !s.success).length;
204
+ return {
205
+ directory,
206
+ scriptTypes,
207
+ totalFiles: validFiles.length,
208
+ synced,
209
+ failed,
210
+ scripts,
211
+ timestamp
212
+ };
213
+ }
214
+ catch (error) {
215
+ const err = error;
216
+ this._logger.error(`Error syncing all scripts: ${err.message}`);
217
+ return {
218
+ directory,
219
+ scriptTypes,
220
+ totalFiles: 0,
221
+ synced: 0,
222
+ failed: 0,
223
+ scripts,
224
+ timestamp
225
+ };
226
+ }
227
+ }
228
+ /**
229
+ * Parse a filename in the format "{name}.{type}.js" to extract the script name and type.
230
+ * Valid types are keys of SCRIPT_TYPES.
231
+ */
232
+ static parseFileName(fileName) {
233
+ if (!fileName || typeof fileName !== 'string') {
234
+ return { isValid: false };
235
+ }
236
+ // Expected format: {name}.{type}.js
237
+ // The name may contain dots, so we parse from the end.
238
+ if (!fileName.endsWith('.js')) {
239
+ return { isValid: false };
240
+ }
241
+ // Remove the .js extension
242
+ const withoutExt = fileName.slice(0, -3);
243
+ // Find the last dot to split name from type
244
+ const lastDotIndex = withoutExt.lastIndexOf('.');
245
+ if (lastDotIndex <= 0) {
246
+ return { isValid: false };
247
+ }
248
+ const scriptName = withoutExt.substring(0, lastDotIndex);
249
+ const scriptType = withoutExt.substring(lastDotIndex + 1);
250
+ if (!scriptName || !scriptType || !SCRIPT_TYPES[scriptType]) {
251
+ return { isValid: false };
252
+ }
253
+ return {
254
+ isValid: true,
255
+ scriptName,
256
+ scriptType
257
+ };
258
+ }
259
+ /**
260
+ * Generate a filename in the format "{name}.{type}.js".
261
+ */
262
+ static generateFileName(scriptName, scriptType) {
263
+ return `${scriptName}.${scriptType}.js`;
264
+ }
265
+ }
266
+ //# sourceMappingURL=ScriptSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScriptSync.js","sourceRoot":"","sources":["../../../src/sn/scriptsync/ScriptSync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,EACH,YAAY,EASf,MAAM,oBAAoB,CAAC;AAE5B;;;GAGG;AACH,MAAM,OAAO,UAAU;IACX,OAAO,GAAW,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3C,IAAI,CAAoB;IACxB,SAAS,CAAkB;IAC3B,SAAS,CAAqB;IAEtC,YAAmB,QAA4B;QAC3C,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,UAAU,CAAC,OAA0B;QAC9C,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,MAAM,MAAM,GAAqB,YAAY,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,wBAAwB,UAAU,EAAE;gBAC7C,KAAK,EAAE,wBAAwB,UAAU,EAAE;gBAC3C,SAAS;aACZ,CAAC;QACN,CAAC;QAED,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,KAAK,KAAK,UAAU,iBAAiB,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YAE1F,MAAM,KAAK,GAAoC;gBAC3C,aAAa,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,UAAU,EAAE;gBAClD,aAAa,EAAE,CAAC;aACnB,CAAC;YAEF,MAAM,QAAQ,GAA4C,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAC9E,MAAM,CAAC,KAAK,EACZ,KAAK,CACR,CAAC;YAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrG,OAAO;oBACH,UAAU;oBACV,UAAU;oBACV,QAAQ;oBACR,SAAS,EAAE,MAAM;oBACjB,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,WAAW,UAAU,kBAAkB,MAAM,CAAC,KAAK,EAAE;oBAC9D,KAAK,EAAE,kBAAkB;oBACzB,SAAS;iBACZ,CAAC;YACN,CAAC;YAED,MAAM,MAAM,GAAiB,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM,aAAa,GAAW,MAAM,CAAC,MAAM,CAAC,WAAW,CAAW,IAAI,EAAE,CAAC;YAEzE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAEnD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wBAAwB,UAAU,QAAQ,QAAQ,EAAE,CAAC,CAAC;YAExE,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,MAAM,CAAC,MAAM;gBACpB,OAAO,EAAE,uBAAuB,MAAM,CAAC,KAAK,KAAK,UAAU,GAAG;gBAC9D,SAAS;aACZ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAU,KAAc,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,UAAU,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3E,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,kBAAkB,MAAM,CAAC,KAAK,KAAK,UAAU,GAAG;gBACzD,KAAK,EAAE,GAAG,CAAC,OAAO;gBAClB,SAAS;aACZ,CAAC;QACN,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU,CAAC,OAA0B;QAC9C,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACrD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,MAAM,MAAM,GAAqB,YAAY,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,wBAAwB,UAAU,EAAE;gBAC7C,KAAK,EAAE,wBAAwB,UAAU,EAAE;gBAC3C,SAAS;aACZ,CAAC;QACN,CAAC;QAED,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,UAAU,QAAQ,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAEhE,MAAM,aAAa,GAAW,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEjE,MAAM,KAAK,GAAoC;gBAC3C,aAAa,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,UAAU,EAAE;gBAClD,aAAa,EAAE,CAAC;aACnB,CAAC;YAEF,MAAM,QAAQ,GAA4C,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAC9E,MAAM,CAAC,KAAK,EACZ,KAAK,CACR,CAAC;YAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrG,OAAO;oBACH,UAAU;oBACV,UAAU;oBACV,QAAQ;oBACR,SAAS,EAAE,MAAM;oBACjB,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,WAAW,UAAU,kBAAkB,MAAM,CAAC,KAAK,EAAE;oBAC9D,KAAK,EAAE,kBAAkB;oBACzB,SAAS;iBACZ,CAAC;YACN,CAAC;YAED,MAAM,MAAM,GAAiB,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC3D,MAAM,KAAK,GAAW,MAAM,CAAC,MAAM,CAAC;YAEpC,MAAM,IAAI,GAA2B,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC;YAEzC,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAExE,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,CAAC;gBAC7E,OAAO;oBACH,UAAU;oBACV,UAAU;oBACV,QAAQ;oBACR,SAAS,EAAE,MAAM;oBACjB,OAAO,EAAE,KAAK;oBACd,KAAK;oBACL,OAAO,EAAE,oBAAoB,MAAM,CAAC,KAAK,KAAK,UAAU,GAAG;oBAC3D,KAAK,EAAE,8BAA8B,WAAW,EAAE,MAAM,IAAI,SAAS,EAAE;oBACvE,SAAS;iBACZ,CAAC;YACN,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,wBAAwB,UAAU,QAAQ,MAAM,CAAC,KAAK,aAAa,KAAK,GAAG,CAAC,CAAC;YAE/F,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,IAAI;gBACb,KAAK;gBACL,OAAO,EAAE,uBAAuB,MAAM,CAAC,KAAK,KAAK,UAAU,GAAG;gBAC9D,SAAS;aACZ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAU,KAAc,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,yBAAyB,UAAU,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3E,OAAO;gBACH,UAAU;gBACV,UAAU;gBACV,QAAQ;gBACR,SAAS,EAAE,MAAM;gBACjB,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,kBAAkB,MAAM,CAAC,KAAK,KAAK,UAAU,GAAG;gBACzD,KAAK,EAAE,GAAG,CAAC,OAAO;gBAClB,SAAS;aACZ,CAAC;QACN,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,cAAc,CAAC,OAAuB;QAC/C,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;QAC9B,MAAM,WAAW,GAAa,OAAO,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAiB,EAAE,CAAC;QAEjC,IAAI,CAAC;YACD,MAAM,KAAK,GAAa,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAElD,MAAM,UAAU,GAAmD,EAAE,CAAC;YACtE,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAClD,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;oBACjF,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;YAED,KAAK,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5C,MAAM,QAAQ,GAAG,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC;gBAC5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC;oBACjC,UAAU,EAAE,MAAM,CAAC,UAAW;oBAC9B,UAAU,EAAE,MAAM,CAAC,UAAW;oBAC9B,QAAQ;iBACX,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAED,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YACrD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;YAEtD,OAAO;gBACH,SAAS;gBACT,WAAW;gBACX,UAAU,EAAE,UAAU,CAAC,MAAM;gBAC7B,MAAM;gBACN,MAAM;gBACN,OAAO;gBACP,SAAS;aACZ,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,GAAG,GAAU,KAAc,CAAC;YAClC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAChE,OAAO;gBACH,SAAS;gBACT,WAAW;gBACX,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,CAAC;gBACT,MAAM,EAAE,CAAC;gBACT,OAAO;gBACP,SAAS;aACZ,CAAC;QACN,CAAC;IACL,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,aAAa,CAAC,QAAgB;QACxC,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,oCAAoC;QACpC,uDAAuD;QACvD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,2BAA2B;QAC3B,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEzC,4CAA4C;QAC5C,MAAM,YAAY,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC;QAE1D,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1D,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC9B,CAAC;QAED,OAAO;YACH,OAAO,EAAE,IAAI;YACb,UAAU;YACV,UAAU;SACb,CAAC;IACN,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,gBAAgB,CAAC,UAAkB,EAAE,UAAkB;QACjE,OAAO,GAAG,UAAU,IAAI,UAAU,KAAK,CAAC;IAC5C,CAAC;CACJ"}