@sonisoft/now-sdk-ext-core 2.4.0 → 2.5.2

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 (43) hide show
  1. package/README.md +96 -27
  2. package/dist/index.d.ts +10 -0
  3. package/dist/index.js +10 -0
  4. package/dist/index.js.map +1 -1
  5. package/dist/sn/aggregate/AggregateModels.d.ts +89 -0
  6. package/dist/sn/aggregate/AggregateModels.js +5 -0
  7. package/dist/sn/aggregate/AggregateModels.js.map +1 -0
  8. package/dist/sn/aggregate/AggregateQuery.d.ts +50 -0
  9. package/dist/sn/aggregate/AggregateQuery.js +144 -0
  10. package/dist/sn/aggregate/AggregateQuery.js.map +1 -0
  11. package/dist/sn/batch/QueryBatchModels.d.ts +93 -0
  12. package/dist/sn/batch/QueryBatchModels.js +5 -0
  13. package/dist/sn/batch/QueryBatchModels.js.map +1 -0
  14. package/dist/sn/batch/QueryBatchOperations.d.ts +41 -0
  15. package/dist/sn/batch/QueryBatchOperations.js +195 -0
  16. package/dist/sn/batch/QueryBatchOperations.js.map +1 -0
  17. package/dist/sn/cmdb/CMDBModels.d.ts +141 -0
  18. package/dist/sn/cmdb/CMDBModels.js +5 -0
  19. package/dist/sn/cmdb/CMDBModels.js.map +1 -0
  20. package/dist/sn/cmdb/CMDBRelationships.d.ts +60 -0
  21. package/dist/sn/cmdb/CMDBRelationships.js +286 -0
  22. package/dist/sn/cmdb/CMDBRelationships.js.map +1 -0
  23. package/dist/sn/discovery/DiscoveryModels.d.ts +160 -0
  24. package/dist/sn/discovery/DiscoveryModels.js +5 -0
  25. package/dist/sn/discovery/DiscoveryModels.js.map +1 -0
  26. package/dist/sn/discovery/InstanceDiscovery.d.ts +45 -0
  27. package/dist/sn/discovery/InstanceDiscovery.js +163 -0
  28. package/dist/sn/discovery/InstanceDiscovery.js.map +1 -0
  29. package/dist/sn/health/HealthModels.d.ts +124 -0
  30. package/dist/sn/health/HealthModels.js +5 -0
  31. package/dist/sn/health/HealthModels.js.map +1 -0
  32. package/dist/sn/health/InstanceHealth.d.ts +58 -0
  33. package/dist/sn/health/InstanceHealth.js +221 -0
  34. package/dist/sn/health/InstanceHealth.js.map +1 -0
  35. package/dist/sn/scope/ScopeManager.d.ts +7 -7
  36. package/dist/sn/scope/ScopeManager.js +19 -14
  37. package/dist/sn/scope/ScopeManager.js.map +1 -1
  38. package/dist/sn/scope/ScopeModels.d.ts +9 -3
  39. package/dist/sn/updateset/UpdateSetManager.d.ts +3 -3
  40. package/dist/sn/updateset/UpdateSetManager.js +12 -7
  41. package/dist/sn/updateset/UpdateSetManager.js.map +1 -1
  42. package/dist/sn/updateset/UpdateSetModels.d.ts +11 -0
  43. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBatchModels.js","sourceRoot":"","sources":["../../../src/sn/batch/QueryBatchModels.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D"}
