checkly 8.16.0 → 8.17.1-prerelease-14d5b2d

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 (45) hide show
  1. package/dist/ai-context/context.js +4 -4
  2. package/dist/ai-context/skills-command/references/configure-ssl-monitors.md +4 -4
  3. package/dist/constructs/grpc-assertion-codegen.js +60 -4
  4. package/dist/constructs/grpc-assertion-codegen.js.map +1 -1
  5. package/dist/constructs/grpc-assertion-validation.js +16 -0
  6. package/dist/constructs/grpc-assertion-validation.js.map +1 -1
  7. package/dist/constructs/grpc-assertion.d.ts +37 -2
  8. package/dist/constructs/grpc-assertion.js +42 -3
  9. package/dist/constructs/grpc-assertion.js.map +1 -1
  10. package/dist/constructs/grpc-request-codegen.js +0 -3
  11. package/dist/constructs/grpc-request-codegen.js.map +1 -1
  12. package/dist/constructs/grpc-request.d.ts +0 -6
  13. package/dist/constructs/internal/assertion-codegen.d.ts +11 -2
  14. package/dist/constructs/internal/assertion-codegen.js +14 -17
  15. package/dist/constructs/internal/assertion-codegen.js.map +1 -1
  16. package/dist/constructs/internal/assertion-grammar.d.ts +35 -0
  17. package/dist/constructs/internal/assertion-grammar.js +75 -0
  18. package/dist/constructs/internal/assertion-grammar.js.map +1 -0
  19. package/dist/constructs/internal/assertion.js +2 -2
  20. package/dist/constructs/internal/assertion.js.map +1 -1
  21. package/dist/constructs/ssl-assertion-codegen.d.ts +2 -0
  22. package/dist/constructs/ssl-assertion-codegen.js +65 -27
  23. package/dist/constructs/ssl-assertion-codegen.js.map +1 -1
  24. package/dist/constructs/ssl-assertion-grammar.d.ts +123 -0
  25. package/dist/constructs/ssl-assertion-grammar.js +90 -0
  26. package/dist/constructs/ssl-assertion-grammar.js.map +1 -0
  27. package/dist/constructs/ssl-assertion-validation.d.ts +6 -6
  28. package/dist/constructs/ssl-assertion-validation.js +97 -28
  29. package/dist/constructs/ssl-assertion-validation.js.map +1 -1
  30. package/dist/constructs/ssl-assertion.d.ts +59 -114
  31. package/dist/constructs/ssl-assertion.js +59 -176
  32. package/dist/constructs/ssl-assertion.js.map +1 -1
  33. package/dist/constructs/traceroute-assertion-grammar.d.ts +33 -0
  34. package/dist/constructs/traceroute-assertion-grammar.js +33 -0
  35. package/dist/constructs/traceroute-assertion-grammar.js.map +1 -0
  36. package/dist/constructs/traceroute-assertion-validation.js +21 -27
  37. package/dist/constructs/traceroute-assertion-validation.js.map +1 -1
  38. package/dist/constructs/traceroute-assertion.d.ts +6 -25
  39. package/dist/constructs/traceroute-assertion.js +5 -51
  40. package/dist/constructs/traceroute-assertion.js.map +1 -1
  41. package/dist/reporters/abstract-list.d.ts +2 -0
  42. package/dist/reporters/abstract-list.js +29 -11
  43. package/dist/reporters/abstract-list.js.map +1 -1
  44. package/oclif.manifest.json +206 -206
  45. package/package.json +7 -7
@@ -1,34 +1,72 @@
1
1
  import { unsupportedAssertionSource, valueForBooleanAssertion, valueForGeneralAssertion, valueForNumericAssertion, } from './internal/assertion-codegen.js';
