@hypequery/protocol-conformance 0.12.0 → 0.14.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.
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/adapters/generators.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkBpC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuC1D;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAMxD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoCzD;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CA2BrD;AAgBD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuB7D;AA4CD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAsFjE;AAkBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyBpD;AAeD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoB1D;AAmBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAmBrD;AAaD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAgBtD"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/adapters/generators.ts"],"names":[],"mappings":"AAIA,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkBpC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuC1D;AAID,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAMxD;AAMD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CA0CzD;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CA2BrD;AAgBD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAuB7D;AA4CD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAsFjE;AAkBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyBpD;AAeD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAoB1D;AAmBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAmBrD;AAaD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAgBtD"}
@@ -89,6 +89,12 @@ export function materializeExpression(spec) {
89
89
  operands: Array.from({ length: groupIndex === 9 ? spec.lastGroupItems : 100 }, () => ({ ...EXPR_LITERAL })),
90
90
  })),
91
91
  };
92
+ case 'segments':
93
+ return {
94
+ kind: 'dataset',
95
+ dataset: 'orders',
96
+ segments: Array.from({ length: spec.count }, (_, index) => `s${index}`),
97
+ };
92
98
  case 'unsafe-accessor': {
93
99
  const value = { kind: 'reference' };
94
100
  Object.defineProperty(value, 'name', { enumerable: true, get: () => 'orders' });
@@ -9,7 +9,7 @@ export declare const REFERENCE_HOSTILE_OBJECT_SUITE: {
9
9
  readonly count: 7;
10
10
  readonly mechanisms: readonly ["getter", "toJSON", "proxy", "custom-prototype", "symbol-key", "sparse-array", "cycle"];
11
11
  };
12
- export declare const REFERENCE_FAMILIES: readonly ["cache-keys-v1", "tagged-values-v1", "identifiers-v1", "expressions-v1", "query-schemas-v1", "query-implementations-v1", "query-events-v1", "query-diagnostics-v1", "deployments-v2", "deployment-bundles-v1", "deployment-releases-v1", "semantic-invocations-v1"];
12
+ export declare const REFERENCE_FAMILIES: readonly ["cache-keys-v1", "cache-preimages-v1", "tagged-values-v1", "identifiers-v1", "expressions-v1", "expressions-v2", "query-schemas-v1", "query-implementations-v1", "query-events-v1", "query-diagnostics-v1", "deployments-v2", "deployments-v3", "deployment-bundles-v1", "deployment-releases-v1", "semantic-invocations-v1", "semantic-invocations-v2"];
13
13
  export declare function referenceHandle(family: string, role: FixtureRole, c: Case, section?: string): HandlerResult;
14
14
  export {};
15
15
  //# sourceMappingURL=reference.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/adapters/reference.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAc9D,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0BpC;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;CAWjC,CAAC;AAEX,eAAO,MAAM,kBAAkB,+QAarB,CAAC;AAEX,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,EACjB,CAAC,EAAE,IAAI,EACP,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CAsCf"}
1
+ {"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/adapters/reference.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAc9D,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA0BpC;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;;CAWjC,CAAC;AAEX,eAAO,MAAM,kBAAkB,oWAiBrB,CAAC;AAEX,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,EACjB,CAAC,EAAE,IAAI,EACP,OAAO,CAAC,EAAE,MAAM,GACf,aAAa,CA8Cf"}
@@ -2,7 +2,7 @@
2
2
  // root export of @hypequery/protocol and returns a wire result. Every operation
3
3
  // goes through the package's supported surface — this is exactly what a second
4
4
  // implementation must reproduce.
5
- import { decodeCanonicalValue, deriveProtocolCacheKey, deriveProtocolCacheNamespaceToken, encodeCanonicalValue, hashCanonicalValue, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, prepareProtocolDeploymentBundleManifest, prepareProtocolDeploymentContract, prepareProtocolDeploymentReleaseEnvelope, splitProtocolQualifiedIdentifier, validateCanonicalValue, validateProtocolDeploymentBundleManifest, validateProtocolDeploymentContract, validateProtocolDeploymentReleaseEnvelope, validateProtocolExpression, validateProtocolQueryDiagnostics, validateProtocolQueryEvent, validateProtocolQueryImplementation, validateProtocolSchema, validateProtocolSemanticInvocation, validateProtocolSemanticInvocationFailure, validateProtocolSemanticInvocationResult, validateProtocolSemanticQuery, validateProtocolSqlExpression, } from '@hypequery/protocol';
5
+ import { buildProtocolCachePreimage, decodeCanonicalValue, deriveProtocolCacheKey, deriveProtocolCacheNamespaceToken, encodeCanonicalValue, hashCanonicalValue, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, prepareProtocolDeploymentBundleManifest, prepareProtocolDeploymentContract, prepareProtocolDeploymentContractV3, prepareProtocolDeploymentReleaseEnvelope, splitProtocolQualifiedIdentifier, validateCanonicalValue, validateProtocolDeploymentBundleManifest, validateProtocolDeploymentContract, validateProtocolDeploymentContractV3, validateProtocolDeploymentReleaseEnvelope, validateProtocolExpression, validateProtocolQueryDiagnostics, validateProtocolQueryEvent, validateProtocolQueryImplementation, validateProtocolSchema, validateProtocolSemanticInvocation, validateProtocolSemanticInvocationFailure, validateProtocolSemanticInvocationResult, validateProtocolSemanticInvocationV2, validateProtocolSemanticQuery, validateProtocolSqlExpression, } from '@hypequery/protocol';
6
6
  import { materializeBundle, materializeDiagnostics, materializeEvent, materializeSemanticInvocation, materializeExpression, materializeIdentifier, materializeImplementation, materializeRelease, materializeSchema, materializeTaggedValue, } from './generators.js';
7
7
  const STABLE_CODE = /^HQ_[A-Z0-9_]+$/;
8
8
  /** Turns a thrown protocol error into a wire rejection; rethrows anything else. */
@@ -44,17 +44,21 @@ export const REFERENCE_HOSTILE_OBJECT_SUITE = {
44
44
  };
45
45
  export const REFERENCE_FAMILIES = [
46
46
  'cache-keys-v1',
47
+ 'cache-preimages-v1',
47
48
  'tagged-values-v1',
48
49
  'identifiers-v1',
49
50
  'expressions-v1',
51
+ 'expressions-v2',
50
52
  'query-schemas-v1',
51
53
  'query-implementations-v1',
52
54
  'query-events-v1',
53
55
  'query-diagnostics-v1',
54
56
  'deployments-v2',
57
+ 'deployments-v3',
55
58
  'deployment-bundles-v1',
56
59
  'deployment-releases-v1',
57
60
  'semantic-invocations-v1',
61
+ 'semantic-invocations-v2',
58
62
  ];
59
63
  export function referenceHandle(family, role, c, section) {
60
64
  switch (family) {
@@ -63,7 +67,9 @@ export function referenceHandle(family, role, c, section) {
63
67
  case 'identifiers-v1':
64
68
  return handleIdentifier(role, c);
65
69
  case 'expressions-v1':
66
- return handleExpression(role, c, section);
70
+ return handleExpression(role, c, section, 1);
71
+ case 'expressions-v2':
72
+ return handleExpression(role, c, section, 2);
67
73
  case 'query-schemas-v1':
68
74
  return attempt(() => {
69
75
  validateProtocolSchema(validationInput(c, materializeSchema));
@@ -83,14 +89,20 @@ export function referenceHandle(family, role, c, section) {
83
89
  });
84
90
  case 'deployments-v2':
85
91
  return handleDeploymentV2(role, c);
92
+ case 'deployments-v3':
93
+ return handleDeploymentV3(role, c);
86
94
  case 'deployment-bundles-v1':
87
95
  return handleBundle(role, c);
88
96
  case 'deployment-releases-v1':
89
97
  return handleRelease(role, c);
90
98
  case 'semantic-invocations-v1':
91
- return handleSemanticInvocation(c);
99
+ return handleSemanticInvocation(c, 1);
100
+ case 'semantic-invocations-v2':
101
+ return handleSemanticInvocation(c, 2);
92
102
  case 'cache-keys-v1':
93
103
  return handleCacheKey(role, c);
104
+ case 'cache-preimages-v1':
105
+ return handleCachePreimage(role, c);
94
106
  default:
95
107
  throw new Error(`reference adapter does not support family ${family}`);
96
108
  }
@@ -99,9 +111,9 @@ export function referenceHandle(family, role, c, section) {
99
111
  * One family covers the invocation, result, and failure records, so each case
100
112
  * names which one it validates against.
101
113
  */
102
- function handleSemanticInvocation(c) {
114
+ function handleSemanticInvocation(c, version) {
103
115
  const validators = {
104
- invocation: validateProtocolSemanticInvocation,
116
+ invocation: version === 2 ? validateProtocolSemanticInvocationV2 : validateProtocolSemanticInvocation,
105
117
  result: validateProtocolSemanticInvocationResult,
106
118
  failure: validateProtocolSemanticInvocationFailure,
107
119
  };
@@ -146,6 +158,18 @@ function handleCacheKey(role, c) {
146
158
  };
147
159
  });
148
160
  }
161
+ function handleCachePreimage(role, c) {
162
+ return attempt(() => {
163
+ const preimage = buildProtocolCachePreimage({
164
+ secret: hexToBytes(c.secretHex),
165
+ definitionIdentity: c.definitionIdentity,
166
+ query: c.query,
167
+ tenant: c.tenant,
168
+ rowLimit: c.rowLimit,
169
+ });
170
+ return role === 'success' ? { ok: true, output: { preimageUtf8: preimage } } : { ok: true };
171
+ });
172
+ }
149
173
  function handleTaggedValue(role, c) {
150
174
  if (role === 'success') {
151
175
  return attempt(() => ({
@@ -185,17 +209,17 @@ function handleIdentifier(role, c) {
185
209
  return ACCEPT;
186
210
  });
187
211
  }
188
- function handleExpression(role, c, section) {
212
+ function handleExpression(role, c, section, extension) {
189
213
  const isQuery = section === '/queries' || c.mode === 'query';
190
214
  const validate = isQuery ? validateProtocolSemanticQuery : validateProtocolExpression;
191
215
  if (role === 'success') {
192
216
  return attempt(() => {
193
- validate(validationInput(c, materializeExpression));
217
+ validate(validationInput(c, materializeExpression), { extension });
194
218
  return ACCEPT;
195
219
  });
196
220
  }
197
221
  return attempt(() => {
198
- validate(validationInput(c, materializeExpression));
222
+ validate(validationInput(c, materializeExpression), { extension });
199
223
  return ACCEPT;
200
224
  });
201
225
  }
@@ -220,6 +244,18 @@ function handleDeploymentV2(role, c) {
220
244
  return ACCEPT;
221
245
  });
222
246
  }
247
+ function handleDeploymentV3(role, c) {
248
+ if (role === 'identity') {
249
+ return attempt(() => {
250
+ const prepared = prepareProtocolDeploymentContractV3(c.value);
251
+ return { ok: true, output: { canonical: prepared.canonical, sha256: prepared.identity } };
252
+ });
253
+ }
254
+ return attempt(() => {
255
+ validateProtocolDeploymentContractV3(c.value);
256
+ return ACCEPT;
257
+ });
258
+ }
223
259
  function handleBundle(role, c) {
224
260
  if (role === 'identity') {
225
261
  return attempt(() => {
package/dist/compare.js CHANGED
@@ -121,6 +121,12 @@ function compareSuccessOutput(ec, o) {
121
121
  return outcome(ec, 'fail', { expected: 'segments', actual: 'mismatch' });
122
122
  }
123
123
  }
124
+ if (ec.family === 'cache-preimages-v1') {
125
+ // By name only: a preimage holds filter values, so a report never prints one.
126
+ if (o.preimageUtf8 !== ec.case.preimageUtf8) {
127
+ return outcome(ec, 'fail', { expected: 'preimageUtf8', actual: 'mismatch' });
128
+ }
129
+ }
124
130
  if (ec.family === 'cache-keys-v1') {
125
131
  // Reported as 'mismatch' rather than by value: a run against non-fixture
126
132
  // inputs would otherwise print keys derived from a real secret.
@@ -0,0 +1,74 @@
1
+ # Cache preimage version 1 fixtures
2
+
3
+ These language-neutral fixtures accompany accepted RFC 0009 ("Tenant
4
+ fingerprint" and "Cache preimage") and are normative for cache preimage
5
+ version 1.
6
+
7
+ ## Success manifest
8
+
9
+ Each entry in `success.json` contains:
10
+
11
+ - `id`: stable fixture identifier;
12
+ - `secretHex`: the namespace's RFC 0013 cache-key secret as lowercase hex,
13
+ used for tenant fingerprints;
14
+ - `definitionIdentity`: 64 lowercase hex characters;
15
+ - `query`: an RFC 0003 semantic query, validated under expression extension 2;
16
+ - `tenant`: the trusted tenant capability, as `{"mode": "none"}`,
17
+ `{"mode": "scoped", "ids": [...]}` with raw tenant identifiers, or
18
+ `{"mode": "all"}`. The preimage replaces each identifier with its tenant
19
+ fingerprint;
20
+ - `rowLimit`: the effective row limit, or `null`;
21
+ - `preimageUtf8`: the exact canonical preimage.
22
+
23
+ `secretHex`, `tenant` and `rowLimit` describe trusted execution context. They are fixture
24
+ inputs, not request fields.
25
+
26
+ ## Rejection manifest
27
+
28
+ Entries in `rejections.json` carry the same inputs plus the required stable
29
+ `error` code. The `precedence-*` cases violate several rules at once and pin
30
+ the first failure.
31
+
32
+ ## What the corpus is designed to prove
33
+
34
+ Equivalent requests must build identical bytes:
35
+
36
+ - `minimal-dataset`, `empty-collections-equal-omitted`,
37
+ `offset-zero-equals-omitted` and `include-meta-and-limit-dropped` all build
38
+ the same preimage;
39
+ - `filters-order-a`, `filters-order-b` and `duplicate-filters-collapse` all
40
+ build the same preimage;
41
+ - `tenant-scoped-sorted-deduplicated` shows that tenant fingerprints are
42
+ sorted and deduplicated.
43
+
44
+ Requests that can return different rows must not:
45
+
46
+ - `measures-empty-differs-from-omitted`: `[]` selects no measures, while
47
+ omitting the field selects every measure;
48
+ - `dimension-order-a` and `dimension-order-b`: column order is part of the
49
+ result;
50
+ - `tenant-scoped` and `tenant-all` differ from each other and from
51
+ `minimal-dataset`, which is tenant-free. This is the RFC 0009 cache-confusion
52
+ guarantee;
53
+ - `definition-changes-preimage` and `row-limit-zero` differ from
54
+ `minimal-dataset`;
55
+ - `tenant-fingerprint-follows-secret`: the same tenant under another secret
56
+ builds a different preimage.
57
+
58
+ Raw tenant identifiers never appear in a preimage, and no scoped case's
59
+ preimage contains its raw identifiers. `tenant-id-has-no-length-cap` and
60
+ `tenant-count-has-no-cap` pin that there is no tenant limit beyond RFC 0013's
61
+ 1 MiB bound on the preimage.
62
+
63
+ ## How these expectations were produced
64
+
65
+ The expectations were generated twice, by independent implementations of the
66
+ rules, before any runtime implemented them:
67
+
68
+ - a Python generator built on the Python RFC 0003 validator, the RFC 8785
69
+ serializer, and `hmac`;
70
+ - a Node generator built on the TypeScript validator, a separate serializer,
71
+ and `node:crypto`.
72
+
73
+ Both produced identical output for all 44 cases. The conformance runner now
74
+ holds `@hypequery/protocol` and the Python package to the same bytes.
@@ -0,0 +1,304 @@
1
+ [
2
+ {
3
+ "id": "secret-missing",
4
+ "secretHex": "",
5
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
6
+ "query": {
7
+ "kind": "dataset",
8
+ "dataset": "orders"
9
+ },
10
+ "tenant": {
11
+ "mode": "none"
12
+ },
13
+ "rowLimit": null,
14
+ "error": "HQ_CACHE_PREIMAGE_SECRET_MISSING"
15
+ },
16
+ {
17
+ "id": "secret-31-bytes",
18
+ "secretHex": "11111111111111111111111111111111111111111111111111111111111111",
19
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
20
+ "query": {
21
+ "kind": "dataset",
22
+ "dataset": "orders"
23
+ },
24
+ "tenant": {
25
+ "mode": "none"
26
+ },
27
+ "rowLimit": null,
28
+ "error": "HQ_CACHE_PREIMAGE_SECRET_TOO_SHORT"
29
+ },
30
+ {
31
+ "id": "definition-uppercase",
32
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
33
+ "definitionIdentity": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
34
+ "query": {
35
+ "kind": "dataset",
36
+ "dataset": "orders"
37
+ },
38
+ "tenant": {
39
+ "mode": "none"
40
+ },
41
+ "rowLimit": null,
42
+ "error": "HQ_CACHE_PREIMAGE_INVALID_DEFINITION"
43
+ },
44
+ {
45
+ "id": "definition-short",
46
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
47
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
48
+ "query": {
49
+ "kind": "dataset",
50
+ "dataset": "orders"
51
+ },
52
+ "tenant": {
53
+ "mode": "none"
54
+ },
55
+ "rowLimit": null,
56
+ "error": "HQ_CACHE_PREIMAGE_INVALID_DEFINITION"
57
+ },
58
+ {
59
+ "id": "definition-not-string",
60
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
61
+ "definitionIdentity": null,
62
+ "query": {
63
+ "kind": "dataset",
64
+ "dataset": "orders"
65
+ },
66
+ "tenant": {
67
+ "mode": "none"
68
+ },
69
+ "rowLimit": null,
70
+ "error": "HQ_CACHE_PREIMAGE_INVALID_DEFINITION"
71
+ },
72
+ {
73
+ "id": "query-unknown-field",
74
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
75
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
76
+ "query": {
77
+ "kind": "dataset",
78
+ "dataset": "orders",
79
+ "sql": "SELECT 1"
80
+ },
81
+ "tenant": {
82
+ "mode": "none"
83
+ },
84
+ "rowLimit": null,
85
+ "error": "HQ_CACHE_PREIMAGE_INVALID_QUERY"
86
+ },
87
+ {
88
+ "id": "query-measures-on-metric",
89
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
90
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
91
+ "query": {
92
+ "kind": "metric",
93
+ "dataset": "orders",
94
+ "metric": "aov",
95
+ "measures": [
96
+ "revenue"
97
+ ]
98
+ },
99
+ "tenant": {
100
+ "mode": "none"
101
+ },
102
+ "rowLimit": null,
103
+ "error": "HQ_CACHE_PREIMAGE_INVALID_QUERY"
104
+ },
105
+ {
106
+ "id": "query-duplicate-segments",
107
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
108
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
109
+ "query": {
110
+ "kind": "dataset",
111
+ "dataset": "orders",
112
+ "segments": [
113
+ "vip",
114
+ "vip"
115
+ ]
116
+ },
117
+ "tenant": {
118
+ "mode": "none"
119
+ },
120
+ "rowLimit": null,
121
+ "error": "HQ_CACHE_PREIMAGE_INVALID_QUERY"
122
+ },
123
+ {
124
+ "id": "tenant-unknown-mode",
125
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
126
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
127
+ "query": {
128
+ "kind": "dataset",
129
+ "dataset": "orders"
130
+ },
131
+ "tenant": {
132
+ "mode": "public"
133
+ },
134
+ "rowLimit": null,
135
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
136
+ },
137
+ {
138
+ "id": "tenant-none-with-ids",
139
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
140
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
141
+ "query": {
142
+ "kind": "dataset",
143
+ "dataset": "orders"
144
+ },
145
+ "tenant": {
146
+ "mode": "none",
147
+ "ids": [
148
+ "acme"
149
+ ]
150
+ },
151
+ "rowLimit": null,
152
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
153
+ },
154
+ {
155
+ "id": "tenant-scoped-empty",
156
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
157
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
158
+ "query": {
159
+ "kind": "dataset",
160
+ "dataset": "orders"
161
+ },
162
+ "tenant": {
163
+ "mode": "scoped",
164
+ "ids": []
165
+ },
166
+ "rowLimit": null,
167
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
168
+ },
169
+ {
170
+ "id": "tenant-scoped-empty-id",
171
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
172
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
173
+ "query": {
174
+ "kind": "dataset",
175
+ "dataset": "orders"
176
+ },
177
+ "tenant": {
178
+ "mode": "scoped",
179
+ "ids": [
180
+ ""
181
+ ]
182
+ },
183
+ "rowLimit": null,
184
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
185
+ },
186
+ {
187
+ "id": "tenant-scoped-non-string-id",
188
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
189
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
190
+ "query": {
191
+ "kind": "dataset",
192
+ "dataset": "orders"
193
+ },
194
+ "tenant": {
195
+ "mode": "scoped",
196
+ "ids": [
197
+ 7
198
+ ]
199
+ },
200
+ "rowLimit": null,
201
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
202
+ },
203
+ {
204
+ "id": "row-limit-negative",
205
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
206
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
207
+ "query": {
208
+ "kind": "dataset",
209
+ "dataset": "orders"
210
+ },
211
+ "tenant": {
212
+ "mode": "none"
213
+ },
214
+ "rowLimit": -1,
215
+ "error": "HQ_CACHE_PREIMAGE_INVALID_LIMIT"
216
+ },
217
+ {
218
+ "id": "row-limit-above-safe-integer",
219
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
220
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
221
+ "query": {
222
+ "kind": "dataset",
223
+ "dataset": "orders"
224
+ },
225
+ "tenant": {
226
+ "mode": "none"
227
+ },
228
+ "rowLimit": 9007199254740992,
229
+ "error": "HQ_CACHE_PREIMAGE_INVALID_LIMIT"
230
+ },
231
+ {
232
+ "id": "row-limit-string",
233
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
234
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
235
+ "query": {
236
+ "kind": "dataset",
237
+ "dataset": "orders"
238
+ },
239
+ "tenant": {
240
+ "mode": "none"
241
+ },
242
+ "rowLimit": "100",
243
+ "error": "HQ_CACHE_PREIMAGE_INVALID_LIMIT"
244
+ },
245
+ {
246
+ "id": "precedence-secret-before-definition",
247
+ "secretHex": "",
248
+ "definitionIdentity": "nope",
249
+ "query": {
250
+ "kind": "dataset",
251
+ "dataset": "orders",
252
+ "sql": "x"
253
+ },
254
+ "tenant": {
255
+ "mode": "public"
256
+ },
257
+ "rowLimit": -1,
258
+ "error": "HQ_CACHE_PREIMAGE_SECRET_MISSING"
259
+ },
260
+ {
261
+ "id": "precedence-definition-before-query",
262
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
263
+ "definitionIdentity": "nope",
264
+ "query": {
265
+ "kind": "dataset",
266
+ "dataset": "orders",
267
+ "sql": "x"
268
+ },
269
+ "tenant": {
270
+ "mode": "public"
271
+ },
272
+ "rowLimit": -1,
273
+ "error": "HQ_CACHE_PREIMAGE_INVALID_DEFINITION"
274
+ },
275
+ {
276
+ "id": "precedence-query-before-tenant",
277
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
278
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
279
+ "query": {
280
+ "kind": "dataset",
281
+ "dataset": "orders",
282
+ "sql": "x"
283
+ },
284
+ "tenant": {
285
+ "mode": "public"
286
+ },
287
+ "rowLimit": -1,
288
+ "error": "HQ_CACHE_PREIMAGE_INVALID_QUERY"
289
+ },
290
+ {
291
+ "id": "precedence-tenant-before-limit",
292
+ "secretHex": "1111111111111111111111111111111111111111111111111111111111111111",
293
+ "definitionIdentity": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
294
+ "query": {
295
+ "kind": "dataset",
296
+ "dataset": "orders"
297
+ },
298
+ "tenant": {
299
+ "mode": "public"
300
+ },
301
+ "rowLimit": -1,
302
+ "error": "HQ_CACHE_PREIMAGE_INVALID_TENANT"
303
+ }
304
+ ]