@sdods/contracts 0.7.2 → 0.9.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/dist/.tsbuildinfo +1 -1
- package/dist/names.d.ts +31 -0
- package/dist/names.js +33 -0
- package/dist/schemas/env.d.ts +55 -0
- package/dist/schemas/env.js +21 -1
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/load.d.ts +84 -0
- package/dist/schemas/load.js +92 -0
- package/dist/schemas/matrix.d.ts +45 -0
- package/dist/schemas/matrix.js +44 -0
- package/dist/schemas/project.d.ts +186 -4
- package/dist/schemas/project.js +214 -3
- package/dist/types.d.ts +160 -0
- package/package.json +1 -1
package/dist/schemas/env.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { EvidencePatchSchema, HealConfigSchema, PerfBudgetsSchema, ScreenshotConfigSchema, TimeoutsSchema, } from './project.js';
|
|
2
|
+
import { A11yPatchSchema, EvidencePatchSchema, HealConfigSchema, PerfBudgetsSchema, ScreenshotConfigSchema, TimeoutsSchema, } from './project.js';
|
|
3
|
+
import { EnvLoadSchema } from './load.js';
|
|
3
4
|
export const ApiAuthSchema = z.discriminatedUnion('type', [
|
|
4
5
|
z.object({ type: z.literal('none') }),
|
|
5
6
|
z.object({ type: z.literal('bearer'), token: z.string() }),
|
|
@@ -24,6 +25,21 @@ export const EnvUseSchema = z.object({
|
|
|
24
25
|
extraHTTPHeaders: z.record(z.string(), z.string()).optional(),
|
|
25
26
|
httpCredentials: z.object({ username: z.string(), password: z.string() }).optional(),
|
|
26
27
|
});
|
|
28
|
+
/**
|
|
29
|
+
* The mail catcher the email steps read. Only Mailpit today: MailHog's API hands back raw MIME
|
|
30
|
+
* (quoted-printable, nested multiparts) and is unmaintained, so an enum value for it would be a
|
|
31
|
+
* half-working promise. `auth.password` trips the secret-literal check, so it must be `${VAR}`.
|
|
32
|
+
*/
|
|
33
|
+
export const MailConfigSchema = z.object({
|
|
34
|
+
provider: z.enum(['mailpit']).default('mailpit'),
|
|
35
|
+
url: z.string().url(),
|
|
36
|
+
auth: z
|
|
37
|
+
.object({ type: z.literal('basic'), username: z.string(), password: z.string() })
|
|
38
|
+
.optional(),
|
|
39
|
+
pollIntervalMs: z.number().int().positive().default(1000),
|
|
40
|
+
clockSkewMs: z.number().int().nonnegative().default(2000),
|
|
41
|
+
timeoutSeconds: z.number().int().positive().default(15),
|
|
42
|
+
});
|
|
27
43
|
export const EnvConfigSchema = z.object({
|
|
28
44
|
name: z.string().min(1),
|
|
29
45
|
description: z.string().optional(),
|
|
@@ -36,6 +52,7 @@ export const EnvConfigSchema = z.object({
|
|
|
36
52
|
}),
|
|
37
53
|
aliases: z.array(z.string().url()).default([]),
|
|
38
54
|
db: z.object({ driver: z.enum(['sqlite', 'postgres']), url: z.string() }).optional(),
|
|
55
|
+
mail: MailConfigSchema.optional(),
|
|
39
56
|
users: z.object({ poolSize: z.number().int().positive().optional() }).default({}),
|
|
40
57
|
vars: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).default({}),
|
|
41
58
|
use: EnvUseSchema.default({}),
|
|
@@ -44,6 +61,9 @@ export const EnvConfigSchema = z.object({
|
|
|
44
61
|
heal: HealConfigSchema.partial().optional(),
|
|
45
62
|
timeouts: TimeoutsSchema.partial().optional(),
|
|
46
63
|
perf: z.object({ budgets: PerfBudgetsSchema.partial() }).optional(),
|
|
64
|
+
a11y: A11yPatchSchema.optional(),
|
|
47
65
|
ci: z.boolean().optional(),
|
|
66
|
+
/** Opt-in for `sdods load`; absent means load tests are refused. */
|
|
67
|
+
load: EnvLoadSchema.optional(),
|
|
48
68
|
});
|
|
49
69
|
//# sourceMappingURL=env.js.map
|
package/dist/schemas/index.d.ts
CHANGED
package/dist/schemas/index.js
CHANGED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Load testing is opt-in per environment. Load against a shared or production environment is
|
|
4
|
+
* destructive, and load against an environment that caps writes measures the cap rather than the
|
|
5
|
+
* system, so `sdods load` refuses to run unless the environment says `load.allowed: true`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const EnvLoadSchema: z.ZodObject<{
|
|
8
|
+
allowed: z.ZodDefault<z.ZodBoolean>;
|
|
9
|
+
maxVus: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
allowWrites: z.ZodDefault<z.ZodBoolean>;
|
|
11
|
+
allowBaseUrlOverride: z.ZodDefault<z.ZodBoolean>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
/** k6 duration: `30s`, `1m30s`, `500ms`, `2h`. */
|
|
14
|
+
export declare const K6DurationSchema: z.ZodString;
|
|
15
|
+
export declare const LOAD_READ_METHODS: readonly ["GET", "HEAD", "OPTIONS"];
|
|
16
|
+
export declare const LOAD_METHODS: readonly ["GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH", "DELETE"];
|
|
17
|
+
export declare const LoadRequestSchema: z.ZodObject<{
|
|
18
|
+
name: z.ZodOptional<z.ZodString>;
|
|
19
|
+
method: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodEnum<{
|
|
20
|
+
GET: "GET";
|
|
21
|
+
HEAD: "HEAD";
|
|
22
|
+
OPTIONS: "OPTIONS";
|
|
23
|
+
POST: "POST";
|
|
24
|
+
PUT: "PUT";
|
|
25
|
+
PATCH: "PATCH";
|
|
26
|
+
DELETE: "DELETE";
|
|
27
|
+
}>>>;
|
|
28
|
+
path: z.ZodString;
|
|
29
|
+
headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
30
|
+
body: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodUnknown>]>>;
|
|
31
|
+
expect: z.ZodDefault<z.ZodObject<{
|
|
32
|
+
status: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>, z.ZodTransform<number[], number | number[]>>;
|
|
33
|
+
bodyContains: z.ZodOptional<z.ZodString>;
|
|
34
|
+
maxDurationMs: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, z.core.$strip>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export declare const LoadStageSchema: z.ZodObject<{
|
|
38
|
+
duration: z.ZodString;
|
|
39
|
+
target: z.ZodNumber;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
/** `projects/<slug>/load/<name>.yaml` */
|
|
42
|
+
export declare const LoadProfileSchema: z.ZodObject<{
|
|
43
|
+
description: z.ZodOptional<z.ZodString>;
|
|
44
|
+
auth: z.ZodDefault<z.ZodEnum<{
|
|
45
|
+
env: "env";
|
|
46
|
+
none: "none";
|
|
47
|
+
}>>;
|
|
48
|
+
thinkTimeSeconds: z.ZodDefault<z.ZodNumber>;
|
|
49
|
+
vus: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
duration: z.ZodOptional<z.ZodString>;
|
|
51
|
+
iterations: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
stages: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
53
|
+
duration: z.ZodString;
|
|
54
|
+
target: z.ZodNumber;
|
|
55
|
+
}, z.core.$strip>>>;
|
|
56
|
+
thresholds: z.ZodPipe<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>, z.ZodTransform<{
|
|
57
|
+
[k: string]: string[];
|
|
58
|
+
}, Record<string, string | string[]>>>;
|
|
59
|
+
requests: z.ZodArray<z.ZodObject<{
|
|
60
|
+
name: z.ZodOptional<z.ZodString>;
|
|
61
|
+
method: z.ZodDefault<z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodEnum<{
|
|
62
|
+
GET: "GET";
|
|
63
|
+
HEAD: "HEAD";
|
|
64
|
+
OPTIONS: "OPTIONS";
|
|
65
|
+
POST: "POST";
|
|
66
|
+
PUT: "PUT";
|
|
67
|
+
PATCH: "PATCH";
|
|
68
|
+
DELETE: "DELETE";
|
|
69
|
+
}>>>;
|
|
70
|
+
path: z.ZodString;
|
|
71
|
+
headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
72
|
+
body: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>, z.ZodArray<z.ZodUnknown>]>>;
|
|
73
|
+
expect: z.ZodDefault<z.ZodObject<{
|
|
74
|
+
status: z.ZodPipe<z.ZodDefault<z.ZodUnion<readonly [z.ZodNumber, z.ZodArray<z.ZodNumber>]>>, z.ZodTransform<number[], number | number[]>>;
|
|
75
|
+
bodyContains: z.ZodOptional<z.ZodString>;
|
|
76
|
+
maxDurationMs: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
}, z.core.$strip>>;
|
|
78
|
+
}, z.core.$strip>>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
export type EnvLoadConfig = z.infer<typeof EnvLoadSchema>;
|
|
81
|
+
export type LoadRequest = z.infer<typeof LoadRequestSchema>;
|
|
82
|
+
export type LoadProfile = z.infer<typeof LoadProfileSchema>;
|
|
83
|
+
export type LoadProfileInput = z.input<typeof LoadProfileSchema>;
|
|
84
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Load testing is opt-in per environment. Load against a shared or production environment is
|
|
4
|
+
* destructive, and load against an environment that caps writes measures the cap rather than the
|
|
5
|
+
* system, so `sdods load` refuses to run unless the environment says `load.allowed: true`.
|
|
6
|
+
*/
|
|
7
|
+
export const EnvLoadSchema = z.object({
|
|
8
|
+
/** The environment is sized for load and owned by the team running it. */
|
|
9
|
+
allowed: z.boolean().default(false),
|
|
10
|
+
/** Refuse profiles whose peak virtual users exceed this. */
|
|
11
|
+
maxVus: z.number().int().positive().optional(),
|
|
12
|
+
/** Allow POST, PUT, PATCH and DELETE requests; read-only profiles need nothing. */
|
|
13
|
+
allowWrites: z.boolean().default(false),
|
|
14
|
+
/**
|
|
15
|
+
* Let `SDODS_API_BASE_URL` send the load somewhere other than this file's `api.baseUrl`. Off by
|
|
16
|
+
* default: the opt-in is for this environment, and a stray override would load another host.
|
|
17
|
+
*/
|
|
18
|
+
allowBaseUrlOverride: z.boolean().default(false),
|
|
19
|
+
});
|
|
20
|
+
/** k6 duration: `30s`, `1m30s`, `500ms`, `2h`. */
|
|
21
|
+
export const K6DurationSchema = z
|
|
22
|
+
.string()
|
|
23
|
+
.regex(/^(\d+(\.\d+)?(ms|s|m|h))+$/, 'expected a k6 duration such as 30s, 1m30s or 500ms');
|
|
24
|
+
export const LOAD_READ_METHODS = ['GET', 'HEAD', 'OPTIONS'];
|
|
25
|
+
export const LOAD_METHODS = [...LOAD_READ_METHODS, 'POST', 'PUT', 'PATCH', 'DELETE'];
|
|
26
|
+
export const LoadRequestSchema = z.object({
|
|
27
|
+
/** Shown in k6 output and used as the request's `name` tag. Defaults to `METHOD path`. */
|
|
28
|
+
name: z.string().min(1).optional(),
|
|
29
|
+
method: z
|
|
30
|
+
.string()
|
|
31
|
+
.transform((m) => m.toUpperCase())
|
|
32
|
+
.pipe(z.enum(LOAD_METHODS))
|
|
33
|
+
.default('GET'),
|
|
34
|
+
/** Relative to the environment's `api.baseUrl`; absolute URLs are refused. */
|
|
35
|
+
path: z
|
|
36
|
+
.string()
|
|
37
|
+
.min(1)
|
|
38
|
+
.refine((p) => p.startsWith('/'), 'path must start with "/" (it is relative to api.baseUrl)'),
|
|
39
|
+
headers: z.record(z.string(), z.string()).default({}),
|
|
40
|
+
/** A string is sent as-is; an object or array is sent as JSON. `${VAR}` reads `__ENV`. */
|
|
41
|
+
body: z.union([z.string(), z.record(z.string(), z.unknown()), z.array(z.unknown())]).optional(),
|
|
42
|
+
expect: z
|
|
43
|
+
.object({
|
|
44
|
+
status: z
|
|
45
|
+
.union([z.number().int(), z.array(z.number().int()).min(1)])
|
|
46
|
+
.default(200)
|
|
47
|
+
.transform((s) => (Array.isArray(s) ? s : [s])),
|
|
48
|
+
bodyContains: z.string().optional(),
|
|
49
|
+
maxDurationMs: z.number().positive().optional(),
|
|
50
|
+
})
|
|
51
|
+
.default({ status: [200] }),
|
|
52
|
+
});
|
|
53
|
+
export const LoadStageSchema = z.object({
|
|
54
|
+
duration: K6DurationSchema,
|
|
55
|
+
target: z.number().int().nonnegative(),
|
|
56
|
+
});
|
|
57
|
+
/** `projects/<slug>/load/<name>.yaml` */
|
|
58
|
+
export const LoadProfileSchema = z
|
|
59
|
+
.object({
|
|
60
|
+
description: z.string().optional(),
|
|
61
|
+
/** `env` sends the environment's `api.auth` and `api.headers`; `none` sends neither. */
|
|
62
|
+
auth: z.enum(['env', 'none']).default('env'),
|
|
63
|
+
/** Pause between iterations of one virtual user, in seconds. */
|
|
64
|
+
thinkTimeSeconds: z.number().nonnegative().default(1),
|
|
65
|
+
vus: z.number().int().positive().optional(),
|
|
66
|
+
duration: K6DurationSchema.optional(),
|
|
67
|
+
iterations: z.number().int().positive().optional(),
|
|
68
|
+
stages: z.array(LoadStageSchema).min(1).optional(),
|
|
69
|
+
/** k6 thresholds, e.g. `http_req_duration: ['p(95)<500']`. A single string is accepted. */
|
|
70
|
+
thresholds: z
|
|
71
|
+
.record(z.string(), z.union([z.string(), z.array(z.string()).min(1)]))
|
|
72
|
+
.default({})
|
|
73
|
+
.transform((t) => Object.fromEntries(Object.entries(t).map(([k, v]) => [k, Array.isArray(v) ? v : [v]]))),
|
|
74
|
+
requests: z.array(LoadRequestSchema).min(1),
|
|
75
|
+
})
|
|
76
|
+
.superRefine((p, ctx) => {
|
|
77
|
+
if (p.stages && (p.duration || p.iterations || p.vus)) {
|
|
78
|
+
ctx.addIssue({
|
|
79
|
+
code: 'custom',
|
|
80
|
+
path: ['stages'],
|
|
81
|
+
message: 'use either stages, or vus with duration or iterations — not both',
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (!p.stages && !(p.vus && (p.duration || p.iterations))) {
|
|
85
|
+
ctx.addIssue({
|
|
86
|
+
code: 'custom',
|
|
87
|
+
path: ['vus'],
|
|
88
|
+
message: 'set stages, or vus with duration or iterations',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* `projects/<slug>/roles.matrix.yaml` — the expected outcome of each role on each surface.
|
|
4
|
+
*
|
|
5
|
+
* `sdods matrix expand` turns every `@matrix:<name>` Scenario Outline into one `Examples:` block per
|
|
6
|
+
* role, tagged `@user:<role>`, so an actor × surface grid is data rather than hundreds of
|
|
7
|
+
* hand-written scenarios. Only the shape lives here; cross-field rules (every row has the same
|
|
8
|
+
* columns, every role resolves to an outcome, `expect` keys are declared roles) are checked by
|
|
9
|
+
* `loadRolesMatrices` in @sdods/core so they can be reported as lint findings.
|
|
10
|
+
*/
|
|
11
|
+
export declare const ROLES_MATRIX_FILE = "roles.matrix.yaml";
|
|
12
|
+
/** A matrix name as it appears in `@matrix:<name>`. Checked by the loader for a readable message. */
|
|
13
|
+
export declare const MATRIX_NAME_RE: RegExp;
|
|
14
|
+
export declare const RolesMatrixRowSchema: z.ZodObject<{
|
|
15
|
+
expect: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
16
|
+
default: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
18
|
+
export declare const RolesMatrixSchema: z.ZodObject<{
|
|
19
|
+
description: z.ZodOptional<z.ZodString>;
|
|
20
|
+
roles: z.ZodArray<z.ZodString>;
|
|
21
|
+
default: z.ZodOptional<z.ZodString>;
|
|
22
|
+
outcomes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
|
+
title: z.ZodOptional<z.ZodString>;
|
|
24
|
+
rows: z.ZodArray<z.ZodObject<{
|
|
25
|
+
expect: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
26
|
+
default: z.ZodOptional<z.ZodString>;
|
|
27
|
+
}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
28
|
+
}, z.core.$strict>;
|
|
29
|
+
export declare const RolesMatrixFileSchema: z.ZodObject<{
|
|
30
|
+
matrices: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
31
|
+
description: z.ZodOptional<z.ZodString>;
|
|
32
|
+
roles: z.ZodArray<z.ZodString>;
|
|
33
|
+
default: z.ZodOptional<z.ZodString>;
|
|
34
|
+
outcomes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
title: z.ZodOptional<z.ZodString>;
|
|
36
|
+
rows: z.ZodArray<z.ZodObject<{
|
|
37
|
+
expect: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
|
|
38
|
+
default: z.ZodOptional<z.ZodString>;
|
|
39
|
+
}, z.core.$catchall<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>>;
|
|
40
|
+
}, z.core.$strict>>;
|
|
41
|
+
}, z.core.$strict>;
|
|
42
|
+
export type RolesMatrixRowInput = z.infer<typeof RolesMatrixRowSchema>;
|
|
43
|
+
export type RolesMatrixInput = z.infer<typeof RolesMatrixSchema>;
|
|
44
|
+
export type RolesMatrixFile = z.infer<typeof RolesMatrixFileSchema>;
|
|
45
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* `projects/<slug>/roles.matrix.yaml` — the expected outcome of each role on each surface.
|
|
4
|
+
*
|
|
5
|
+
* `sdods matrix expand` turns every `@matrix:<name>` Scenario Outline into one `Examples:` block per
|
|
6
|
+
* role, tagged `@user:<role>`, so an actor × surface grid is data rather than hundreds of
|
|
7
|
+
* hand-written scenarios. Only the shape lives here; cross-field rules (every row has the same
|
|
8
|
+
* columns, every role resolves to an outcome, `expect` keys are declared roles) are checked by
|
|
9
|
+
* `loadRolesMatrices` in @sdods/core so they can be reported as lint findings.
|
|
10
|
+
*/
|
|
11
|
+
export const ROLES_MATRIX_FILE = 'roles.matrix.yaml';
|
|
12
|
+
/** A matrix name as it appears in `@matrix:<name>`. Checked by the loader for a readable message. */
|
|
13
|
+
export const MATRIX_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
14
|
+
const MatrixCellSchema = z.union([z.string(), z.number(), z.boolean()]);
|
|
15
|
+
export const RolesMatrixRowSchema = z
|
|
16
|
+
.object({
|
|
17
|
+
/** One outcome for every role, or a per-role map; roles left out fall back to `default`. */
|
|
18
|
+
expect: z.union([z.string().min(1), z.record(z.string(), z.string().min(1))]).optional(),
|
|
19
|
+
/** Outcome for the roles this row's `expect` map does not name. Overrides the matrix default. */
|
|
20
|
+
default: z.string().min(1).optional(),
|
|
21
|
+
})
|
|
22
|
+
// Every other key is an Examples column (`surface: /settings/billing` → `<surface>`).
|
|
23
|
+
.catchall(MatrixCellSchema);
|
|
24
|
+
export const RolesMatrixSchema = z
|
|
25
|
+
.object({
|
|
26
|
+
description: z.string().optional(),
|
|
27
|
+
/** The actors, in the order their Examples blocks are written. Each must be a declared role. */
|
|
28
|
+
roles: z.array(z.string().regex(/^[^\s@|]+$/, 'a role cannot contain spaces, @ or |')).min(1),
|
|
29
|
+
/** Outcome for any role a row does not name. */
|
|
30
|
+
default: z.string().min(1).optional(),
|
|
31
|
+
/** When set, every outcome must be one of these (catches `alowed`). */
|
|
32
|
+
outcomes: z.array(z.string().min(1)).min(1).optional(),
|
|
33
|
+
/** Example title, written as the `# title-format:` of each generated block. Must use `<role>` and every row column, so titles are unique. */
|
|
34
|
+
title: z.string().min(1).optional(),
|
|
35
|
+
rows: z.array(RolesMatrixRowSchema).min(1),
|
|
36
|
+
})
|
|
37
|
+
.strict();
|
|
38
|
+
export const RolesMatrixFileSchema = z
|
|
39
|
+
.object({
|
|
40
|
+
/** Keys are matrix names (`MATRIX_NAME_RE`), referenced as `@matrix:<name>`. */
|
|
41
|
+
matrices: z.record(z.string(), RolesMatrixSchema),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -48,15 +48,19 @@ export declare const UserPoolSchema: z.ZodObject<{
|
|
|
48
48
|
roleColumn: z.ZodDefault<z.ZodString>;
|
|
49
49
|
leaseStore: z.ZodDefault<z.ZodEnum<{
|
|
50
50
|
file: "file";
|
|
51
|
-
db: "db";
|
|
52
51
|
}>>;
|
|
53
52
|
leaseTtlMs: z.ZodDefault<z.ZodNumber>;
|
|
54
53
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
55
54
|
exclusive: "exclusive";
|
|
56
55
|
shared: "shared";
|
|
57
56
|
}>>;
|
|
58
|
-
waitMs: z.
|
|
57
|
+
waitMs: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
leaseScope: z.ZodDefault<z.ZodEnum<{
|
|
59
|
+
scenario: "scenario";
|
|
60
|
+
worker: "worker";
|
|
61
|
+
}>>;
|
|
59
62
|
}, z.core.$strip>;
|
|
63
|
+
export type UserPoolConfig = z.infer<typeof UserPoolSchema>;
|
|
60
64
|
export declare const AuthStrategySchema: z.ZodEnum<{
|
|
61
65
|
custom: "custom";
|
|
62
66
|
none: "none";
|
|
@@ -106,6 +110,14 @@ export declare const ProjectAuthSchema: z.ZodObject<{
|
|
|
106
110
|
prefix: z.ZodDefault<z.ZodString>;
|
|
107
111
|
}, z.core.$strip>>;
|
|
108
112
|
}, z.core.$strip>;
|
|
113
|
+
/**
|
|
114
|
+
* Settings for one named visual baseline (`the page should match the visual baseline "<name>"`).
|
|
115
|
+
* `mask` is added to the project/env `screenshots.mask`, never a replacement for it.
|
|
116
|
+
*/
|
|
117
|
+
export declare const BaselineConfigSchema: z.ZodObject<{
|
|
118
|
+
mask: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
119
|
+
maxDiffPixelRatio: z.ZodOptional<z.ZodNumber>;
|
|
120
|
+
}, z.core.$strip>;
|
|
109
121
|
export declare const ScreenshotConfigSchema: z.ZodObject<{
|
|
110
122
|
policy: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
111
123
|
visual: "visual";
|
|
@@ -116,6 +128,11 @@ export declare const ScreenshotConfigSchema: z.ZodObject<{
|
|
|
116
128
|
}>>>;
|
|
117
129
|
fullPage: z.ZodDefault<z.ZodBoolean>;
|
|
118
130
|
mask: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
131
|
+
maxDiffPixelRatio: z.ZodDefault<z.ZodNumber>;
|
|
132
|
+
baselines: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
133
|
+
mask: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
134
|
+
maxDiffPixelRatio: z.ZodOptional<z.ZodNumber>;
|
|
135
|
+
}, z.core.$strip>>>;
|
|
119
136
|
viewport: z.ZodDefault<z.ZodObject<{
|
|
120
137
|
width: z.ZodNumber;
|
|
121
138
|
height: z.ZodNumber;
|
|
@@ -229,6 +246,43 @@ export declare const EVIDENCE_DEFAULTS: {
|
|
|
229
246
|
readonly trace: "on-first-retry";
|
|
230
247
|
readonly redactTraces: true;
|
|
231
248
|
};
|
|
249
|
+
/**
|
|
250
|
+
* Selectors the canvas steps (`canvas.steps.ts`) use to find nodes, handles, edges, node fields and
|
|
251
|
+
* badges on a graph editor. The defaults are the DOM React Flow (v11 and v12) renders; a project on
|
|
252
|
+
* another editor, or with its own markers, overrides only the keys that differ.
|
|
253
|
+
*
|
|
254
|
+
* Values are CSS selector templates. `{id}`, `{handle}`, `{source}`, `{target}`, `{field}` and
|
|
255
|
+
* `{badge}` are replaced by the step argument, escaped for a quoted CSS string, so write them inside
|
|
256
|
+
* quotes: `[data-id="{id}"]`. `{testIdAttribute}` is replaced by the project's attribute name.
|
|
257
|
+
*/
|
|
258
|
+
export declare const CANVAS_DEFAULTS: {
|
|
259
|
+
/** The editor surface; every other lookup is scoped inside it. */
|
|
260
|
+
readonly root: ".react-flow";
|
|
261
|
+
/** Every node, for counting. */
|
|
262
|
+
readonly nodes: ".react-flow__node";
|
|
263
|
+
/** One node by id. */
|
|
264
|
+
readonly node: ".react-flow__node[data-id=\"{id}\"]";
|
|
265
|
+
/** A handle, searched inside its node. */
|
|
266
|
+
readonly handle: ".react-flow__handle[data-handleid=\"{handle}\"]";
|
|
267
|
+
/** An edge by source and target node id. React Flow's default edge aria-label. */
|
|
268
|
+
readonly edge: ".react-flow__edge[aria-label=\"Edge from {source} to {target}\"]";
|
|
269
|
+
/** A field, searched inside its node. A wrapper is fine: the editable control inside it is filled. */
|
|
270
|
+
readonly field: "[name=\"{field}\"], [aria-label=\"{field}\"], [{testIdAttribute}=\"{field}\"]";
|
|
271
|
+
/** A badge, searched inside its node. */
|
|
272
|
+
readonly badge: "[{testIdAttribute}=\"{badge}\"]";
|
|
273
|
+
/** What a node matches once selected; `I select the node` waits for it. Empty skips the check. */
|
|
274
|
+
readonly selected: ".selected";
|
|
275
|
+
};
|
|
276
|
+
export declare const CanvasConfigSchema: z.ZodDefault<z.ZodObject<{
|
|
277
|
+
root: z.ZodDefault<z.ZodString>;
|
|
278
|
+
nodes: z.ZodDefault<z.ZodString>;
|
|
279
|
+
node: z.ZodDefault<z.ZodString>;
|
|
280
|
+
handle: z.ZodDefault<z.ZodString>;
|
|
281
|
+
edge: z.ZodDefault<z.ZodString>;
|
|
282
|
+
field: z.ZodDefault<z.ZodString>;
|
|
283
|
+
badge: z.ZodDefault<z.ZodString>;
|
|
284
|
+
selected: z.ZodDefault<z.ZodString>;
|
|
285
|
+
}, z.core.$strip>>;
|
|
232
286
|
/**
|
|
233
287
|
* Scenarios that must pass before anything else in the run starts: probes, login, seeding.
|
|
234
288
|
*
|
|
@@ -252,6 +306,45 @@ export declare const PerfBudgetsSchema: z.ZodObject<{
|
|
|
252
306
|
ttfbMs: z.ZodOptional<z.ZodNumber>;
|
|
253
307
|
apiP95Ms: z.ZodOptional<z.ZodNumber>;
|
|
254
308
|
}, z.core.$strip>;
|
|
309
|
+
/** axe impact levels, weakest first. Mirrored by `IMPACT_ORDER` in core's a11y audit. */
|
|
310
|
+
export declare const A11yImpactSchema: z.ZodEnum<{
|
|
311
|
+
minor: "minor";
|
|
312
|
+
moderate: "moderate";
|
|
313
|
+
serious: "serious";
|
|
314
|
+
critical: "critical";
|
|
315
|
+
}>;
|
|
316
|
+
/**
|
|
317
|
+
* The audit every `@a11y` UI or hybrid scenario gets at its end.
|
|
318
|
+
*
|
|
319
|
+
* `failOn` is the weakest impact that fails the scenario: `serious` fails on serious and critical
|
|
320
|
+
* violations and reports the rest. `include` narrows the audit to these selectors, `exclude` leaves
|
|
321
|
+
* these selectors out (a third-party widget the team does not own, for instance). Both are passed
|
|
322
|
+
* to axe as they are, so a selector that matches nothing in `include` fails the audit rather than
|
|
323
|
+
* scanning an empty page.
|
|
324
|
+
*/
|
|
325
|
+
export declare const A11yConfigSchema: z.ZodObject<{
|
|
326
|
+
failOn: z.ZodDefault<z.ZodEnum<{
|
|
327
|
+
minor: "minor";
|
|
328
|
+
moderate: "moderate";
|
|
329
|
+
serious: "serious";
|
|
330
|
+
critical: "critical";
|
|
331
|
+
}>>;
|
|
332
|
+
include: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
333
|
+
exclude: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
334
|
+
}, z.core.$strip>;
|
|
335
|
+
/** The env-level patch: every key optional and default-free, for the reason `EvidencePatchSchema` gives. */
|
|
336
|
+
export declare const A11yPatchSchema: z.ZodObject<{
|
|
337
|
+
failOn: z.ZodOptional<z.ZodEnum<{
|
|
338
|
+
minor: "minor";
|
|
339
|
+
moderate: "moderate";
|
|
340
|
+
serious: "serious";
|
|
341
|
+
critical: "critical";
|
|
342
|
+
}>>;
|
|
343
|
+
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
344
|
+
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
345
|
+
}, z.core.$strip>;
|
|
346
|
+
/** Branch names `integrations.github.evidence.branch` refuses: prune force-rewrites the branch. */
|
|
347
|
+
export declare const EVIDENCE_PROTECTED_BRANCHES: string[];
|
|
255
348
|
export declare const GitHubIntegrationSchema: z.ZodObject<{
|
|
256
349
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
257
350
|
owner: z.ZodOptional<z.ZodString>;
|
|
@@ -267,6 +360,19 @@ export declare const GitHubIntegrationSchema: z.ZodObject<{
|
|
|
267
360
|
labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
268
361
|
tokenEnv: z.ZodDefault<z.ZodString>;
|
|
269
362
|
uploadToRelease: z.ZodOptional<z.ZodString>;
|
|
363
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
364
|
+
host: z.ZodDefault<z.ZodEnum<{
|
|
365
|
+
none: "none";
|
|
366
|
+
branch: "branch";
|
|
367
|
+
}>>;
|
|
368
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
369
|
+
branch: z.ZodDefault<z.ZodString>;
|
|
370
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
371
|
+
maxFileBytes: z.ZodDefault<z.ZodNumber>;
|
|
372
|
+
maxRunBytes: z.ZodDefault<z.ZodNumber>;
|
|
373
|
+
retainDays: z.ZodDefault<z.ZodNumber>;
|
|
374
|
+
gifPreview: z.ZodDefault<z.ZodBoolean>;
|
|
375
|
+
}, z.core.$strip>>;
|
|
270
376
|
}, z.core.$strip>;
|
|
271
377
|
export declare const JiraIntegrationSchema: z.ZodObject<{
|
|
272
378
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -305,6 +411,19 @@ export declare const IntegrationsSchema: z.ZodObject<{
|
|
|
305
411
|
labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
306
412
|
tokenEnv: z.ZodDefault<z.ZodString>;
|
|
307
413
|
uploadToRelease: z.ZodOptional<z.ZodString>;
|
|
414
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
415
|
+
host: z.ZodDefault<z.ZodEnum<{
|
|
416
|
+
none: "none";
|
|
417
|
+
branch: "branch";
|
|
418
|
+
}>>;
|
|
419
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
420
|
+
branch: z.ZodDefault<z.ZodString>;
|
|
421
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
422
|
+
maxFileBytes: z.ZodDefault<z.ZodNumber>;
|
|
423
|
+
maxRunBytes: z.ZodDefault<z.ZodNumber>;
|
|
424
|
+
retainDays: z.ZodDefault<z.ZodNumber>;
|
|
425
|
+
gifPreview: z.ZodDefault<z.ZodBoolean>;
|
|
426
|
+
}, z.core.$strip>>;
|
|
308
427
|
}, z.core.$strip>>;
|
|
309
428
|
jira: z.ZodOptional<z.ZodObject<{
|
|
310
429
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -442,6 +561,17 @@ export declare const ScheduleSchema: z.ZodObject<{
|
|
|
442
561
|
}>>>;
|
|
443
562
|
retentionRuns: z.ZodOptional<z.ZodNumber>;
|
|
444
563
|
}, z.core.$strip>;
|
|
564
|
+
/**
|
|
565
|
+
* Requirement traceability (`@req:<id>` tags → `sdods report traceability`).
|
|
566
|
+
*
|
|
567
|
+
* The id is opaque: SDODS does not decide whether it names a Jira story, a line in a requirements
|
|
568
|
+
* document or a clause of a regulation. That choice belongs to whoever signs the export.
|
|
569
|
+
*/
|
|
570
|
+
export declare const TraceabilitySchema: z.ZodObject<{
|
|
571
|
+
requirements: z.ZodOptional<z.ZodString>;
|
|
572
|
+
link: z.ZodOptional<z.ZodString>;
|
|
573
|
+
require: z.ZodDefault<z.ZodBoolean>;
|
|
574
|
+
}, z.core.$strip>;
|
|
445
575
|
/**
|
|
446
576
|
* Hierarchy: organization → workspace → project → module.
|
|
447
577
|
* A module is a feature area of an application (auth, inventory, checkout …) that owns a
|
|
@@ -688,6 +818,16 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
688
818
|
}, z.core.$strip>>;
|
|
689
819
|
}, z.core.$strip>>;
|
|
690
820
|
routes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
821
|
+
canvas: z.ZodDefault<z.ZodObject<{
|
|
822
|
+
root: z.ZodDefault<z.ZodString>;
|
|
823
|
+
nodes: z.ZodDefault<z.ZodString>;
|
|
824
|
+
node: z.ZodDefault<z.ZodString>;
|
|
825
|
+
handle: z.ZodDefault<z.ZodString>;
|
|
826
|
+
edge: z.ZodDefault<z.ZodString>;
|
|
827
|
+
field: z.ZodDefault<z.ZodString>;
|
|
828
|
+
badge: z.ZodDefault<z.ZodString>;
|
|
829
|
+
selected: z.ZodDefault<z.ZodString>;
|
|
830
|
+
}, z.core.$strip>>;
|
|
691
831
|
tags: z.ZodDefault<z.ZodObject<{
|
|
692
832
|
suites: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
693
833
|
extra: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
@@ -725,14 +865,17 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
725
865
|
roleColumn: z.ZodDefault<z.ZodString>;
|
|
726
866
|
leaseStore: z.ZodDefault<z.ZodEnum<{
|
|
727
867
|
file: "file";
|
|
728
|
-
db: "db";
|
|
729
868
|
}>>;
|
|
730
869
|
leaseTtlMs: z.ZodDefault<z.ZodNumber>;
|
|
731
870
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
732
871
|
exclusive: "exclusive";
|
|
733
872
|
shared: "shared";
|
|
734
873
|
}>>;
|
|
735
|
-
waitMs: z.
|
|
874
|
+
waitMs: z.ZodOptional<z.ZodNumber>;
|
|
875
|
+
leaseScope: z.ZodDefault<z.ZodEnum<{
|
|
876
|
+
scenario: "scenario";
|
|
877
|
+
worker: "worker";
|
|
878
|
+
}>>;
|
|
736
879
|
}, z.core.$strip>>;
|
|
737
880
|
}, z.core.$strip>>;
|
|
738
881
|
auth: z.ZodDefault<z.ZodObject<{
|
|
@@ -778,6 +921,11 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
778
921
|
}>>>;
|
|
779
922
|
fullPage: z.ZodDefault<z.ZodBoolean>;
|
|
780
923
|
mask: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
924
|
+
maxDiffPixelRatio: z.ZodDefault<z.ZodNumber>;
|
|
925
|
+
baselines: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
926
|
+
mask: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
927
|
+
maxDiffPixelRatio: z.ZodOptional<z.ZodNumber>;
|
|
928
|
+
}, z.core.$strip>>>;
|
|
781
929
|
viewport: z.ZodDefault<z.ZodObject<{
|
|
782
930
|
width: z.ZodNumber;
|
|
783
931
|
height: z.ZodNumber;
|
|
@@ -850,6 +998,16 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
850
998
|
apiP95Ms: z.ZodOptional<z.ZodNumber>;
|
|
851
999
|
}, z.core.$strip>>;
|
|
852
1000
|
}, z.core.$strip>>;
|
|
1001
|
+
a11y: z.ZodDefault<z.ZodObject<{
|
|
1002
|
+
failOn: z.ZodDefault<z.ZodEnum<{
|
|
1003
|
+
minor: "minor";
|
|
1004
|
+
moderate: "moderate";
|
|
1005
|
+
serious: "serious";
|
|
1006
|
+
critical: "critical";
|
|
1007
|
+
}>>;
|
|
1008
|
+
include: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1009
|
+
exclude: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1010
|
+
}, z.core.$strip>>;
|
|
853
1011
|
integrations: z.ZodDefault<z.ZodObject<{
|
|
854
1012
|
github: z.ZodOptional<z.ZodObject<{
|
|
855
1013
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -866,6 +1024,19 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
866
1024
|
labels: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
867
1025
|
tokenEnv: z.ZodDefault<z.ZodString>;
|
|
868
1026
|
uploadToRelease: z.ZodOptional<z.ZodString>;
|
|
1027
|
+
evidence: z.ZodOptional<z.ZodObject<{
|
|
1028
|
+
host: z.ZodDefault<z.ZodEnum<{
|
|
1029
|
+
none: "none";
|
|
1030
|
+
branch: "branch";
|
|
1031
|
+
}>>;
|
|
1032
|
+
repo: z.ZodOptional<z.ZodString>;
|
|
1033
|
+
branch: z.ZodDefault<z.ZodString>;
|
|
1034
|
+
tokenEnv: z.ZodOptional<z.ZodString>;
|
|
1035
|
+
maxFileBytes: z.ZodDefault<z.ZodNumber>;
|
|
1036
|
+
maxRunBytes: z.ZodDefault<z.ZodNumber>;
|
|
1037
|
+
retainDays: z.ZodDefault<z.ZodNumber>;
|
|
1038
|
+
gifPreview: z.ZodDefault<z.ZodBoolean>;
|
|
1039
|
+
}, z.core.$strip>>;
|
|
869
1040
|
}, z.core.$strip>>;
|
|
870
1041
|
jira: z.ZodOptional<z.ZodObject<{
|
|
871
1042
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -984,6 +1155,11 @@ export declare const ProjectConfigSchema: z.ZodObject<{
|
|
|
984
1155
|
allure: z.ZodDefault<z.ZodBoolean>;
|
|
985
1156
|
junit: z.ZodDefault<z.ZodBoolean>;
|
|
986
1157
|
}, z.core.$strip>>;
|
|
1158
|
+
traceability: z.ZodOptional<z.ZodObject<{
|
|
1159
|
+
requirements: z.ZodOptional<z.ZodString>;
|
|
1160
|
+
link: z.ZodOptional<z.ZodString>;
|
|
1161
|
+
require: z.ZodDefault<z.ZodBoolean>;
|
|
1162
|
+
}, z.core.$strip>>;
|
|
987
1163
|
ci: z.ZodDefault<z.ZodObject<{
|
|
988
1164
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
989
1165
|
env: z.ZodOptional<z.ZodString>;
|
|
@@ -1090,9 +1266,15 @@ export type TestingType = z.infer<typeof TestingTypeSchema>;
|
|
|
1090
1266
|
export type ProjectConfig = z.infer<typeof ProjectConfigSchema>;
|
|
1091
1267
|
export type ProjectConfigInput = z.input<typeof ProjectConfigSchema>;
|
|
1092
1268
|
export type ScreenshotConfig = z.infer<typeof ScreenshotConfigSchema>;
|
|
1269
|
+
export type BaselineConfig = z.infer<typeof BaselineConfigSchema>;
|
|
1093
1270
|
export type EvidenceConfig = z.infer<typeof EvidenceSchema>;
|
|
1271
|
+
export type CanvasConfig = z.infer<typeof CanvasConfigSchema>;
|
|
1094
1272
|
export type SetupConfig = z.infer<typeof SetupSchema>;
|
|
1273
|
+
export type TraceabilityConfig = z.infer<typeof TraceabilitySchema>;
|
|
1095
1274
|
export type HealConfig = z.infer<typeof HealConfigSchema>;
|
|
1275
|
+
export type A11yConfig = z.infer<typeof A11yConfigSchema>;
|
|
1276
|
+
export type A11yImpact = z.infer<typeof A11yImpactSchema>;
|
|
1277
|
+
export type ProcessGates = ProcessConfig['gates'];
|
|
1096
1278
|
export type TimeoutsConfig = z.infer<typeof TimeoutsSchema>;
|
|
1097
1279
|
export type ProjectAuthConfig = z.infer<typeof ProjectAuthSchema>;
|
|
1098
1280
|
export type McpServerConfig = z.infer<typeof McpServerSchema>;
|