@ampsec/platform-client 87.3.0 → 87.5.0
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.
- package/build/src/dto/contexts.dto.d.ts +10 -10
- package/build/src/dto/flows.dto.d.ts +164 -0
- package/build/src/dto/flows.dto.js +3 -0
- package/build/src/dto/flows.dto.js.map +1 -1
- package/build/src/dto/index.d.ts +1 -0
- package/build/src/dto/index.js +1 -0
- package/build/src/dto/index.js.map +1 -1
- package/build/src/dto/platform/platform.contexts.dto.d.ts +8 -8
- package/build/src/dto/platform/platform.flows.dto.d.ts +94 -0
- package/build/src/dto/ruleSet.dto.d.ts +38 -0
- package/build/src/dto/ruleSet.dto.js +18 -0
- package/build/src/dto/ruleSet.dto.js.map +1 -0
- package/build/src/dto/rules.dto.d.ts +233 -16
- package/build/src/dto/rules.dto.js +69 -7
- package/build/src/dto/rules.dto.js.map +1 -1
- package/build/src/services/AmpApi.d.ts +4 -1
- package/build/src/services/AmpApi.js +4 -0
- package/build/src/services/AmpApi.js.map +1 -1
- package/build/src/services/AmpSdk.js +1 -1
- package/build/src/services/AmpSdk.js.map +1 -1
- package/build/src/services/tagSpecs.service.d.ts +17 -3
- package/build/src/services/tagSpecs.service.js +47 -1
- package/build/src/services/tagSpecs.service.js.map +1 -1
- package/package.json +1 -1
- package/src/dto/flows.dto.ts +3 -0
- package/src/dto/index.ts +1 -0
- package/src/dto/ruleSet.dto.ts +19 -0
- package/src/dto/rules.dto.ts +140 -7
- package/src/services/AmpApi.ts +7 -0
- package/src/services/AmpSdk.ts +2 -2
- package/src/services/tagSpecs.service.ts +60 -4
package/src/dto/rules.dto.ts
CHANGED
|
@@ -1,31 +1,90 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
|
|
3
|
-
/* ─── Create / Upsert
|
|
3
|
+
/* ─── Database Input Schemas (Create / Upsert) ──── */
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Flat condition format (backward compatible)
|
|
7
|
+
* Used when submitting simple or flat conditions
|
|
8
|
+
*/
|
|
9
|
+
export const _FlatConditionSchema = z.object({
|
|
10
|
+
type: z.enum(['bool', 'numeric', 'string', 'array', 'datetime']),
|
|
11
|
+
name: z.string(),
|
|
12
|
+
operator: z.string(),
|
|
13
|
+
value: z.any().optional(),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Hierarchical condition group format (new)
|
|
18
|
+
* Supports nested AND/OR logic with unlimited depth
|
|
19
|
+
*/
|
|
20
|
+
export const _ConditionGroupSchema: z.ZodType<any> = z.lazy(() =>
|
|
21
|
+
z.object({
|
|
22
|
+
id: z.string().optional(),
|
|
23
|
+
behavior: z.enum(['any', 'all']),
|
|
24
|
+
sort_order: z.number().default(0),
|
|
25
|
+
conditions: z.array(_FlatConditionSchema).optional(),
|
|
26
|
+
childGroups: z.array(_ConditionGroupSchema).optional(),
|
|
27
|
+
})
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Action format
|
|
32
|
+
* Each action has a type and associated data
|
|
33
|
+
*/
|
|
34
|
+
export const _ActionSchema = z.object({
|
|
35
|
+
action_type: z.enum(['then', 'else']),
|
|
36
|
+
action_data: z.record(z.any()).optional(),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create rule schema - supports both flat and hierarchical conditions
|
|
41
|
+
*/
|
|
4
42
|
export const _CreateRuleSchema = z.object({
|
|
5
|
-
|
|
43
|
+
rule_set_id: z.string(),
|
|
44
|
+
cid: z.string().optional(),
|
|
45
|
+
tid: z.string().optional(),
|
|
6
46
|
priority: z.number().default(0),
|
|
7
|
-
conditions: z.
|
|
8
|
-
|
|
47
|
+
conditions: z.array(_FlatConditionSchema).optional(),
|
|
48
|
+
conditionGroups: z.array(_ConditionGroupSchema).optional(),
|
|
49
|
+
actions: z.array(_ActionSchema).optional(),
|
|
9
50
|
});
|
|
10
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Upsert rule schema - for updates
|
|
54
|
+
*/
|
|
11
55
|
export const _RuleUpsertSchema = z.object({
|
|
12
56
|
id: z.string(),
|
|
13
57
|
priority: z.number().optional(),
|
|
14
|
-
conditions: z.
|
|
15
|
-
|
|
58
|
+
conditions: z.array(_FlatConditionSchema).optional(),
|
|
59
|
+
conditionGroups: z.array(_ConditionGroupSchema).optional(),
|
|
60
|
+
actions: z.array(_ActionSchema).optional(),
|
|
61
|
+
rule_set_id: z.string().optional(),
|
|
16
62
|
});
|
|
17
63
|
|
|
18
64
|
export type CreateRuleDtoSchema = z.infer<typeof _CreateRuleSchema> & {
|
|
19
65
|
tid: string;
|
|
66
|
+
rule_set_id: string;
|
|
20
67
|
};
|
|
21
68
|
|
|
22
69
|
export type RuleUpsertDtoSchema = z.infer<typeof _RuleUpsertSchema>;
|
|
23
70
|
|
|
71
|
+
export type FlatConditionSchema = z.infer<typeof _FlatConditionSchema>;
|
|
72
|
+
export type ConditionGroupSchema = z.infer<typeof _ConditionGroupSchema>;
|
|
73
|
+
export type ActionSchema = z.infer<typeof _ActionSchema>;
|
|
74
|
+
|
|
24
75
|
/* ─── Compiled Rule Types ─────────────────────────────────────────────────
|
|
25
76
|
* Describe the JSON shape produced by RuleService.compileRulesToJson()
|
|
26
77
|
* and consumed by the rules engine.
|
|
78
|
+
*
|
|
79
|
+
* NOTE: The RulesEngine receives COMPILED conditions (CompiledConditionNode),
|
|
80
|
+
* NOT raw database ConditionGroups. The compilation process converts the
|
|
81
|
+
* hierarchical ConditionGroup structure to this CompositeConditions format.
|
|
27
82
|
* ────────────────────────────────────────────────────────────────────────── */
|
|
28
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Leaf condition (single condition)
|
|
86
|
+
* e.g. { type: "string", name: "severity", operator: "equal_to", value: "CRITICAL" }
|
|
87
|
+
*/
|
|
29
88
|
export type CompiledLeafCondition = {
|
|
30
89
|
type: string;
|
|
31
90
|
name: string;
|
|
@@ -33,13 +92,26 @@ export type CompiledLeafCondition = {
|
|
|
33
92
|
value: unknown;
|
|
34
93
|
};
|
|
35
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Composite condition (AND/OR grouping)
|
|
97
|
+
* e.g. { any: [...], all: [...] }
|
|
98
|
+
* Supports unlimited nesting
|
|
99
|
+
*/
|
|
36
100
|
export type CompiledCompositeCondition = {
|
|
37
101
|
any?: CompiledConditionNode[];
|
|
38
102
|
all?: CompiledConditionNode[];
|
|
39
103
|
};
|
|
40
104
|
|
|
105
|
+
/**
|
|
106
|
+
* A condition node is either a leaf condition or composite group
|
|
107
|
+
* Recursive type supporting arbitrary nesting depth
|
|
108
|
+
*/
|
|
41
109
|
export type CompiledConditionNode = CompiledLeafCondition | CompiledCompositeCondition;
|
|
42
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Action payload structure
|
|
113
|
+
* Each action has a type and arbitrary metadata
|
|
114
|
+
*/
|
|
43
115
|
export type CompiledActionData = {
|
|
44
116
|
type: string;
|
|
45
117
|
[key: string]: unknown;
|
|
@@ -53,14 +125,75 @@ export type CompiledActions = {
|
|
|
53
125
|
[action_type: string]: CompiledActionData[];
|
|
54
126
|
};
|
|
55
127
|
|
|
56
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* Compiled rule as produced by compileRulesToJson()
|
|
130
|
+
* This is what RulesEngine.execute() receives
|
|
131
|
+
*/
|
|
57
132
|
export type CompiledRule = {
|
|
133
|
+
id: string;
|
|
58
134
|
priority: number;
|
|
59
135
|
conditions: CompiledConditionNode | null;
|
|
60
136
|
actions: CompiledActions;
|
|
61
137
|
};
|
|
62
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Result type for getRuleSetByRuleIds()
|
|
141
|
+
* Maps rule ID to its compiled ruleset
|
|
142
|
+
*/
|
|
63
143
|
export type RuleSetByIdResult = {
|
|
64
144
|
ruleId: string;
|
|
65
145
|
ruleSet: CompiledRule[];
|
|
66
146
|
};
|
|
147
|
+
|
|
148
|
+
/* ─── Internal Database Types ──────────────────────────────────────────── */
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Database representation of a condition group (hierarchical storage)
|
|
152
|
+
* NOT used by RulesEngine - only internal storage
|
|
153
|
+
*/
|
|
154
|
+
export type ConditionGroupEntity = {
|
|
155
|
+
id: string;
|
|
156
|
+
rule_id: string;
|
|
157
|
+
parent_group_id: string | null;
|
|
158
|
+
behavior: 'any' | 'all';
|
|
159
|
+
sort_order: number;
|
|
160
|
+
conditions?: FlatConditionSchema[];
|
|
161
|
+
childGroups?: ConditionGroupEntity[];
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Database representation of a condition (flat storage)
|
|
166
|
+
* Can be used standalone (legacy) or within a ConditionGroup (new)
|
|
167
|
+
*/
|
|
168
|
+
export type ConditionEntity = {
|
|
169
|
+
id: string;
|
|
170
|
+
rule_id: string;
|
|
171
|
+
condition_group_id?: string | null;
|
|
172
|
+
type: string;
|
|
173
|
+
name: string;
|
|
174
|
+
operator: string;
|
|
175
|
+
value: unknown;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Compilation flow:
|
|
180
|
+
*
|
|
181
|
+
* Database Layer:
|
|
182
|
+
* Rule.conditionGroups: ConditionGroupEntity[] (hierarchical)
|
|
183
|
+
* Rule.conditions: ConditionEntity[] (flat - legacy fallback)
|
|
184
|
+
*
|
|
185
|
+
* ↓ RuleService.compileRulesToJson()
|
|
186
|
+
*
|
|
187
|
+
* Compilation Layer:
|
|
188
|
+
* buildConditionsFromGroups(conditionGroups, conditions)
|
|
189
|
+
* - If conditionGroups exist: recursively build tree via buildGroupNode()
|
|
190
|
+
* - If empty: fallback to flat conditions
|
|
191
|
+
* buildActions() wraps in array-of-arrays
|
|
192
|
+
*
|
|
193
|
+
* ↓ Returns CompiledRule[]
|
|
194
|
+
*
|
|
195
|
+
* RulesEngine Layer:
|
|
196
|
+
* RulesEngine.execute(compiledRules, input)
|
|
197
|
+
* - Processes CompiledConditionNode (any/all nested structure)
|
|
198
|
+
* - Actions are array of arrays: `response.then.push(...rule.actions.then)`
|
|
199
|
+
*/
|
package/src/services/AmpApi.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
NotificationService,
|
|
32
32
|
PredictionService,
|
|
33
33
|
CustomActionsService,
|
|
34
|
+
RulesService,
|
|
34
35
|
} from '.';
|
|
35
36
|
import {KIND, TARGET_API_AGENT} from './constants';
|
|
36
37
|
import {getAmpRestClient, AmpRestClientOptions, AgentIdentityService, ConnectorInstallService, DefaultEnumService, EnumService, RestClient} from './rest';
|
|
@@ -43,6 +44,7 @@ import {TrainingsService} from './trainings.service';
|
|
|
43
44
|
import {AnalyticsService} from './analytics.service';
|
|
44
45
|
import {EngagementLogsService} from './engagementLogs.service';
|
|
45
46
|
import {ConnectorReadinessService} from './connectorReadiness.service';
|
|
47
|
+
import {AmpSdkTagSpecsService} from './tagSpecs.service';
|
|
46
48
|
|
|
47
49
|
export type AmpApiOptions = AmpRestClientOptions;
|
|
48
50
|
|
|
@@ -80,9 +82,11 @@ export class AmpApi {
|
|
|
80
82
|
readonly providers: AmpDataService<ProviderDto>;
|
|
81
83
|
readonly reportResults: AmpDataService<ReportResultDto>;
|
|
82
84
|
readonly reports: AmpReportService;
|
|
85
|
+
readonly rules: RulesService;
|
|
83
86
|
readonly saasAssets: AmpDataService<SaasAssetDto>;
|
|
84
87
|
readonly saasComponents: AmpDataService<SaasComponentDto>;
|
|
85
88
|
readonly saasUsers: AmpDataService<SaasUserDto>;
|
|
89
|
+
readonly tagSpecsService: AmpSdkTagSpecsService;
|
|
86
90
|
readonly settings: AmpSettingsService;
|
|
87
91
|
readonly tenants: AmpEntityService<TenantUpsertDto, TenantDto>;
|
|
88
92
|
readonly tokens: AmpDataService<TokenDto>;
|
|
@@ -117,9 +121,12 @@ export class AmpApi {
|
|
|
117
121
|
this.providers = new AmpDataServiceImpl<ProviderDto>(rest, KIND.PROVIDERS);
|
|
118
122
|
this.reportResults = new AmpDataServiceImpl<ReportResultDto>(rest, KIND.REPORT_RESULTS);
|
|
119
123
|
this.reports = new AmpReportServiceImpl(rest);
|
|
124
|
+
this.rules = new RulesService(rest, KIND.RULES, TARGET_API_AGENT);
|
|
120
125
|
this.saasAssets = new AmpDataServiceImpl<SaasAssetDto>(rest, KIND.SAAS_ASSETS);
|
|
121
126
|
this.saasComponents = new AmpDataServiceImpl<SaasComponentDto>(rest, KIND.SAAS_COMPONENTS);
|
|
122
127
|
this.saasUsers = new AmpDataServiceImpl<SaasUserDto>(rest, KIND.SAAS_USERS);
|
|
128
|
+
//this.tagSpecsService = new TagSpecsService(rest, KIND.TAG_SPECS, TARGET_API_AGENT);
|
|
129
|
+
this.tagSpecsService = new AmpSdkTagSpecsService(rest, KIND.TAG_SPECS, TARGET_API_AGENT);
|
|
123
130
|
this.settings = new AmpSettingsService(rest);
|
|
124
131
|
this.tenants = new AmpEntityServiceImpl<TenantUpsertDto, TenantDto>(rest, KIND.TENANTS);
|
|
125
132
|
this.tokens = new AmpDataServiceImpl<TokenDto>(rest, KIND.TOKENS);
|
package/src/services/AmpSdk.ts
CHANGED
|
@@ -60,7 +60,7 @@ import {
|
|
|
60
60
|
} from './entity.service';
|
|
61
61
|
import {AmpSdkCustomActionsService} from './customActions.platform.service';
|
|
62
62
|
import {AmpRestClientOptions, RestClient, getAmpRestClient} from './rest';
|
|
63
|
-
import {KIND, TARGET_API_PLATFORM} from './constants';
|
|
63
|
+
import {KIND, TARGET_API_AGENT, TARGET_API_PLATFORM} from './constants';
|
|
64
64
|
import {DefaultEnumService, EnumService} from './rest/EnumService';
|
|
65
65
|
import {AmpSdkSettingsService} from './settings.service';
|
|
66
66
|
import {AmpSaaSEntityService, AmpSaaSEntityServiceImpl, AmpSdkSaasAssetService, AmpSdkSaasComponentService, AmpSdkSaasUserService} from './saasEntity.service';
|
|
@@ -176,7 +176,7 @@ export class AmpSdkServices {
|
|
|
176
176
|
this.stagedSaaSUsers = new TruncatableAmpEntityServiceImpl<PlatformStagedSaasUserUpsertDto, PlatformStagedSaasUserDto>(rest, KIND.STAGED_SAAS_USERS, TARGET_API_PLATFORM);
|
|
177
177
|
|
|
178
178
|
this.settings = new AmpSdkSettingsService(rest);
|
|
179
|
-
this.tagSpecs = new AmpSdkTagSpecsService(rest);
|
|
179
|
+
this.tagSpecs = new AmpSdkTagSpecsService(rest, KIND.TAG_SPECS, TARGET_API_AGENT);
|
|
180
180
|
this.tenants = new TenantsService(rest, TARGET_API_PLATFORM);
|
|
181
181
|
this.tenantNotes = new TenantNotesService(rest, TARGET_API_PLATFORM);
|
|
182
182
|
this.tokens = new AmpEntityServiceImpl<PlatformTokenUpsertDto, PlatformTokenDto>(rest, KIND.TOKENS, TARGET_API_PLATFORM);
|
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
// sdk/services/tagSpec.sdk.service.ts
|
|
2
|
-
import {RestClient} from './rest';
|
|
3
|
-
import {TagSpecDto, TagSpecWithRuleSetDto} from '../dto/tagSpecs.dto';
|
|
4
|
-
import {KIND} from './constants';
|
|
2
|
+
import {RestClient, RestResponse} from './rest';
|
|
3
|
+
import {TagSpecDto, TagSpecUpsertDto, TagSpecWithRuleSetDto} from '../dto/tagSpecs.dto';
|
|
4
|
+
import {KIND, TargetApi} from './constants';
|
|
5
5
|
import {Page} from '../dto';
|
|
6
|
+
import {FilterCriteria} from '../FilterCriteria';
|
|
6
7
|
|
|
7
8
|
const TAG_SPECS_PAGE_SIZE = 250;
|
|
8
9
|
|
|
9
10
|
export class AmpSdkTagSpecsService {
|
|
10
11
|
protected readonly rest: RestClient;
|
|
12
|
+
protected readonly targetApi: string;
|
|
13
|
+
protected readonly kind: string;
|
|
11
14
|
|
|
12
|
-
constructor(rest: RestClient) {
|
|
15
|
+
constructor(rest: RestClient, kind?: string, targetApi?: TargetApi) {
|
|
13
16
|
this.rest = rest;
|
|
17
|
+
this.kind = kind || KIND.TAG_SPECS;
|
|
18
|
+
this.targetApi = targetApi || 'platform';
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
async listByTenant(tid: string): Promise<TagSpecWithRuleSetDto[]> {
|
|
@@ -50,4 +55,55 @@ export class AmpSdkTagSpecsService {
|
|
|
50
55
|
|
|
51
56
|
return res.data as TagSpecDto;
|
|
52
57
|
}
|
|
58
|
+
|
|
59
|
+
async create(dto: TagSpecUpsertDto): Promise<RestResponse> {
|
|
60
|
+
return await this.rest.call({
|
|
61
|
+
url: `/${this.targetApi}/v1/${this.kind}`,
|
|
62
|
+
method: 'POST',
|
|
63
|
+
data: dto,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async update(id: string, dto: TagSpecUpsertDto): Promise<RestResponse> {
|
|
68
|
+
return await this.rest.call({
|
|
69
|
+
url: `/${this.targetApi}/v1/${this.kind}/${id}`,
|
|
70
|
+
method: 'PUT',
|
|
71
|
+
data: dto,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async get(id: string): Promise<RestResponse> {
|
|
76
|
+
return await this.rest.call({
|
|
77
|
+
url: `/${this.targetApi}/v1/${this.kind}/${id}`,
|
|
78
|
+
method: 'GET',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async listWithRules(params: {tid?: string; limit?: number; offset?: number}): Promise<RestResponse> {
|
|
83
|
+
const queryParams: Record<string, unknown> = {
|
|
84
|
+
limit: 200,
|
|
85
|
+
...params,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return await this.rest.call({
|
|
89
|
+
url: `/${this.targetApi}/v1/${this.kind}/with-rules`,
|
|
90
|
+
method: 'GET',
|
|
91
|
+
params: queryParams,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async list(params: FilterCriteria): Promise<RestResponse> {
|
|
96
|
+
return await this.rest.call({
|
|
97
|
+
url: `/${this.targetApi}/v1/${this.kind}`,
|
|
98
|
+
method: 'GET',
|
|
99
|
+
params,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async delete(id: string): Promise<RestResponse> {
|
|
104
|
+
return await this.rest.call({
|
|
105
|
+
url: `/${this.targetApi}/v1/${this.kind}/${id}`,
|
|
106
|
+
method: 'DELETE',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
53
109
|
}
|