@@ -0,0 +1,41 @@
1
+ import { ServiceNowInstance } from "../ServiceNowInstance.js";
2
+ import { QueryUpdateOptions, QueryDeleteOptions, QueryUpdateResult, QueryDeleteResult } from './QueryBatchModels.js';
3
+ /**
4
+ * QueryBatchOperations provides query-based bulk update and delete operations.
5
+ * Records are found by encoded query, then updated or deleted in bulk.
6
+ * Includes a dry-run mode (default) for safe previewing before execution.
7
+ */
8
+ export declare class QueryBatchOperations {
9
+ private static readonly DEFAULT_LIMIT;
10
+ private static readonly MAX_LIMIT;
11
+ private _logger;
12
+ private _req;
13
+ private _tableAPI;
14
+ private _instance;
15
+ private _headers;
16
+ constructor(instance: ServiceNowInstance);
17
+ /**
18
+ * Find records matching a query and update them with the provided data.
19
+ * Defaults to dry-run mode (confirm=false) which returns match count without executing.
20
+ *
21
+ * @param options Query update options
22
+ * @returns QueryUpdateResult with match count, update count, and any errors
23
+ * @throws Error if table, query, or data is empty
24
+ */
25
+ queryUpdate(options: QueryUpdateOptions): Promise<QueryUpdateResult>;
26
+ /**
27
+ * Find records matching a query and delete them.
28
+ * Defaults to dry-run mode (confirm=false) which returns match count without executing.
29
+ *
30
+ * @param options Query delete options
31
+ * @returns QueryDeleteResult with match count, delete count, and any errors
32
+ * @throws Error if table or query is empty
33
+ */
34
+ queryDelete(options: QueryDeleteOptions): Promise<QueryDeleteResult>;
35
+ /**
36
+ * Find records matching a query and return their sys_ids.
37
+ * Only fetches sys_id field for efficiency.
38
+ * @private
39
+ */
40
+ private _findMatchingRecords;
41
+ }
@@ -0,0 +1,195 @@
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
+ * QueryBatchOperations provides query-based bulk update and delete operations.
6
+ * Records are found by encoded query, then updated or deleted in bulk.
7
+ * Includes a dry-run mode (default) for safe previewing before execution.
8
+ */
9
+ export class QueryBatchOperations {
10
+ static DEFAULT_LIMIT = 200;
11
+ static MAX_LIMIT = 10000;
12
+ _logger = new Logger("QueryBatchOperations");
13
+ _req;
14
+ _tableAPI;
15
+ _instance;
16
+ _headers = {
17
+ "Content-Type": "application/json",
18
+ "Accept": "application/json"
19
+ };
20
+ constructor(instance) {
21
+ this._instance = instance;
22
+ this._req = new ServiceNowRequest(instance);
23
+ this._tableAPI = new TableAPIRequest(instance);
24
+ }
25
+ /**
26
+ * Find records matching a query and update them with the provided data.
27
+ * Defaults to dry-run mode (confirm=false) which returns match count without executing.
28
+ *
29
+ * @param options Query update options
30
+ * @returns QueryUpdateResult with match count, update count, and any errors
31
+ * @throws Error if table, query, or data is empty
32
+ */
33
+ async queryUpdate(options) {
34
+ const startTime = Date.now();
35
+ if (!options.table || options.table.trim().length === 0) {
36
+ throw new Error('Table name is required');
37
+ }
38
+ if (!options.query || options.query.trim().length === 0) {
39
+ throw new Error('Query is required');
40
+ }
41
+ if (!options.data || Object.keys(options.data).length === 0) {
42
+ throw new Error('Update data is required and must not be empty');
43
+ }
44
+ const limit = Math.min(options.limit ?? QueryBatchOperations.DEFAULT_LIMIT, QueryBatchOperations.MAX_LIMIT);
45
+ const isDryRun = options.confirm !== true;
46
+ this._logger.info(`Query update on '${options.table}' with query '${options.query}' (dryRun=${isDryRun}, limit=${limit})`);
47
+ // Step 1: Find matching records
48
+ const matchingSysIds = await this._findMatchingRecords(options.table, options.query, limit);
49
+ const matchCount = matchingSysIds.length;
50
+ if (options.onProgress) {
51
+ options.onProgress(`Found ${matchCount} matching records in '${options.table}'`);
52
+ }
53
+ // Step 2: Dry run - return count only
54
+ if (isDryRun) {
55
+ this._logger.info(`Dry run: ${matchCount} records would be updated in '${options.table}'`);
56
+ return {
57
+ dryRun: true,
58
+ matchCount,
59
+ updatedCount: 0,
60
+ success: true,
61
+ errors: [],
62
+ executionTimeMs: Date.now() - startTime
63
+ };
64
+ }
65
+ // Step 3: Execute updates
66
+ const errors = [];
67
+ let updatedCount = 0;
68
+ for (let i = 0; i < matchingSysIds.length; i++) {
69
+ const sysId = matchingSysIds[i];
70
+ try {
71
+ const response = await this._tableAPI.put(options.table, sysId, options.data);
72
+ if (response && response.status === 200) {
73
+ updatedCount++;
74
+ }
75
+ else {
76
+ errors.push({ sysId, error: `Update failed with status: ${response?.status ?? 'unknown'}` });
77
+ }
78
+ }
79
+ catch (err) {
80
+ const errorMsg = err instanceof Error ? err.message : String(err);
81
+ errors.push({ sysId, error: errorMsg });
82
+ }
83
+ if (options.onProgress && (i + 1) % 50 === 0) {
84
+ options.onProgress(`Updated ${updatedCount}/${matchCount} records (${errors.length} errors)`);
85
+ }
86
+ }
87
+ if (options.onProgress) {
88
+ options.onProgress(`Update complete: ${updatedCount} updated, ${errors.length} errors`);
89
+ }
90
+ return {
91
+ dryRun: false,
92
+ matchCount,
93
+ updatedCount,
94
+ success: errors.length === 0,
95
+ errors,
96
+ executionTimeMs: Date.now() - startTime
97
+ };
98
+ }
99
+ /**
100
+ * Find records matching a query and delete them.
101
+ * Defaults to dry-run mode (confirm=false) which returns match count without executing.
102
+ *
103
+ * @param options Query delete options
104
+ * @returns QueryDeleteResult with match count, delete count, and any errors
105
+ * @throws Error if table or query is empty
106
+ */
107
+ async queryDelete(options) {
108
+ const startTime = Date.now();
109
+ if (!options.table || options.table.trim().length === 0) {
110
+ throw new Error('Table name is required');
111
+ }
112
+ if (!options.query || options.query.trim().length === 0) {
113
+ throw new Error('Query is required');
114
+ }
115
+ const limit = Math.min(options.limit ?? QueryBatchOperations.DEFAULT_LIMIT, QueryBatchOperations.MAX_LIMIT);
116
+ const isDryRun = options.confirm !== true;
117
+ this._logger.info(`Query delete on '${options.table}' with query '${options.query}' (dryRun=${isDryRun}, limit=${limit})`);
118
+ // Step 1: Find matching records
119
+ const matchingSysIds = await this._findMatchingRecords(options.table, options.query, limit);
120
+ const matchCount = matchingSysIds.length;
121
+ if (options.onProgress) {
122
+ options.onProgress(`Found ${matchCount} matching records in '${options.table}'`);
123
+ }
124
+ // Step 2: Dry run - return count only
125
+ if (isDryRun) {
126
+ this._logger.info(`Dry run: ${matchCount} records would be deleted from '${options.table}'`);
127
+ return {
128
+ dryRun: true,
129
+ matchCount,
130
+ deletedCount: 0,
131
+ success: true,
132
+ errors: [],
133
+ executionTimeMs: Date.now() - startTime
134
+ };
135
+ }
136
+ // Step 3: Execute deletes
137
+ const errors = [];
138
+ let deletedCount = 0;
139
+ for (let i = 0; i < matchingSysIds.length; i++) {
140
+ const sysId = matchingSysIds[i];
141
+ try {
142
+ const request = {
143
+ path: `/api/now/table/${options.table}/${sysId}`,
144
+ method: 'delete',
145
+ headers: this._headers,
146
+ query: null,
147
+ body: null
148
+ };
149
+ const response = await this._req.executeRequest(request);
150
+ if (response && (response.status === 200 || response.status === 204)) {
151
+ deletedCount++;
152
+ }
153
+ else {
154
+ errors.push({ sysId, error: `Delete failed with status: ${response?.status ?? 'unknown'}` });
155
+ }
156
+ }
157
+ catch (err) {
158
+ const errorMsg = err instanceof Error ? err.message : String(err);
159
+ errors.push({ sysId, error: errorMsg });
160
+ }
161
+ if (options.onProgress && (i + 1) % 50 === 0) {
162
+ options.onProgress(`Deleted ${deletedCount}/${matchCount} records (${errors.length} errors)`);
163
+ }
164
+ }
165
+ if (options.onProgress) {
166
+ options.onProgress(`Delete complete: ${deletedCount} deleted, ${errors.length} errors`);
167
+ }
168
+ return {
169
+ dryRun: false,
170
+ matchCount,
171
+ deletedCount,
172
+ success: errors.length === 0,
173
+ errors,
174
+ executionTimeMs: Date.now() - startTime
175
+ };
176
+ }
177
+ /**
178
+ * Find records matching a query and return their sys_ids.
179
+ * Only fetches sys_id field for efficiency.
180
+ * @private
181
+ */
182
+ async _findMatchingRecords(table, query, limit) {
183
+ const queryParams = {
184
+ sysparm_query: query,
185
+ sysparm_limit: limit,
186
+ sysparm_fields: 'sys_id'
187
+ };
188
+ const response = await this._tableAPI.get(table, queryParams);
189
+ if (response && response.status === 200 && response.bodyObject?.result) {
190
+ return response.bodyObject.result.map(r => r.sys_id);
191
+ }
192
+ throw new Error(`Failed to query records in table '${table}'. Status: ${response?.status ?? 'unknown'}`);
193
+ }
194
+ }
195
+ //# sourceMappingURL=QueryBatchOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBatchOperations.js","sourceRoot":"","sources":["../../../src/sn/batch/QueryBatchOperations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Direction of relationship traversal.
3
+ */
4
+ export type TraversalDirection = 'upstream' | 'downstream' | 'both';
5
+ /**
6
+ * Options for getting direct relationships of a CI.
7
+ */
8
+ export interface GetRelationshipsOptions {
9
+ /** The sys_id of the CI to get relationships for (required) */
10
+ ciSysId: string;
11
+ /** Direction of traversal. Defaults to 'both'. */
12
+ direction?: TraversalDirection;
13
+ /** Optional relationship type filter (name from cmdb_rel_type) */
14
+ relationType?: string;
15
+ /** Maximum number of relationships to return. Defaults to 100. */
16
+ limit?: number;
17
+ }
18
+ /**
19
+ * Options for traversing the CMDB relationship graph.
20
+ */
21
+ export interface TraverseGraphOptions {
22
+ /** The sys_id of the starting CI (required) */
23
+ ciSysId: string;
24
+ /** Direction of traversal. Defaults to 'downstream'. */
25
+ direction?: TraversalDirection;
26
+ /** Maximum traversal depth. Defaults to 3. Max allowed: 5. */
27
+ maxDepth?: number;
28
+ /** Optional relationship type filter */
29
+ relationType?: string;
30
+ /** Maximum total CIs to visit. Defaults to 200. Max allowed: 1000. */
31
+ maxNodes?: number;
32
+ }
33
+ /**
34
+ * A CI record from the CMDB.
35
+ */
36
+ export interface CMDBCIRecord {
37
+ /** The system ID */
38
+ sys_id: string;
39
+ /** The CI name */
40
+ name?: string;
41
+ /** The CI class (table name) */
42
+ sys_class_name?: string;
43
+ /** Additional fields */
44
+ [key: string]: unknown;
45
+ }
46
+ /**
47
+ * A relationship record from cmdb_rel_ci.
48
+ */
49
+ export interface CMDBRelationshipRecord {
50
+ /** The system ID of the relationship */
51
+ sys_id: string;
52
+ /** The parent CI sys_id */
53
+ parent: string | {
54
+ link: string;
55
+ value: string;
56
+ display_value?: string;
57
+ };
58
+ /** The child CI sys_id */
59
+ child: string | {
60
+ link: string;
61
+ value: string;
62
+ display_value?: string;
63
+ };
64
+ /** The relationship type */
65
+ type: string | {
66
+ link: string;
67
+ value: string;
68
+ display_value?: string;
69
+ };
70
+ /** Additional fields */
71
+ [key: string]: unknown;
72
+ }
73
+ /**
74
+ * A node in the relationship graph.
75
+ */
76
+ export interface GraphNode {
77
+ /** The CI sys_id */
78
+ sysId: string;
79
+ /** The CI name */
80
+ name: string;
81
+ /** The CI class */
82
+ className: string;
83
+ /** Depth from the starting CI (0 = root) */
84
+ depth: number;
85
+ }
86
+ /**
87
+ * An edge in the relationship graph.
88
+ */
89
+ export interface GraphEdge {
90
+ /** Parent CI sys_id */
91
+ parentSysId: string;
92
+ /** Child CI sys_id */
93
+ childSysId: string;
94
+ /** Relationship type name */
95
+ typeName: string;
96
+ /** Relationship sys_id */
97
+ relationshipSysId: string;
98
+ }
99
+ /**
100
+ * Result of getting direct relationships.
101
+ */
102
+ export interface RelationshipsResult {
103
+ /** The queried CI */
104
+ ci: CMDBCIRecord;
105
+ /** Direct relationships */
106
+ relationships: Array<{
107
+ /** The related CI */
108
+ relatedCI: CMDBCIRecord;
109
+ /** Direction: 'upstream' (this CI is child) or 'downstream' (this CI is parent) */
110
+ direction: 'upstream' | 'downstream';
111
+ /** Relationship type name */
112
+ typeName: string;
113
+ /** Relationship record sys_id */
114
+ relationshipSysId: string;
115
+ }>;
116
+ }
117
+ /**
118
+ * Result of a full graph traversal.
119
+ */
120
+ export interface GraphTraversalResult {
121
+ /** The starting CI */
122
+ rootCI: CMDBCIRecord;
123
+ /** All nodes visited in the graph */
124
+ nodes: GraphNode[];
125
+ /** All edges discovered in the graph */
126
+ edges: GraphEdge[];
127
+ /** Total number of API calls made */
128
+ apiCallCount: number;
129
+ /** Whether the traversal was truncated due to maxDepth or maxNodes */
130
+ truncated: boolean;
131
+ /** Reason for truncation if truncated is true */
132
+ truncationReason?: string;
133
+ }
134
+ /** Response from cmdb_ci query. */
135
+ export interface CMDBCIResponse {
136
+ result: CMDBCIRecord[];
137
+ }
138
+ /** Response from cmdb_rel_ci query. */
139
+ export interface CMDBRelResponse {
140
+ result: CMDBRelationshipRecord[];
141
+ }
@@ -0,0 +1,5 @@
1
+ // ============================================================
2
+ // Options Types
3
+ // ============================================================
4
+ export {};
5
+ //# sourceMappingURL=CMDBModels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CMDBModels.js","sourceRoot":"","sources":["../../../src/sn/cmdb/CMDBModels.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,gBAAgB;AAChB,+DAA+D"}
@@ -0,0 +1,60 @@
1
+ import { ServiceNowInstance } from "../ServiceNowInstance.js";
2
+ import { GetRelationshipsOptions, TraverseGraphOptions, RelationshipsResult, GraphTraversalResult } from './CMDBModels.js';
3
+ /**
4
+ * CMDBRelationships provides methods for querying and traversing
5
+ * CMDB relationship graphs. Supports single-level lookups and
6
+ * multi-level BFS traversal with configurable depth and direction.
7
+ */
8
+ export declare class CMDBRelationships {
9
+ private static readonly CMDB_CI_TABLE;
10
+ private static readonly CMDB_REL_CI_TABLE;
11
+ private static readonly MAX_DEPTH;
12
+ private static readonly MAX_NODES;
13
+ private _logger;
14
+ private _tableAPI;
15
+ private _instance;
16
+ /** Cache for CI records to minimize API calls during traversal */
17
+ private _ciCache;
18
+ constructor(instance: ServiceNowInstance);
19
+ /**
20
+ * Get direct relationships of a CI (single level).
21
+ *
22
+ * @param options Relationship query options
23
+ * @returns RelationshipsResult with the CI and its direct relationships
24
+ * @throws Error if ciSysId is empty
25
+ */
26
+ getRelationships(options: GetRelationshipsOptions): Promise<RelationshipsResult>;
27
+ /**
28
+ * Traverse the CMDB relationship graph using BFS starting from a CI.
29
+ *
30
+ * @param options Traversal options
31
+ * @returns GraphTraversalResult with all nodes, edges, and metadata
32
+ * @throws Error if ciSysId is empty
33
+ */
34
+ traverseGraph(options: TraverseGraphOptions): Promise<GraphTraversalResult>;
35
+ /**
36
+ * Look up a single CI by sys_id. Uses cache when available.
37
+ * @private
38
+ */
39
+ private _lookupCI;
40
+ /**
41
+ * Batch look up multiple CIs by sys_id.
42
+ * @private
43
+ */
44
+ private _batchLookupCIs;
45
+ /**
46
+ * Query relationships from cmdb_rel_ci.
47
+ * @private
48
+ */
49
+ private _queryRelationships;
50
+ /**
51
+ * Extract sys_id from a field that may be a string or reference object.
52
+ * @private
53
+ */
54
+ private _extractSysId;
55
+ /**
56
+ * Extract display value or value from a field.
57
+ * @private
58
+ */
59
+ private _extractDisplayValue;
60
+ }