2
- const generalNoArgs = { hasProperty: false, hasRegex: false };
3
- // The string sources additionally accept the MATCHES (regex) operator.
4
- const generalWithMatches = { hasProperty: false, hasRegex: false, hasMatches: true };
2
+ import { isSslNumericTarget, sslPropertyValueType } from './ssl-assertion-grammar.js';
3
+ // Every SSL source addresses its value through the property slot — CERTIFICATE /
4
+ // CONNECTION use a field selector, JSON_RESPONSE a JSONPath, and TEXT_RESPONSE a
5
+ // regex (the backend and runner read the TEXT_RESPONSE pattern from `property`,
6
+ // not `regex`). The regex slot is never emitted.
7
+ const withProperty = { hasProperty: true, hasRegex: false };
8
+ // The comparisons each typed helper can render. A comparison outside the set makes the
9
+ // helper throw, which would abort the whole import over a single assertion, so the
10
+ // dispatch below checks membership rather than relying on the throw. Exported so the
11
+ // grammar consistency spec can assert numeric properties declare only operators this
12
+ // renders, rather than restating the set.
13
+ export const numericComparisons = {
14
+ EQUALS: true, NOT_EQUALS: true, GREATER_THAN: true, LESS_THAN: true,
15
+ };
16
+ // The boolean helper renders only EQUALS as a bare boolean literal; any other comparison
17
+ // falls through to the quoted-string form, which would not compile against a boolean
18
+ // operator. The grammar spec asserts boolean properties declare only this.
19
+ export const booleanComparisons = {
20
+ EQUALS: true,
21
+ };
22
+ // The operators for a numeric or boolean property take a `number` / `boolean`, so their
23
+ // targets must be emitted as bare literals rather than quoted strings — otherwise the
24
+ // generated code does not compile.
25
+ //
26
+ // Each typed path is guarded on the assertion actually fitting it, because remote data is
27
+ // not bound by the builder's types: the backend accepts any target string, so a monitor
28
+ // created via the UI or API can carry `selfSigned = 'yes'` or `keySizeBits = ''`. Coercing
29
+ // those would silently rewrite the assertion on the next deploy ('yes' would become
30
+ // `false`), so they fall through to the string form, which round-trips the value untouched
31
+ // and is reported by validateSslAssertion instead.
32
+ function valueForPropertyScopedAssertion(method, assertion) {
33
+ const valueType = sslPropertyValueType(assertion.source, assertion.property);
34
+ // Rendered with Number, not the helper's default parseInt: isSslNumericTarget has
35
+ // already established the whole target is a number, and parseInt would truncate '30.5'
36
+ // to 30 — a silently different assertion on the next deploy. Sharing the predicate with
37
+ // validateSslAssertion is what keeps the two honest: every target validation accepts is
38
+ // rendered as a numeric literal the property's operators take, so no assertion the CLI
39
+ // calls valid is emitted as code that does not compile.
40
+ const isRenderableNumber = valueType === 'number'
41
+ && Object.hasOwn(numericComparisons, assertion.comparison)
42
+ && isSslNumericTarget(assertion.target);
43
+ if (isRenderableNumber) {
44
+ return valueForNumericAssertion('SslAssertionBuilder', method, assertion, {
45
+ hasProperty: true,
46
+ parse: Number,
47
+ });
48
+ }
49
+ const isRenderableBoolean = valueType === 'boolean'
50
+ && Object.hasOwn(booleanComparisons, assertion.comparison)
51
+ && (assertion.target === 'true' || assertion.target === 'false');
52
+ if (isRenderableBoolean) {
53
+ return valueForBooleanAssertion('SslAssertionBuilder', method, assertion, { hasProperty: true });
54
+ }
55
+ return valueForGeneralAssertion('SslAssertionBuilder', method, assertion, withProperty);
56
+ }
5
57
  export function valueForSslAssertion(genfile, assertion) {
6
58
  genfile.namedImport('SslAssertionBuilder', 'checkly/constructs');
7
59
  switch (assertion.source) {
8
- case 'CERT_EXPIRES_IN_DAYS':
9
- return valueForNumericAssertion('SslAssertionBuilder', 'certExpiresInDays', assertion);
10
- case 'KEY_SIZE_BITS':
11
- return valueForNumericAssertion('SslAssertionBuilder', 'keySizeBits', assertion);
12
- case 'CERT_NOT_EXPIRED':
13
- return valueForBooleanAssertion('SslAssertionBuilder', 'certNotExpired', assertion);
14
- case 'HOSTNAME_VERIFIED':
15
- return valueForBooleanAssertion('SslAssertionBuilder', 'hostnameVerified', assertion);
16
- case 'CHAIN_TRUSTED':
17
- return valueForBooleanAssertion('SslAssertionBuilder', 'chainTrusted', assertion);
18
- case 'OCSP_STAPLED':
19
- return valueForBooleanAssertion('SslAssertionBuilder', 'ocspStapled', assertion);
20
- case 'TLS_VERSION':
21
- return valueForGeneralAssertion('SslAssertionBuilder', 'tlsVersion', assertion, generalNoArgs);
22
- case 'CIPHER_SUITE':
23
- return valueForGeneralAssertion('SslAssertionBuilder', 'cipherSuite', assertion, generalWithMatches);
24
- case 'ISSUER_CN':
25
- return valueForGeneralAssertion('SslAssertionBuilder', 'issuerCn', assertion, generalWithMatches);
26
- case 'CERT_FINGERPRINT_SHA256':
27
- return valueForGeneralAssertion('SslAssertionBuilder', 'certFingerprintSha256', assertion, generalNoArgs);
28
- case 'ISSUER_FINGERPRINT_SHA256':
29
- return valueForGeneralAssertion('SslAssertionBuilder', 'issuerFingerprintSha256', assertion, generalNoArgs);
30
- case 'SIGNATURE_ALGORITHM':
31
- return valueForGeneralAssertion('SslAssertionBuilder', 'signatureAlgorithm', assertion, generalWithMatches);
60
+ case 'CERTIFICATE':
61
+ return valueForPropertyScopedAssertion('certificate', assertion);
62
+ case 'CONNECTION':
63
+ return valueForPropertyScopedAssertion('connection', assertion);
64
+ case 'JSON_RESPONSE':
65
+ return valueForGeneralAssertion('SslAssertionBuilder', 'jsonResponse', assertion, withProperty);
66
+ case 'TEXT_RESPONSE':
67
+ return valueForGeneralAssertion('SslAssertionBuilder', 'textResponse', assertion, withProperty);
68
+ case 'RESPONSE_TIME':
69
+ return valueForNumericAssertion('SslAssertionBuilder', 'responseTime', assertion);
32
70
  default:
33
71
  return unsupportedAssertionSource(assertion.source, 'SSL');
34
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ssl-assertion-codegen.js","sourceRoot":"","sources":["../../src/constructs/ssl-assertion-codegen.ts"],"names":[],"mappings":"AACA,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,iCAAiC,CAAA;AAGxC,MAAM,aAAa,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;AAC7D,uEAAuE;AACvE,MAAM,kBAAkB,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;AAEpF,MAAM,UAAU,oBAAoB,CAAE,OAAsB,EAAE,SAAuB;IACnF,OAAO,CAAC,WAAW,CAAC,qBAAqB,EAAE,oBAAoB,CAAC,CAAA;IAEhE,QAAQ,SAAS,CAAC,MAAM,EAAE,CAAC;QACzB,KAAK,sBAAsB;YACzB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,mBAAmB,EAAE,SAAS,CAAC,CAAA;QACxF,KAAK,eAAe;YAClB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAA;QAClF,KAAK,kBAAkB;YACrB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAA;QACrF,KAAK,mBAAmB;YACtB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,SAAS,CAAC,CAAA;QACvF,KAAK,eAAe;YAClB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,cAAc,EAAE,SAAS,CAAC,CAAA;QACnF,KAAK,cAAc;YACjB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,aAAa,EAAE,SAAS,CAAC,CAAA;QAClF,KAAK,aAAa;YAChB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;QAChG,KAAK,cAAc;YACjB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,aAAa,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAA;QACtG,KAAK,WAAW;YACd,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,UAAU,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAA;QACnG,KAAK,yBAAyB;YAC5B,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,uBAAuB,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;QAC3G,KAAK,2BAA2B;YAC9B,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,yBAAyB,EAAE,SAAS,EAAE,aAAa,CAAC,CAAA;QAC7G,KAAK,qBAAqB;YACxB,OAAO,wBAAwB,CAAC,qBAAqB,EAAE,oBAAoB,EAAE,SAAS,EAAE,kBAAkB,CAAC,CAAA;QAC7G;YACE,OAAO,0BAA0B,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC9D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"ssl-assertion-codegen.js","sourceRoot":"","sources":["../../src/constructs/ssl-assertion-codegen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { TargetValueType } from './internal/assertion-grammar.js';
2
+ import type { SignatureAlgorithmValue, TlsVersionValue } from './ssl-assertion.js';
3
+ export declare const certificateGrammar: {
4
+ /** Days until the certificate expires (numeric). */
5
+ readonly daysUntilExpiry: {
6
+ readonly operators: readonly ["equals", "notEquals", "greaterThan", "lessThan"];
7
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<number>;
8
+ };
9
+ /** Certificate key size in bits (numeric). */
10
+ readonly keySizeBits: {
11
+ readonly operators: readonly ["equals", "notEquals", "greaterThan", "lessThan"];
12
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<number>;
13
+ };
14
+ /** Certificate subject common name (free-form string). */
15
+ readonly subjectCN: {
16
+ readonly operators: readonly ["equals", "notEquals", "contains", "notContains"];
17
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
18
+ };
19
+ /** Certificate issuer common name (free-form string). */
20
+ readonly issuerCN: {
21
+ readonly operators: readonly ["equals", "notEquals", "contains", "notContains"];
22
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
23
+ };
24
+ /** Certificate serial number — an opaque identifier, compared whole. */
25
+ readonly serialNumber: {
26
+ readonly operators: readonly ["equals", "notEquals"];
27
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
28
+ };
29
+ /** Certificate SHA-256 fingerprint — an opaque identifier, compared whole. */
30
+ readonly fingerprintSha256: {
31
+ readonly operators: readonly ["equals", "notEquals"];
32
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
33
+ };
34
+ /** Issuer SHA-256 fingerprint — an opaque identifier, compared whole. */
35
+ readonly issuerFingerprintSha256: {
36
+ readonly operators: readonly ["equals", "notEquals"];
37
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
38
+ };
39
+ /** Certificate public key algorithm (e.g. `'RSA'`, `'ECDSA'`), compared whole. */
40
+ readonly keyAlgorithm: {
41
+ readonly operators: readonly ["equals", "notEquals"];
42
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
43
+ };
44
+ /** Certificate signature algorithm — a Go `x509 SignatureAlgorithm.String()` value. */
45
+ readonly signatureAlgorithm: {
46
+ readonly operators: readonly ["equals", "notEquals"];
47
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<SignatureAlgorithmValue>;
48
+ };
49
+ /** Certificate subject alternative names. A list, so only membership can be asserted. */
50
+ readonly sans: {
51
+ readonly operators: readonly ["contains", "notContains"];
52
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
53
+ };
54
+ /** Whether the certificate is self-signed (boolean). */
55
+ readonly selfSigned: {
56
+ readonly operators: readonly ["equals"];
57
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<boolean>;
58
+ };
59
+ /** Whether the certificate is a CA certificate (boolean). */
60
+ readonly isCA: {
61
+ readonly operators: readonly ["equals"];
62
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<boolean>;
63
+ };
64
+ };
65
+ export declare const connectionGrammar: {
66
+ /** Negotiated TLS version. Ordered, so `greaterThan` expresses a minimum. */
67
+ readonly tlsVersion: {
68
+ readonly operators: readonly ["equals", "notEquals", "greaterThan", "lessThan"];
69
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<TlsVersionValue>;
70
+ };
71
+ /** Negotiated cipher suite (free-form string; hundreds of IANA names). */
72
+ readonly cipherSuite: {
73
+ readonly operators: readonly ["equals", "notEquals", "contains", "notContains"];
74
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
75
+ };
76
+ /** Whether the hostname is verified against the certificate (boolean). */
77
+ readonly hostnameVerified: {
78
+ readonly operators: readonly ["equals"];
79
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<boolean>;
80
+ };
81
+ /** Whether the certificate chain is trusted (boolean). */
82
+ readonly chainTrusted: {
83
+ readonly operators: readonly ["equals"];
84
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<boolean>;
85
+ };
86
+ /** Whether a stapled OCSP response was provided during the handshake (boolean). */
87
+ readonly ocspStapled: {
88
+ readonly operators: readonly ["equals"];
89
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<boolean>;
90
+ };
91
+ /** OCSP revocation status (e.g. `'good'`, `'revoked'`), compared whole. */
92
+ readonly ocspStatus: {
93
+ readonly operators: readonly ["equals", "notEquals"];
94
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
95
+ };
96
+ /** The IP address the hostname resolved to (free-form string). */
97
+ readonly resolvedIp: {
98
+ readonly operators: readonly ["equals", "notEquals", "contains", "notContains"];
99
+ readonly target: import("./internal/assertion-grammar.js").TargetSpec<string>;
100
+ };
101
+ };
102
+ /**
103
+ * The wire comparisons each property of a source accepts, keyed by property name. Empty for
104
+ * a source with no property-scoped grammar. Used by validation to reject an unsupported
105
+ * comparison written as an object literal.
106
+ */
107
+ export declare function sslComparisonsForSource(source: string): Record<string, Record<string, true>>;
108
+ /**
109
+ * How the target of a property-scoped SSL assertion is written, or `undefined` for a
110
+ * property the backend does not define. Callers must handle the unknown case: object
111
+ * literals bypass the builder's compile-time check and are reported by
112
+ * `validateSslAssertion` instead.
113
+ */
114
+ export declare function sslPropertyValueType(source: string, property: string): TargetValueType | undefined;
115
+ /**
116
+ * Whether a target is one this CLI treats as a number.
117
+ *
118
+ * Validation and codegen must agree: anything validation accepts, codegen has to render as
119
+ * a bare numeric literal, because the property's operators take a `number` and a quoted
120
+ * target would not compile. Targets are plain strings on the wire and reach here from object
121
+ * literals and remote monitors, so this is a runtime predicate rather than a type.
122
+ */
123
+ export declare function isSslNumericTarget(target: string): boolean;
@@ -0,0 +1,90 @@
1
+ import { booleanTarget, comparisonsForGrammar, defineGrammar, numberTarget, stringTarget, valueTypeForGrammar, } from './internal/assertion-grammar.js';
2
+ // The single declaration of the SSL certificate/connection assertion grammar. Each row is
3
+ // a property's entire contract — the operators it exposes and the type of its target. The
4
+ // public `SslAssertionBuilder`, its property unions, the validation whitelist, and codegen
5
+ // all derive from these two tables, so a property cannot gain an operator the whitelist
6
+ // rejects, or a target type codegen renders wrong, without editing this one row.
7
+ export const certificateGrammar = defineGrammar({
8
+ /** Days until the certificate expires (numeric). */
9
+ daysUntilExpiry: { operators: ['equals', 'notEquals', 'greaterThan', 'lessThan'], target: numberTarget() },
10
+ /** Certificate key size in bits (numeric). */
11
+ keySizeBits: { operators: ['equals', 'notEquals', 'greaterThan', 'lessThan'], target: numberTarget() },
12
+ /** Certificate subject common name (free-form string). */
13
+ subjectCN: { operators: ['equals', 'notEquals', 'contains', 'notContains'], target: stringTarget() },
14
+ /** Certificate issuer common name (free-form string). */
15
+ issuerCN: { operators: ['equals', 'notEquals', 'contains', 'notContains'], target: stringTarget() },
16
+ /** Certificate serial number — an opaque identifier, compared whole. */
17
+ serialNumber: { operators: ['equals', 'notEquals'], target: stringTarget() },
18
+ /** Certificate SHA-256 fingerprint — an opaque identifier, compared whole. */
19
+ fingerprintSha256: { operators: ['equals', 'notEquals'], target: stringTarget() },
20
+ /** Issuer SHA-256 fingerprint — an opaque identifier, compared whole. */
21
+ issuerFingerprintSha256: { operators: ['equals', 'notEquals'], target: stringTarget() },
22
+ /** Certificate public key algorithm (e.g. `'RSA'`, `'ECDSA'`), compared whole. */
23
+ keyAlgorithm: { operators: ['equals', 'notEquals'], target: stringTarget() },
24
+ /** Certificate signature algorithm — a Go `x509 SignatureAlgorithm.String()` value. */
25
+ signatureAlgorithm: { operators: ['equals', 'notEquals'], target: stringTarget() },
26
+ /** Certificate subject alternative names. A list, so only membership can be asserted. */
27
+ sans: { operators: ['contains', 'notContains'], target: stringTarget() },
28
+ /** Whether the certificate is self-signed (boolean). */
29
+ selfSigned: { operators: ['equals'], target: booleanTarget() },
30
+ /** Whether the certificate is a CA certificate (boolean). */
31
+ isCA: { operators: ['equals'], target: booleanTarget() },
32
+ });
33
+ export const connectionGrammar = defineGrammar({
34
+ /** Negotiated TLS version. Ordered, so `greaterThan` expresses a minimum. */
35
+ tlsVersion: { operators: ['equals', 'notEquals', 'greaterThan', 'lessThan'], target: stringTarget() },
36
+ /** Negotiated cipher suite (free-form string; hundreds of IANA names). */
37
+ cipherSuite: { operators: ['equals', 'notEquals', 'contains', 'notContains'], target: stringTarget() },
38
+ /** Whether the hostname is verified against the certificate (boolean). */
39
+ hostnameVerified: { operators: ['equals'], target: booleanTarget() },
40
+ /** Whether the certificate chain is trusted (boolean). */
41
+ chainTrusted: { operators: ['equals'], target: booleanTarget() },
42
+ /** Whether a stapled OCSP response was provided during the handshake (boolean). */
43
+ ocspStapled: { operators: ['equals'], target: booleanTarget() },
44
+ /** OCSP revocation status (e.g. `'good'`, `'revoked'`), compared whole. */
45
+ ocspStatus: { operators: ['equals', 'notEquals'], target: stringTarget() },
46
+ /** The IP address the hostname resolved to (free-form string). */
47
+ resolvedIp: { operators: ['equals', 'notEquals', 'contains', 'notContains'], target: stringTarget() },
48
+ });
49
+ const grammarBySource = {
50
+ CERTIFICATE: certificateGrammar,
51
+ CONNECTION: connectionGrammar,
52
+ };
53
+ function propertyGrammar(source, property) {
54
+ const grammar = Object.hasOwn(grammarBySource, source) ? grammarBySource[source] : undefined;
55
+ if (grammar === undefined || !Object.hasOwn(grammar, property)) {
56
+ return undefined;
57
+ }
58
+ return grammar[property];
59
+ }
60
+ /**
61
+ * The wire comparisons each property of a source accepts, keyed by property name. Empty for
62
+ * a source with no property-scoped grammar. Used by validation to reject an unsupported
63
+ * comparison written as an object literal.
64
+ */
65
+ export function sslComparisonsForSource(source) {
66
+ const grammar = Object.hasOwn(grammarBySource, source) ? grammarBySource[source] : {};
67
+ return Object.fromEntries(Object.entries(grammar).map(([property, decl]) => [property, comparisonsForGrammar(decl)]));
68
+ }
69
+ /**
70
+ * How the target of a property-scoped SSL assertion is written, or `undefined` for a
71
+ * property the backend does not define. Callers must handle the unknown case: object
72
+ * literals bypass the builder's compile-time check and are reported by
73
+ * `validateSslAssertion` instead.
74
+ */
75
+ export function sslPropertyValueType(source, property) {
76
+ const decl = propertyGrammar(source, property);
77
+ return decl === undefined ? undefined : valueTypeForGrammar(decl);
78
+ }
79
+ /**
80
+ * Whether a target is one this CLI treats as a number.
81
+ *
82
+ * Validation and codegen must agree: anything validation accepts, codegen has to render as
83
+ * a bare numeric literal, because the property's operators take a `number` and a quoted
84
+ * target would not compile. Targets are plain strings on the wire and reach here from object
85
+ * literals and remote monitors, so this is a runtime predicate rather than a type.
86
+ */
87
+ export function isSslNumericTarget(target) {
88
+ return target.trim() !== '' && Number.isFinite(Number(target));
89
+ }
90
+ //# sourceMappingURL=ssl-assertion-grammar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssl-assertion-grammar.js","sourceRoot":"","sources":["../../src/constructs/ssl-assertion-grammar.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import { Diagnostics } from './diagnostics.js';
2
2
  import { SslAssertion } from './ssl-assertion.js';
3
3
  /**
4
- * Reports SSL assertions whose source, comparison or boolean target the backend does
5
- * not accept.
4
+ * Reports SSL assertions whose source, property, comparison or boolean target the
5
+ * backend does not accept.
6
6
  *
7
7
  * Assertions written as plain object literals bypass SslAssertionBuilder and are
8
- * type-legal, because the fields are declared as plain strings. The backend rejects
9
- * an unknown source or an operator not allowed for the source with a 400; a boolean
10
- * source with a non-`true`/`false` target is accepted at deploy but never matches at
11
- * evaluation, so it is reported too.
8
+ * type-legal, because the fields are declared as plain strings. The backend rejects an
9
+ * unknown source, an unknown property or an operator not allowed for the property with
10
+ * a 400; a boolean or numeric property whose target is not of that type is accepted at
11
+ * deploy but never matches at evaluation, so it is reported too.
12
12
  */
13
13
  export declare function validateSslAssertion(diagnostics: Diagnostics, assertion: SslAssertion, index: number): void;
@@ -1,30 +1,87 @@
1
1
  import { addAssertionDiagnostic, quotedKeys } from './internal/assertion-validation.js';
2
- // The operators the backend accepts per source, minus the CLI-dropped
3
- // GREATER_THAN_OR_EQUAL. Keyed by the source union so adding a source without a rule
4
- // fails to compile.
2
+ import { isSslNumericTarget, sslComparisonsForSource, sslPropertyValueType } from './ssl-assertion-grammar.js';
3
+ const NUMBER = { EQUALS: true, NOT_EQUALS: true, GREATER_THAN: true, LESS_THAN: true };
4
+ // Keyed by the source union so adding a source without a rule fails to compile.
5
5
  const rules = {
6
- CERT_EXPIRES_IN_DAYS: { comparisons: { EQUALS: true, NOT_EQUALS: true, GREATER_THAN: true, LESS_THAN: true } },
7
- KEY_SIZE_BITS: { comparisons: { EQUALS: true } },
8
- CERT_NOT_EXPIRED: { comparisons: { EQUALS: true }, booleanTarget: true },
9
- HOSTNAME_VERIFIED: { comparisons: { EQUALS: true }, booleanTarget: true },
10
- CHAIN_TRUSTED: { comparisons: { EQUALS: true }, booleanTarget: true },
11
- OCSP_STAPLED: { comparisons: { EQUALS: true }, booleanTarget: true },
12
- TLS_VERSION: { comparisons: { EQUALS: true } },
13
- SIGNATURE_ALGORITHM: { comparisons: { EQUALS: true, MATCHES: true } },
14
- CIPHER_SUITE: { comparisons: { EQUALS: true, NOT_EQUALS: true, MATCHES: true } },
15
- ISSUER_CN: { comparisons: { EQUALS: true, NOT_EQUALS: true, MATCHES: true } },
16
- CERT_FINGERPRINT_SHA256: { comparisons: { EQUALS: true } },
17
- ISSUER_FINGERPRINT_SHA256: { comparisons: { EQUALS: true } },
6
+ CERTIFICATE: { properties: sslComparisonsForSource('CERTIFICATE') },
7
+ CONNECTION: { properties: sslComparisonsForSource('CONNECTION') },
8
+ RESPONSE_TIME: { comparisons: NUMBER, valueType: 'number' },
9
+ JSON_RESPONSE: {
10
+ comparisons: {
11
+ EQUALS: true,
12
+ NOT_EQUALS: true,
13
+ IS_EMPTY: true,
14
+ NOT_EMPTY: true,
15
+ GREATER_THAN: true,
16
+ LESS_THAN: true,
17
+ CONTAINS: true,
18
+ NOT_CONTAINS: true,
19
+ IS_NULL: true,
20
+ NOT_NULL: true,
21
+ },
22
+ },
23
+ TEXT_RESPONSE: {
24
+ comparisons: {
25
+ EQUALS: true,
26
+ NOT_EQUALS: true,
27
+ IS_EMPTY: true,
28
+ NOT_EMPTY: true,
29
+ CONTAINS: true,
30
+ NOT_CONTAINS: true,
31
+ GREATER_THAN: true,
32
+ LESS_THAN: true,
33
+ },
34
+ },
18
35
  };
36
+ function isPropertyScoped(rule) {
37
+ return 'properties' in rule;
38
+ }
39
+ function formatValue(value) {
40
+ return value === '' ? '(none)' : `"${value}"`;
41
+ }
19
42
  /**
20
- * Reports SSL assertions whose source, comparison or boolean target the backend does
21
- * not accept.
43
+ * Reports a target that is not of the value type its source or property expects.
44
+ *
45
+ * Target *values* are checked where the accepted set is universal — booleans are two
46
+ * values, numbers are a total predicate — so a typo is a pure footgun the backend will not
47
+ * catch: it accepts any target string at deploy and simply never matches at evaluation,
48
+ * leaving an assertion that looks configured but silently never fires.
49
+ *
50
+ * The closed *enumerated* sets (tlsVersion, signatureAlgorithm) are deliberately not
51
+ * checked: the builder's typed operators already constrain them, and restating their
52
+ * members here would duplicate the value unions.
53
+ */
54
+ function validateTargetValue(diagnostics, assertion, location, valueType, subject) {
55
+ // `target` is declared a string, but object-literal assertions are not typechecked when
56
+ // a check file is loaded, so a hand-written `target: 30` or an omitted target reaches
57
+ // here as a non-string. Report it rather than dereferencing it — a TypeError out of
58
+ // validate() would abort the command with no location or message.
59
+ const target = assertion.target;
60
+ if (typeof target !== 'string') {
61
+ if (valueType !== undefined) {
62
+ addAssertionDiagnostic(diagnostics, `The ${subject} assertion at "${location}" must compare against a ${valueType} written as a string, `
63
+ + `but got ${JSON.stringify(target) ?? String(target)}.`);
64
+ }
65
+ return;
66
+ }
67
+ if (valueType === 'boolean' && target !== 'true' && target !== 'false') {
68
+ addAssertionDiagnostic(diagnostics, `The ${subject} assertion at "${location}" must compare against "true" or "false", `
69
+ + `but got "${target}".`);
70
+ }
71
+ if (valueType === 'number' && !isSslNumericTarget(target)) {
72
+ addAssertionDiagnostic(diagnostics, `The ${subject} assertion at "${location}" must compare against a number, `
73
+ + `but got ${formatValue(target)}.`);
74
+ }
75
+ }
76
+ /**
77
+ * Reports SSL assertions whose source, property, comparison or boolean target the
78
+ * backend does not accept.
22
79
  *
23
80
  * Assertions written as plain object literals bypass SslAssertionBuilder and are
24
- * type-legal, because the fields are declared as plain strings. The backend rejects
25
- * an unknown source or an operator not allowed for the source with a 400; a boolean
26
- * source with a non-`true`/`false` target is accepted at deploy but never matches at
27
- * evaluation, so it is reported too.
81
+ * type-legal, because the fields are declared as plain strings. The backend rejects an
82
+ * unknown source, an unknown property or an operator not allowed for the property with
83
+ * a 400; a boolean or numeric property whose target is not of that type is accepted at
84
+ * deploy but never matches at evaluation, so it is reported too.
28
85
  */
29
86
  export function validateSslAssertion(diagnostics, assertion, index) {
30
87
  const location = `request.assertions[${index}]`;
@@ -36,14 +93,26 @@ export function validateSslAssertion(diagnostics, assertion, index) {
36
93
  + `Expected one of ${quotedKeys(rules)}.`);
37
94
  return;
38
95
  }
39
- if (!Object.hasOwn(rule.comparisons, assertion.comparison)) {
40
- addAssertionDiagnostic(diagnostics, `The ${assertion.source} assertion at "${location}" has an unsupported comparison `
41
- + `${assertion.comparison === '' ? '(none)' : `"${assertion.comparison}"`}. `
42
- + `Expected one of ${quotedKeys(rule.comparisons)}.`);
96
+ if (!isPropertyScoped(rule)) {
97
+ if (!Object.hasOwn(rule.comparisons, assertion.comparison)) {
98
+ addAssertionDiagnostic(diagnostics, `The ${assertion.source} assertion at "${location}" has an unsupported comparison `
99
+ + `${formatValue(assertion.comparison)}. Expected one of ${quotedKeys(rule.comparisons)}.`);
100
+ }
101
+ validateTargetValue(diagnostics, assertion, location, rule.valueType, assertion.source);
102
+ return;
103
+ }
104
+ const comparisons = Object.hasOwn(rule.properties, assertion.property)
105
+ ? rule.properties[assertion.property]
106
+ : undefined;
107
+ if (comparisons === undefined) {
108
+ addAssertionDiagnostic(diagnostics, `The ${assertion.source} assertion at "${location}" has an unknown property `
109
+ + `${formatValue(assertion.property)}. Expected one of ${quotedKeys(rule.properties)}.`);
110
+ return;
43
111
  }
44
- if (rule.booleanTarget && assertion.target !== 'true' && assertion.target !== 'false') {
45
- addAssertionDiagnostic(diagnostics, `The ${assertion.source} assertion at "${location}" must compare against "true" or "false", `
46
- + `but got "${assertion.target}".`);
112
+ if (!Object.hasOwn(comparisons, assertion.comparison)) {
113
+ addAssertionDiagnostic(diagnostics, `The ${assertion.source} "${assertion.property}" assertion at "${location}" has an unsupported comparison `
114
+ + `${formatValue(assertion.comparison)}. Expected one of ${quotedKeys(comparisons)}.`);
47
115
  }
116
+ validateTargetValue(diagnostics, assertion, location, sslPropertyValueType(assertion.source, assertion.property), `${assertion.source} "${assertion.property}"`);
48
117
  }
49
118
  //# sourceMappingURL=ssl-assertion-validation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ssl-assertion-validation.js","sourceRoot":"","sources":["../../src/constructs/ssl-assertion-validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssl-assertion-validation.js","sourceRoot":"","sources":["../../src/constructs/ssl-assertion-validation.ts"],"names":[],"mappings":"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"}