fg-tracker-mcp 0.7.0 → 0.8.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/CHANGELOG.md +5 -0
- package/README.md +11 -0
- package/dist/infra/tools.js +10 -1
- package/dist/infra/tools.js.map +1 -1
- package/dist/loadtest/routes.d.ts +52 -0
- package/dist/loadtest/routes.js +370 -0
- package/dist/loadtest/routes.js.map +1 -0
- package/dist/loadtest/scenario.d.ts +334 -0
- package/dist/loadtest/scenario.js +501 -0
- package/dist/loadtest/scenario.js.map +1 -0
- package/dist/loadtest/tools.d.ts +128 -0
- package/dist/loadtest/tools.js +378 -0
- package/dist/loadtest/tools.js.map +1 -0
- package/dist/server.d.ts +1 -1
- package/dist/server.js +5 -1
- package/dist/server.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roteiro (`document`) e plano (estilo k6) da Simulação de ambiente — CONTRATO.md §28.2 e §28.3.
|
|
3
|
+
* Esquemas zod com descrições em pt-BR para o agente, validação com caminhos precisos, avisos
|
|
4
|
+
* semânticos (variáveis não definidas, senhas literais, efeitos externos) e presets de plano.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/** Converte "30s", "10m", "1h30m", "500ms" (ou número em segundos) para milissegundos; `null` se inválida. */
|
|
8
|
+
export declare function parseDuration(value: string | number): number | null;
|
|
9
|
+
/** Formata milissegundos no estilo k6: 90000 → "1m30s", 7200000 → "2h", 500 → "500ms". */
|
|
10
|
+
export declare function formatDuration(ms: number): string;
|
|
11
|
+
export declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
12
|
+
export declare const extractSchema: z.ZodObject<{
|
|
13
|
+
var: z.ZodString;
|
|
14
|
+
from: z.ZodEnum<{
|
|
15
|
+
status: "status";
|
|
16
|
+
json: "json";
|
|
17
|
+
header: "header";
|
|
18
|
+
regex: "regex";
|
|
19
|
+
}>;
|
|
20
|
+
path: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
export declare const checkSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
23
|
+
type: z.ZodLiteral<"status">;
|
|
24
|
+
in: z.ZodArray<z.ZodNumber>;
|
|
25
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
26
|
+
type: z.ZodLiteral<"json">;
|
|
27
|
+
path: z.ZodString;
|
|
28
|
+
exists: z.ZodOptional<z.ZodBoolean>;
|
|
29
|
+
equals: z.ZodOptional<z.ZodUnknown>;
|
|
30
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
31
|
+
type: z.ZodLiteral<"bodyContains">;
|
|
32
|
+
value: z.ZodString;
|
|
33
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
34
|
+
type: z.ZodLiteral<"maxDurationMs">;
|
|
35
|
+
value: z.ZodNumber;
|
|
36
|
+
}, z.core.$strict>], "type">;
|
|
37
|
+
export declare const stepSchema: z.ZodObject<{
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
method: z.ZodEnum<{
|
|
40
|
+
GET: "GET";
|
|
41
|
+
POST: "POST";
|
|
42
|
+
PATCH: "PATCH";
|
|
43
|
+
DELETE: "DELETE";
|
|
44
|
+
PUT: "PUT";
|
|
45
|
+
HEAD: "HEAD";
|
|
46
|
+
OPTIONS: "OPTIONS";
|
|
47
|
+
}>;
|
|
48
|
+
path: z.ZodString;
|
|
49
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
50
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
51
|
+
extract: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
52
|
+
var: z.ZodString;
|
|
53
|
+
from: z.ZodEnum<{
|
|
54
|
+
status: "status";
|
|
55
|
+
json: "json";
|
|
56
|
+
header: "header";
|
|
57
|
+
regex: "regex";
|
|
58
|
+
}>;
|
|
59
|
+
path: z.ZodOptional<z.ZodString>;
|
|
60
|
+
}, z.core.$strict>>>;
|
|
61
|
+
checks: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
62
|
+
type: z.ZodLiteral<"status">;
|
|
63
|
+
in: z.ZodArray<z.ZodNumber>;
|
|
64
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
65
|
+
type: z.ZodLiteral<"json">;
|
|
66
|
+
path: z.ZodString;
|
|
67
|
+
exists: z.ZodOptional<z.ZodBoolean>;
|
|
68
|
+
equals: z.ZodOptional<z.ZodUnknown>;
|
|
69
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
70
|
+
type: z.ZodLiteral<"bodyContains">;
|
|
71
|
+
value: z.ZodString;
|
|
72
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
73
|
+
type: z.ZodLiteral<"maxDurationMs">;
|
|
74
|
+
value: z.ZodNumber;
|
|
75
|
+
}, z.core.$strict>], "type">>>;
|
|
76
|
+
thinkTimeMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>>;
|
|
77
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
78
|
+
skipIf: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
79
|
+
}, z.core.$strict>;
|
|
80
|
+
export declare const scenarioSchema: z.ZodObject<{
|
|
81
|
+
version: z.ZodLiteral<1>;
|
|
82
|
+
name: z.ZodString;
|
|
83
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
84
|
+
defaults: z.ZodOptional<z.ZodObject<{
|
|
85
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
86
|
+
timeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
87
|
+
thinkTimeMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>>;
|
|
88
|
+
}, z.core.$strict>>;
|
|
89
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
90
|
+
setup: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
91
|
+
name: z.ZodString;
|
|
92
|
+
method: z.ZodEnum<{
|
|
93
|
+
GET: "GET";
|
|
94
|
+
POST: "POST";
|
|
95
|
+
PATCH: "PATCH";
|
|
96
|
+
DELETE: "DELETE";
|
|
97
|
+
PUT: "PUT";
|
|
98
|
+
HEAD: "HEAD";
|
|
99
|
+
OPTIONS: "OPTIONS";
|
|
100
|
+
}>;
|
|
101
|
+
path: z.ZodString;
|
|
102
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
103
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
104
|
+
extract: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
105
|
+
var: z.ZodString;
|
|
106
|
+
from: z.ZodEnum<{
|
|
107
|
+
status: "status";
|
|
108
|
+
json: "json";
|
|
109
|
+
header: "header";
|
|
110
|
+
regex: "regex";
|
|
111
|
+
}>;
|
|
112
|
+
path: z.ZodOptional<z.ZodString>;
|
|
113
|
+
}, z.core.$strict>>>;
|
|
114
|
+
checks: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
115
|
+
type: z.ZodLiteral<"status">;
|
|
116
|
+
in: z.ZodArray<z.ZodNumber>;
|
|
117
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
118
|
+
type: z.ZodLiteral<"json">;
|
|
119
|
+
path: z.ZodString;
|
|
120
|
+
exists: z.ZodOptional<z.ZodBoolean>;
|
|
121
|
+
equals: z.ZodOptional<z.ZodUnknown>;
|
|
122
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
123
|
+
type: z.ZodLiteral<"bodyContains">;
|
|
124
|
+
value: z.ZodString;
|
|
125
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
126
|
+
type: z.ZodLiteral<"maxDurationMs">;
|
|
127
|
+
value: z.ZodNumber;
|
|
128
|
+
}, z.core.$strict>], "type">>>;
|
|
129
|
+
thinkTimeMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>>;
|
|
130
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
131
|
+
skipIf: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
132
|
+
}, z.core.$strict>>>;
|
|
133
|
+
steps: z.ZodArray<z.ZodObject<{
|
|
134
|
+
name: z.ZodString;
|
|
135
|
+
method: z.ZodEnum<{
|
|
136
|
+
GET: "GET";
|
|
137
|
+
POST: "POST";
|
|
138
|
+
PATCH: "PATCH";
|
|
139
|
+
DELETE: "DELETE";
|
|
140
|
+
PUT: "PUT";
|
|
141
|
+
HEAD: "HEAD";
|
|
142
|
+
OPTIONS: "OPTIONS";
|
|
143
|
+
}>;
|
|
144
|
+
path: z.ZodString;
|
|
145
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
146
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
147
|
+
extract: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
148
|
+
var: z.ZodString;
|
|
149
|
+
from: z.ZodEnum<{
|
|
150
|
+
status: "status";
|
|
151
|
+
json: "json";
|
|
152
|
+
header: "header";
|
|
153
|
+
regex: "regex";
|
|
154
|
+
}>;
|
|
155
|
+
path: z.ZodOptional<z.ZodString>;
|
|
156
|
+
}, z.core.$strict>>>;
|
|
157
|
+
checks: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
158
|
+
type: z.ZodLiteral<"status">;
|
|
159
|
+
in: z.ZodArray<z.ZodNumber>;
|
|
160
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
161
|
+
type: z.ZodLiteral<"json">;
|
|
162
|
+
path: z.ZodString;
|
|
163
|
+
exists: z.ZodOptional<z.ZodBoolean>;
|
|
164
|
+
equals: z.ZodOptional<z.ZodUnknown>;
|
|
165
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
166
|
+
type: z.ZodLiteral<"bodyContains">;
|
|
167
|
+
value: z.ZodString;
|
|
168
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
169
|
+
type: z.ZodLiteral<"maxDurationMs">;
|
|
170
|
+
value: z.ZodNumber;
|
|
171
|
+
}, z.core.$strict>], "type">>>;
|
|
172
|
+
thinkTimeMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>>;
|
|
173
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
174
|
+
skipIf: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
175
|
+
}, z.core.$strict>>;
|
|
176
|
+
teardown: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
177
|
+
name: z.ZodString;
|
|
178
|
+
method: z.ZodEnum<{
|
|
179
|
+
GET: "GET";
|
|
180
|
+
POST: "POST";
|
|
181
|
+
PATCH: "PATCH";
|
|
182
|
+
DELETE: "DELETE";
|
|
183
|
+
PUT: "PUT";
|
|
184
|
+
HEAD: "HEAD";
|
|
185
|
+
OPTIONS: "OPTIONS";
|
|
186
|
+
}>;
|
|
187
|
+
path: z.ZodString;
|
|
188
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
189
|
+
body: z.ZodOptional<z.ZodUnknown>;
|
|
190
|
+
extract: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
191
|
+
var: z.ZodString;
|
|
192
|
+
from: z.ZodEnum<{
|
|
193
|
+
status: "status";
|
|
194
|
+
json: "json";
|
|
195
|
+
header: "header";
|
|
196
|
+
regex: "regex";
|
|
197
|
+
}>;
|
|
198
|
+
path: z.ZodOptional<z.ZodString>;
|
|
199
|
+
}, z.core.$strict>>>;
|
|
200
|
+
checks: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
201
|
+
type: z.ZodLiteral<"status">;
|
|
202
|
+
in: z.ZodArray<z.ZodNumber>;
|
|
203
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
204
|
+
type: z.ZodLiteral<"json">;
|
|
205
|
+
path: z.ZodString;
|
|
206
|
+
exists: z.ZodOptional<z.ZodBoolean>;
|
|
207
|
+
equals: z.ZodOptional<z.ZodUnknown>;
|
|
208
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
209
|
+
type: z.ZodLiteral<"bodyContains">;
|
|
210
|
+
value: z.ZodString;
|
|
211
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
212
|
+
type: z.ZodLiteral<"maxDurationMs">;
|
|
213
|
+
value: z.ZodNumber;
|
|
214
|
+
}, z.core.$strict>], "type">>>;
|
|
215
|
+
thinkTimeMs: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>]>>;
|
|
216
|
+
weight: z.ZodOptional<z.ZodNumber>;
|
|
217
|
+
skipIf: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
218
|
+
}, z.core.$strict>>>;
|
|
219
|
+
}, z.core.$strict>;
|
|
220
|
+
export type LoadtestScenario = z.infer<typeof scenarioSchema>;
|
|
221
|
+
export type LoadtestStep = z.infer<typeof stepSchema>;
|
|
222
|
+
export interface ValidationIssue {
|
|
223
|
+
path: string;
|
|
224
|
+
message: string;
|
|
225
|
+
}
|
|
226
|
+
/** Converte o caminho do zod em notação `steps[1].checks[0].in`. */
|
|
227
|
+
export declare function formatIssuePath(path: ReadonlyArray<PropertyKey>): string;
|
|
228
|
+
export declare function zodIssues(error: z.ZodError): ValidationIssue[];
|
|
229
|
+
export declare const EXTERNAL_EFFECT_RE: RegExp;
|
|
230
|
+
export interface ExternalEffectWarning {
|
|
231
|
+
step: string;
|
|
232
|
+
section: 'setup' | 'steps' | 'teardown';
|
|
233
|
+
method: string;
|
|
234
|
+
path: string;
|
|
235
|
+
reason: string;
|
|
236
|
+
}
|
|
237
|
+
export declare function externalEffect(method: string, path: string): string | null;
|
|
238
|
+
export interface ScenarioSummary {
|
|
239
|
+
name: string;
|
|
240
|
+
baseUrl: string | null;
|
|
241
|
+
setup: string[];
|
|
242
|
+
steps: string[];
|
|
243
|
+
teardown: string[];
|
|
244
|
+
extractedVars: string[];
|
|
245
|
+
checks: number;
|
|
246
|
+
checkTypes: Record<string, number>;
|
|
247
|
+
usesCredentials: boolean;
|
|
248
|
+
externalEffects: ExternalEffectWarning[];
|
|
249
|
+
warnings: string[];
|
|
250
|
+
}
|
|
251
|
+
/** Resumo e avisos semânticos de um roteiro já validado. */
|
|
252
|
+
export declare function summarizeScenario(scenario: LoadtestScenario): ScenarioSummary;
|
|
253
|
+
export type ScenarioValidation = {
|
|
254
|
+
ok: true;
|
|
255
|
+
scenario: LoadtestScenario;
|
|
256
|
+
summary: ScenarioSummary;
|
|
257
|
+
issues: [];
|
|
258
|
+
} | {
|
|
259
|
+
ok: false;
|
|
260
|
+
issues: ValidationIssue[];
|
|
261
|
+
};
|
|
262
|
+
export declare function validateScenario(input: unknown): ScenarioValidation;
|
|
263
|
+
export declare const EXECUTORS: readonly ["constant-vus", "ramping-vus", "constant-arrival-rate", "ramping-arrival-rate", "shared-iterations", "per-vu-iterations"];
|
|
264
|
+
export declare const PRESETS: readonly ["smoke", "load", "stress", "spike", "soak", "breakpoint"];
|
|
265
|
+
export type Preset = (typeof PRESETS)[number];
|
|
266
|
+
export declare const planSchema: z.ZodObject<{
|
|
267
|
+
executor: z.ZodEnum<{
|
|
268
|
+
"constant-vus": "constant-vus";
|
|
269
|
+
"ramping-vus": "ramping-vus";
|
|
270
|
+
"constant-arrival-rate": "constant-arrival-rate";
|
|
271
|
+
"ramping-arrival-rate": "ramping-arrival-rate";
|
|
272
|
+
"shared-iterations": "shared-iterations";
|
|
273
|
+
"per-vu-iterations": "per-vu-iterations";
|
|
274
|
+
}>;
|
|
275
|
+
vus: z.ZodOptional<z.ZodNumber>;
|
|
276
|
+
duration: z.ZodOptional<z.ZodString>;
|
|
277
|
+
stages: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
278
|
+
duration: z.ZodString;
|
|
279
|
+
target: z.ZodNumber;
|
|
280
|
+
}, z.core.$strict>>>;
|
|
281
|
+
rate: z.ZodOptional<z.ZodNumber>;
|
|
282
|
+
timeUnit: z.ZodOptional<z.ZodString>;
|
|
283
|
+
preAllocatedVUs: z.ZodOptional<z.ZodNumber>;
|
|
284
|
+
maxVUs: z.ZodOptional<z.ZodNumber>;
|
|
285
|
+
iterations: z.ZodOptional<z.ZodNumber>;
|
|
286
|
+
gracefulStop: z.ZodOptional<z.ZodString>;
|
|
287
|
+
thresholds: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>;
|
|
288
|
+
abortOnFail: z.ZodOptional<z.ZodBoolean>;
|
|
289
|
+
preset: z.ZodOptional<z.ZodEnum<{
|
|
290
|
+
custom: "custom";
|
|
291
|
+
smoke: "smoke";
|
|
292
|
+
load: "load";
|
|
293
|
+
stress: "stress";
|
|
294
|
+
spike: "spike";
|
|
295
|
+
soak: "soak";
|
|
296
|
+
breakpoint: "breakpoint";
|
|
297
|
+
}>>;
|
|
298
|
+
}, z.core.$strict>;
|
|
299
|
+
export type LoadtestPlan = z.infer<typeof planSchema>;
|
|
300
|
+
export type PlanValidation = {
|
|
301
|
+
ok: true;
|
|
302
|
+
plan: LoadtestPlan;
|
|
303
|
+
issues: [];
|
|
304
|
+
} | {
|
|
305
|
+
ok: false;
|
|
306
|
+
issues: ValidationIssue[];
|
|
307
|
+
};
|
|
308
|
+
export declare function validatePlan(input: unknown): PlanValidation;
|
|
309
|
+
export interface PlanShape {
|
|
310
|
+
executor: string;
|
|
311
|
+
/** Pico de VUs (arrival-rate: maxVUs ou preAllocatedVUs). */
|
|
312
|
+
peakVus: number;
|
|
313
|
+
/** Pico de iterações por segundo (só arrival-rate). */
|
|
314
|
+
peakIterationsPerSecond: number | null;
|
|
315
|
+
/** Duração total estimada em ms (sem gracefulStop; iterations: null). */
|
|
316
|
+
durationMs: number | null;
|
|
317
|
+
duration: string;
|
|
318
|
+
}
|
|
319
|
+
/** Pico de VUs/taxa e duração de um plano válido (para confirmação e avisos). */
|
|
320
|
+
export declare function describePlan(plan: LoadtestPlan): PlanShape;
|
|
321
|
+
export interface PresetOptions {
|
|
322
|
+
vus?: number;
|
|
323
|
+
/** Alvo de iterações por segundo; com ele os presets usam executores arrival-rate. */
|
|
324
|
+
targetRps?: number;
|
|
325
|
+
duration?: string;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Plano sugerido para cada preset (§28.3), no espírito dos tipos de teste do k6:
|
|
329
|
+
* smoke (1–5 VUs, 1 min), load (rampa + platô), stress (degraus acima do normal), spike (salto súbito),
|
|
330
|
+
* soak (carga média por horas) e breakpoint (rampa de arrival-rate até quebrar, abortOnFail).
|
|
331
|
+
*/
|
|
332
|
+
export declare function presetPlan(preset: Preset, options?: PresetOptions): LoadtestPlan;
|
|
333
|
+
/** Avisos sobre um plano (tamanho, duração, ausência de thresholds). */
|
|
334
|
+
export declare function planWarnings(plan: LoadtestPlan): string[];
|