@hypequery/protocol-conformance 0.11.1 → 0.11.2
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/adapters/generators.d.ts +0 -1
- package/dist/adapters/generators.d.ts.map +1 -1
- package/dist/adapters/generators.js +0 -112
- package/dist/adapters/reference.d.ts +1 -1
- package/dist/adapters/reference.d.ts.map +1 -1
- package/dist/adapters/reference.js +6 -6
- package/fixtures/deployments-v2/identity.json +7 -0
- package/fixtures/deployments-v2/success.json +67 -0
- package/fixtures/fuzz-seeds-v1/structured-values.json +3 -3
- package/fixtures/manifest.json +3 -7
- package/package.json +2 -2
- package/fixtures/deployments-v1/README.md +0 -11
- package/fixtures/deployments-v1/identity.json +0 -12
- package/fixtures/deployments-v1/rejections.json +0 -18
- package/fixtures/deployments-v1/success.json +0 -139
|
@@ -7,7 +7,6 @@ export declare function materializeImplementation(spec: Spec): unknown;
|
|
|
7
7
|
export declare function materializeSemanticInvocation(spec: Spec): unknown;
|
|
8
8
|
export declare function materializeEvent(spec: Spec): unknown;
|
|
9
9
|
export declare function materializeDiagnostics(spec: Spec): unknown;
|
|
10
|
-
export declare function materializeDeployment(spec: Spec): unknown;
|
|
11
10
|
export declare function materializeBundle(spec: Spec): unknown;
|
|
12
11
|
export declare function materializeRelease(spec: Spec): unknown;
|
|
13
12
|
export {};
|
|
@@ -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;
|
|
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"}
|
|
@@ -368,118 +368,6 @@ export function materializeDiagnostics(spec) {
|
|
|
368
368
|
default: throw new Error(`Unknown diagnostics generator: ${String(spec.type)}`);
|
|
369
369
|
}
|
|
370
370
|
}
|
|
371
|
-
// --- deployments-v1 ---
|
|
372
|
-
function minimalDataset(name = 'orders') {
|
|
373
|
-
return {
|
|
374
|
-
name,
|
|
375
|
-
source: 'orders',
|
|
376
|
-
tenant: { kind: 'not-required' },
|
|
377
|
-
dimensions: [],
|
|
378
|
-
measures: [],
|
|
379
|
-
filters: [],
|
|
380
|
-
metrics: [],
|
|
381
|
-
relationships: [],
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
function baseDeployment() {
|
|
385
|
-
return {
|
|
386
|
-
kind: 'hypequery-deployment',
|
|
387
|
-
version: 1,
|
|
388
|
-
datasets: [minimalDataset()],
|
|
389
|
-
queries: [],
|
|
390
|
-
artifacts: [],
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
export function materializeDeployment(spec) {
|
|
394
|
-
const value = baseDeployment();
|
|
395
|
-
switch (spec.type) {
|
|
396
|
-
case 'wrong-root-type': return [];
|
|
397
|
-
case 'unknown-root-field': return { ...value, extra: true };
|
|
398
|
-
case 'unsupported-version': return { ...value, version: 2 };
|
|
399
|
-
case 'invalid-dataset-identifier': return { ...value, datasets: [minimalDataset('bad-name')] };
|
|
400
|
-
case 'invalid-relationship-queryability':
|
|
401
|
-
return {
|
|
402
|
-
...value,
|
|
403
|
-
datasets: [{
|
|
404
|
-
...minimalDataset(),
|
|
405
|
-
relationships: [{
|
|
406
|
-
name: 'items', kind: 'hasMany', target: 'orders', from: 'id', to: 'order_id', queryable: true,
|
|
407
|
-
}],
|
|
408
|
-
}],
|
|
409
|
-
};
|
|
410
|
-
case 'missing-runtime-artifact':
|
|
411
|
-
return {
|
|
412
|
-
...value,
|
|
413
|
-
queries: [{
|
|
414
|
-
name: 'health',
|
|
415
|
-
input: { kind: 'any' },
|
|
416
|
-
output: { kind: 'any' },
|
|
417
|
-
implementation: {
|
|
418
|
-
kind: 'runtime-reference', runtime: 'node', artifactSha256: '0'.repeat(64), entrypoint: 'queries.health',
|
|
419
|
-
},
|
|
420
|
-
endpoint: { access: { kind: 'public' }, tenant: { kind: 'not-required' }, method: 'GET', path: '/health' },
|
|
421
|
-
tags: [],
|
|
422
|
-
}],
|
|
423
|
-
};
|
|
424
|
-
case 'ambiguous-query-route': {
|
|
425
|
-
const namedQuery = (name) => ({
|
|
426
|
-
name,
|
|
427
|
-
input: { kind: 'void' },
|
|
428
|
-
output: { kind: 'void' },
|
|
429
|
-
implementation: {
|
|
430
|
-
kind: 'semantic-plan',
|
|
431
|
-
query: { kind: 'dataset', dataset: 'orders', dimensions: [], measures: [], filters: [], orderBy: [] },
|
|
432
|
-
},
|
|
433
|
-
endpoint: { access: { kind: 'public' }, tenant: { kind: 'not-required' }, method: 'GET', path: '/same' },
|
|
434
|
-
tags: [],
|
|
435
|
-
});
|
|
436
|
-
return { ...value, queries: [namedQuery('first'), namedQuery('second')] };
|
|
437
|
-
}
|
|
438
|
-
case 'invalid-sensitivity':
|
|
439
|
-
return { ...value, datasets: [{ ...minimalDataset(), sensitivity: 'secret' }] };
|
|
440
|
-
case 'invalid-currency':
|
|
441
|
-
return { ...value, datasets: [{ ...minimalDataset(), currency: 'usd' }] };
|
|
442
|
-
case 'empty-defaults':
|
|
443
|
-
return { ...value, datasets: [{ ...minimalDataset(), defaults: {} }] };
|
|
444
|
-
case 'default-dimension-not-groupable':
|
|
445
|
-
return {
|
|
446
|
-
...value,
|
|
447
|
-
datasets: [{
|
|
448
|
-
...minimalDataset(),
|
|
449
|
-
dimensions: [{
|
|
450
|
-
name: 'status',
|
|
451
|
-
type: 'string',
|
|
452
|
-
source: { kind: 'column', column: 'status' },
|
|
453
|
-
filterable: true,
|
|
454
|
-
groupable: false,
|
|
455
|
-
}],
|
|
456
|
-
defaults: { dimensions: ['status'] },
|
|
457
|
-
}],
|
|
458
|
-
};
|
|
459
|
-
case 'default-grain-without-time-field':
|
|
460
|
-
// `timeGrain` has nothing to apply to unless the dataset declares
|
|
461
|
-
// `timeField`, so the reference reports it as a broken reference.
|
|
462
|
-
return { ...value, datasets: [{ ...minimalDataset(), defaults: { timeGrain: 'day' } }] };
|
|
463
|
-
case 'too-many-datasets':
|
|
464
|
-
return { ...value, datasets: Array.from({ length: 101 }, (_, i) => minimalDataset(`dataset_${i}`)) };
|
|
465
|
-
case 'too-many-synonyms':
|
|
466
|
-
return {
|
|
467
|
-
...value,
|
|
468
|
-
datasets: [{
|
|
469
|
-
...minimalDataset(),
|
|
470
|
-
synonyms: Array.from({ length: 101 }, (_, i) => `synonym_${i}`),
|
|
471
|
-
}],
|
|
472
|
-
};
|
|
473
|
-
case 'source-too-large':
|
|
474
|
-
return { ...value, datasets: [{ ...minimalDataset(), source: repeat('a', 1_025) }] };
|
|
475
|
-
case 'unsafe-accessor': {
|
|
476
|
-
const unsafe = baseDeployment();
|
|
477
|
-
Object.defineProperty(unsafe, 'kind', { enumerable: true, get: () => 'hypequery-deployment' });
|
|
478
|
-
return unsafe;
|
|
479
|
-
}
|
|
480
|
-
default: throw new Error(`Unknown deployment generator: ${String(spec.type)}`);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
371
|
// --- deployment-bundles-v1 ---
|
|
484
372
|
function bundleArtifact(index = 0) {
|
|
485
373
|
const sha256 = index.toString(16).padStart(64, '0');
|
|
@@ -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-
|
|
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"];
|
|
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;
|
|
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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// goes through the package's supported surface — this is exactly what a second
|
|
4
4
|
// implementation must reproduce.
|
|
5
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';
|
|
6
|
-
import { materializeBundle,
|
|
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. */
|
|
9
9
|
function mapError(error) {
|
|
@@ -51,7 +51,7 @@ export const REFERENCE_FAMILIES = [
|
|
|
51
51
|
'query-implementations-v1',
|
|
52
52
|
'query-events-v1',
|
|
53
53
|
'query-diagnostics-v1',
|
|
54
|
-
'deployments-
|
|
54
|
+
'deployments-v2',
|
|
55
55
|
'deployment-bundles-v1',
|
|
56
56
|
'deployment-releases-v1',
|
|
57
57
|
'semantic-invocations-v1',
|
|
@@ -81,8 +81,8 @@ export function referenceHandle(family, role, c, section) {
|
|
|
81
81
|
validateProtocolQueryDiagnostics(validationInput(c, materializeDiagnostics));
|
|
82
82
|
return ACCEPT;
|
|
83
83
|
});
|
|
84
|
-
case 'deployments-
|
|
85
|
-
return
|
|
84
|
+
case 'deployments-v2':
|
|
85
|
+
return handleDeploymentV2(role, c);
|
|
86
86
|
case 'deployment-bundles-v1':
|
|
87
87
|
return handleBundle(role, c);
|
|
88
88
|
case 'deployment-releases-v1':
|
|
@@ -208,7 +208,7 @@ function handleImplementation(c) {
|
|
|
208
208
|
return ACCEPT;
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
|
-
function
|
|
211
|
+
function handleDeploymentV2(role, c) {
|
|
212
212
|
if (role === 'identity') {
|
|
213
213
|
return attempt(() => {
|
|
214
214
|
const prepared = prepareProtocolDeploymentContract(c.value);
|
|
@@ -216,7 +216,7 @@ function handleDeployment(role, c) {
|
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
return attempt(() => {
|
|
219
|
-
validateProtocolDeploymentContract(
|
|
219
|
+
validateProtocolDeploymentContract(c.value);
|
|
220
220
|
return ACCEPT;
|
|
221
221
|
});
|
|
222
222
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "derived-measures",
|
|
4
|
+
"canonical": "{\"datasets\":[{\"dimensions\":[],\"filters\":[],\"measures\":[{\"aggregation\":\"sum\",\"field\":\"amount\",\"filters\":[],\"name\":\"revenue\"},{\"aggregation\":\"count\",\"field\":\"id\",\"filters\":[],\"name\":\"orders\"},{\"expression\":{\"kind\":\"binary\",\"left\":{\"kind\":\"reference\",\"name\":\"revenue\"},\"operator\":\"divide\",\"right\":{\"args\":[{\"kind\":\"reference\",\"name\":\"orders\"}],\"function\":\"nullIfZero\",\"kind\":\"call\"}},\"kind\":\"derived\",\"name\":\"averageOrderValue\",\"uses\":[{\"alias\":\"revenue\",\"measure\":\"revenue\"},{\"alias\":\"orders\",\"measure\":\"orders\"}]}],\"name\":\"orders\",\"relationships\":[],\"source\":\"orders\",\"tenant\":{\"kind\":\"not-required\"}}],\"kind\":\"hypequery-deployment\",\"version\":2}",
|
|
5
|
+
"sha256": "bd7b6818e8028e609923324455c3842425dcaa447dfd7d792b50de288769f379"
|
|
6
|
+
}
|
|
7
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"id": "derived-measures",
|
|
4
|
+
"value": {
|
|
5
|
+
"kind": "hypequery-deployment",
|
|
6
|
+
"version": 2,
|
|
7
|
+
"datasets": [
|
|
8
|
+
{
|
|
9
|
+
"name": "orders",
|
|
10
|
+
"source": "orders",
|
|
11
|
+
"tenant": {
|
|
12
|
+
"kind": "not-required"
|
|
13
|
+
},
|
|
14
|
+
"dimensions": [],
|
|
15
|
+
"measures": [
|
|
16
|
+
{
|
|
17
|
+
"name": "revenue",
|
|
18
|
+
"aggregation": "sum",
|
|
19
|
+
"field": "amount",
|
|
20
|
+
"filters": []
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "orders",
|
|
24
|
+
"aggregation": "count",
|
|
25
|
+
"field": "id",
|
|
26
|
+
"filters": []
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"kind": "derived",
|
|
30
|
+
"name": "averageOrderValue",
|
|
31
|
+
"uses": [
|
|
32
|
+
{
|
|
33
|
+
"alias": "revenue",
|
|
34
|
+
"measure": "revenue"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"alias": "orders",
|
|
38
|
+
"measure": "orders"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"expression": {
|
|
42
|
+
"kind": "binary",
|
|
43
|
+
"operator": "divide",
|
|
44
|
+
"left": {
|
|
45
|
+
"kind": "reference",
|
|
46
|
+
"name": "revenue"
|
|
47
|
+
},
|
|
48
|
+
"right": {
|
|
49
|
+
"kind": "call",
|
|
50
|
+
"function": "nullIfZero",
|
|
51
|
+
"args": [
|
|
52
|
+
{
|
|
53
|
+
"kind": "reference",
|
|
54
|
+
"name": "orders"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
"filters": [],
|
|
62
|
+
"relationships": []
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[
|
|
2
|
-
{ "id": "empty-object", "value": {}, "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1", "query-diagnostics-v1", "query-implementations-v1", "deployments-
|
|
2
|
+
{ "id": "empty-object", "value": {}, "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1", "query-diagnostics-v1", "query-implementations-v1", "deployments-v2"] },
|
|
3
3
|
{ "id": "null-root", "value": null, "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1", "query-diagnostics-v1"] },
|
|
4
|
-
{ "id": "array-root", "value": [], "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1", "query-diagnostics-v1", "deployments-
|
|
4
|
+
{ "id": "array-root", "value": [], "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1", "query-diagnostics-v1", "deployments-v2"] },
|
|
5
5
|
{ "id": "string-root", "value": "hello", "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1"] },
|
|
6
6
|
{ "id": "number-root", "value": 42, "targets": ["expressions-v1", "query-schemas-v1", "query-events-v1"] },
|
|
7
7
|
{ "id": "unknown-kind", "value": { "kind": "no-such-kind" }, "targets": ["expressions-v1", "query-schemas-v1", "query-implementations-v1"] },
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
{ "id": "unicode-identifier-confusable", "value": { "kind": "reference", "name": "аdmin" }, "targets": ["expressions-v1"] },
|
|
26
26
|
{ "id": "event-kind-only", "value": { "kind": "hypequery-query-event" }, "targets": ["query-events-v1"] },
|
|
27
27
|
{ "id": "diagnostics-kind-only", "value": { "kind": "hypequery-query-diagnostics" }, "targets": ["query-diagnostics-v1"] },
|
|
28
|
-
{ "id": "deployment-kind-only", "value": { "kind": "hypequery-deployment" }, "targets": ["deployments-
|
|
28
|
+
{ "id": "deployment-kind-only", "value": { "kind": "hypequery-deployment" }, "targets": ["deployments-v2"] },
|
|
29
29
|
{ "id": "implementation-kind-only", "value": { "kind": "compiled-sql" }, "targets": ["query-implementations-v1"] },
|
|
30
30
|
{ "id": "negative-version", "value": { "kind": "hypequery-query-event", "version": -1 }, "targets": ["query-events-v1"] },
|
|
31
31
|
{ "id": "float-version", "value": { "kind": "hypequery-query-event", "version": 1.5 }, "targets": ["query-events-v1"] }
|
package/fixtures/manifest.json
CHANGED
|
@@ -92,22 +92,18 @@
|
|
|
92
92
|
]
|
|
93
93
|
},
|
|
94
94
|
{
|
|
95
|
-
"name": "deployments-
|
|
95
|
+
"name": "deployments-v2",
|
|
96
96
|
"rfc": "0006",
|
|
97
97
|
"codePrefixes": [
|
|
98
98
|
"HQ_DEPLOYMENT_"
|
|
99
99
|
],
|
|
100
100
|
"files": [
|
|
101
101
|
{
|
|
102
|
-
"path": "deployments-
|
|
102
|
+
"path": "deployments-v2/success.json",
|
|
103
103
|
"role": "success"
|
|
104
104
|
},
|
|
105
105
|
{
|
|
106
|
-
"path": "deployments-
|
|
107
|
-
"role": "rejection"
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"path": "deployments-v1/identity.json",
|
|
106
|
+
"path": "deployments-v2/identity.json",
|
|
111
107
|
"role": "identity"
|
|
112
108
|
}
|
|
113
109
|
]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/protocol-conformance",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "Cross-language conformance runner for the Hypequery analytics security protocol",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hypequery",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"README.md"
|
|
32
32
|
],
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@hypequery/protocol": "^0.
|
|
34
|
+
"@hypequery/protocol": "^0.14.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^22.5.0",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Deployment contract v1 fixtures
|
|
2
|
-
|
|
3
|
-
These fixtures exercise RFC 0006 deployment envelopes containing datasets, named queries, endpoint policy, and runtime artifact references.
|
|
4
|
-
|
|
5
|
-
- `success.json` contains accepted language-neutral deployments.
|
|
6
|
-
- `rejections.json` pins generated invalid inputs and stable error codes.
|
|
7
|
-
- `identity.json` pins canonical bytes and deployment identities.
|
|
8
|
-
|
|
9
|
-
Coverage includes closed fields, versions, identifiers, relationship queryability, missing runtime artifacts, ambiguous routes, collection limits, source limits, and unsafe accessors.
|
|
10
|
-
|
|
11
|
-
Semantic metadata (`examples`, `synonyms`, `format`, `unit`, `currency`, `timezone`, `sensitivity`) plus dataset `description`, `owner`, `freshness`, and `defaults` are covered by the `dataset-with-semantic-metadata` success case and by rejections for an unsupported sensitivity, a non-ISO currency, empty defaults, a default dimension that is not groupable, a default grain without a time field, and a synonym list above the 100-item semantic-metadata ceiling.
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "dataset-and-runtime-query",
|
|
4
|
-
"canonical": "{\"artifacts\":[{\"artifactSha256\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"runtime\":\"node\"}],\"datasets\":[{\"dimensions\":[{\"filterable\":true,\"groupable\":true,\"name\":\"status\",\"source\":{\"column\":\"status\",\"kind\":\"column\"},\"type\":\"string\"}],\"endpoint\":{\"access\":{\"kind\":\"authenticated\",\"roles\":[],\"scopes\":[\"read:orders\"]},\"maxLimit\":1000,\"path\":\"/api/analytics/datasets/orders/query\",\"tenant\":{\"column\":\"tenant_id\",\"kind\":\"required\",\"mode\":\"auto-inject\"}},\"filters\":[{\"field\":\"status\",\"name\":\"status\",\"operators\":[\"eq\",\"neq\"]}],\"limits\":{\"maxResultSize\":1000},\"measures\":[{\"aggregation\":\"sum\",\"field\":\"amount\",\"filters\":[],\"name\":\"revenue\"}],\"metrics\":[],\"name\":\"orders\",\"relationships\":[],\"source\":\"analytics.orders\",\"tenant\":{\"field\":\"tenant_id\",\"kind\":\"required\"},\"timeField\":\"created_at\"}],\"kind\":\"hypequery-deployment\",\"queries\":[{\"endpoint\":{\"access\":{\"kind\":\"public\"},\"method\":\"GET\",\"path\":\"/api/analytics/queries/health\",\"tenant\":{\"kind\":\"not-required\"}},\"implementation\":{\"artifactSha256\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"entrypoint\":\"queries.health\",\"kind\":\"runtime-reference\",\"runtime\":\"node\"},\"input\":{\"kind\":\"any\"},\"name\":\"health\",\"output\":{\"kind\":\"object\",\"properties\":{\"ok\":{\"kind\":\"boolean\"}},\"required\":[\"ok\"],\"unknownProperties\":\"strip\"},\"tags\":[\"system\"]}],\"version\":1}",
|
|
5
|
-
"sha256": "1ec521ddeb1bf29205a2c0e2876b24b0eab49c0002825bc569071fbf6ad23e2d"
|
|
6
|
-
},
|
|
7
|
-
{
|
|
8
|
-
"id": "dataset-with-semantic-metadata",
|
|
9
|
-
"canonical": "{\"artifacts\":[],\"datasets\":[{\"defaults\":{\"dimensions\":[\"status\"],\"timeGrain\":\"day\"},\"description\":\"Completed customer orders.\",\"dimensions\":[{\"examples\":[\"paid\",\"refunded\"],\"filterable\":true,\"groupable\":true,\"name\":\"status\",\"sensitivity\":\"public\",\"source\":{\"column\":\"status\",\"kind\":\"column\"},\"synonyms\":[\"state\"],\"type\":\"string\"}],\"filters\":[{\"examples\":[\"paid\"],\"field\":\"status\",\"name\":\"status\",\"operators\":[\"eq\",\"neq\"]}],\"freshness\":{\"maxAgeSeconds\":3600},\"measures\":[{\"aggregation\":\"sum\",\"currency\":\"USD\",\"field\":\"amount\",\"filters\":[],\"format\":\"0,0.00\",\"name\":\"revenue\",\"sensitivity\":\"confidential\",\"unit\":\"currency\"}],\"metrics\":[],\"name\":\"orders\",\"owner\":\"revenue-team\",\"relationships\":[],\"sensitivity\":\"internal\",\"source\":\"analytics.orders\",\"synonyms\":[\"purchases\",\"sales\"],\"tenant\":{\"field\":\"tenant_id\",\"kind\":\"required\"},\"timeField\":\"created_at\",\"timezone\":\"UTC\"}],\"kind\":\"hypequery-deployment\",\"queries\":[],\"version\":1}",
|
|
10
|
-
"sha256": "c5c349d90561634fa773753d0bccddfb8af60925f09bb0c9310af8fae3762ca9"
|
|
11
|
-
}
|
|
12
|
-
]
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{ "id": "wrong-root-type", "generator": { "type": "wrong-root-type" }, "error": "HQ_DEPLOYMENT_TYPE" },
|
|
3
|
-
{ "id": "unknown-root-field", "generator": { "type": "unknown-root-field" }, "error": "HQ_DEPLOYMENT_UNKNOWN_FIELD" },
|
|
4
|
-
{ "id": "unsupported-version", "generator": { "type": "unsupported-version" }, "error": "HQ_DEPLOYMENT_INVALID_VERSION" },
|
|
5
|
-
{ "id": "invalid-dataset-identifier", "generator": { "type": "invalid-dataset-identifier" }, "error": "HQ_DEPLOYMENT_INVALID_IDENTIFIER" },
|
|
6
|
-
{ "id": "invalid-relationship-queryability", "generator": { "type": "invalid-relationship-queryability" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
|
|
7
|
-
{ "id": "missing-runtime-artifact", "generator": { "type": "missing-runtime-artifact" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
|
|
8
|
-
{ "id": "ambiguous-query-route", "generator": { "type": "ambiguous-query-route" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
|
|
9
|
-
{ "id": "invalid-sensitivity", "generator": { "type": "invalid-sensitivity" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
|
|
10
|
-
{ "id": "invalid-currency", "generator": { "type": "invalid-currency" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
|
|
11
|
-
{ "id": "empty-defaults", "generator": { "type": "empty-defaults" }, "error": "HQ_DEPLOYMENT_INVALID_VALUE" },
|
|
12
|
-
{ "id": "default-dimension-not-groupable", "generator": { "type": "default-dimension-not-groupable" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
|
|
13
|
-
{ "id": "default-grain-without-time-field", "generator": { "type": "default-grain-without-time-field" }, "error": "HQ_DEPLOYMENT_INVALID_REFERENCE" },
|
|
14
|
-
{ "id": "too-many-datasets", "generator": { "type": "too-many-datasets" }, "error": "HQ_DEPLOYMENT_TOO_MANY_ITEMS" },
|
|
15
|
-
{ "id": "too-many-synonyms", "generator": { "type": "too-many-synonyms" }, "error": "HQ_DEPLOYMENT_TOO_MANY_ITEMS" },
|
|
16
|
-
{ "id": "source-too-large", "generator": { "type": "source-too-large" }, "error": "HQ_DEPLOYMENT_TOO_LARGE" },
|
|
17
|
-
{ "id": "unsafe-accessor", "generator": { "type": "unsafe-accessor" }, "error": "HQ_DEPLOYMENT_UNSAFE_OBJECT" }
|
|
18
|
-
]
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "dataset-and-runtime-query",
|
|
4
|
-
"value": {
|
|
5
|
-
"kind": "hypequery-deployment",
|
|
6
|
-
"version": 1,
|
|
7
|
-
"datasets": [
|
|
8
|
-
{
|
|
9
|
-
"name": "orders",
|
|
10
|
-
"source": "analytics.orders",
|
|
11
|
-
"tenant": { "kind": "required", "field": "tenant_id" },
|
|
12
|
-
"timeField": "created_at",
|
|
13
|
-
"dimensions": [
|
|
14
|
-
{
|
|
15
|
-
"name": "status",
|
|
16
|
-
"type": "string",
|
|
17
|
-
"source": { "kind": "column", "column": "status" },
|
|
18
|
-
"filterable": true,
|
|
19
|
-
"groupable": true
|
|
20
|
-
}
|
|
21
|
-
],
|
|
22
|
-
"measures": [
|
|
23
|
-
{
|
|
24
|
-
"name": "revenue",
|
|
25
|
-
"aggregation": "sum",
|
|
26
|
-
"field": "amount",
|
|
27
|
-
"filters": []
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
"filters": [
|
|
31
|
-
{
|
|
32
|
-
"name": "status",
|
|
33
|
-
"field": "status",
|
|
34
|
-
"operators": ["eq", "neq"]
|
|
35
|
-
}
|
|
36
|
-
],
|
|
37
|
-
"metrics": [],
|
|
38
|
-
"relationships": [],
|
|
39
|
-
"limits": { "maxResultSize": 1000 },
|
|
40
|
-
"endpoint": {
|
|
41
|
-
"access": { "kind": "authenticated", "roles": [], "scopes": ["read:orders"] },
|
|
42
|
-
"tenant": { "kind": "required", "mode": "auto-inject", "column": "tenant_id" },
|
|
43
|
-
"maxLimit": 1000,
|
|
44
|
-
"path": "/api/analytics/datasets/orders/query"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
],
|
|
48
|
-
"queries": [
|
|
49
|
-
{
|
|
50
|
-
"name": "health",
|
|
51
|
-
"input": { "kind": "any" },
|
|
52
|
-
"output": {
|
|
53
|
-
"kind": "object",
|
|
54
|
-
"properties": { "ok": { "kind": "boolean" } },
|
|
55
|
-
"required": ["ok"],
|
|
56
|
-
"unknownProperties": "strip"
|
|
57
|
-
},
|
|
58
|
-
"implementation": {
|
|
59
|
-
"kind": "runtime-reference",
|
|
60
|
-
"runtime": "node",
|
|
61
|
-
"artifactSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
|
|
62
|
-
"entrypoint": "queries.health"
|
|
63
|
-
},
|
|
64
|
-
"endpoint": {
|
|
65
|
-
"access": { "kind": "public" },
|
|
66
|
-
"tenant": { "kind": "not-required" },
|
|
67
|
-
"method": "GET",
|
|
68
|
-
"path": "/api/analytics/queries/health"
|
|
69
|
-
},
|
|
70
|
-
"tags": ["system"]
|
|
71
|
-
}
|
|
72
|
-
],
|
|
73
|
-
"artifacts": [
|
|
74
|
-
{
|
|
75
|
-
"runtime": "node",
|
|
76
|
-
"artifactSha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"id": "dataset-with-semantic-metadata",
|
|
83
|
-
"value": {
|
|
84
|
-
"kind": "hypequery-deployment",
|
|
85
|
-
"version": 1,
|
|
86
|
-
"datasets": [
|
|
87
|
-
{
|
|
88
|
-
"name": "orders",
|
|
89
|
-
"description": "Completed customer orders.",
|
|
90
|
-
"source": "analytics.orders",
|
|
91
|
-
"owner": "revenue-team",
|
|
92
|
-
"freshness": { "maxAgeSeconds": 3600 },
|
|
93
|
-
"defaults": { "dimensions": ["status"], "timeGrain": "day" },
|
|
94
|
-
"synonyms": ["purchases", "sales"],
|
|
95
|
-
"timezone": "UTC",
|
|
96
|
-
"sensitivity": "internal",
|
|
97
|
-
"tenant": { "kind": "required", "field": "tenant_id" },
|
|
98
|
-
"timeField": "created_at",
|
|
99
|
-
"dimensions": [
|
|
100
|
-
{
|
|
101
|
-
"name": "status",
|
|
102
|
-
"type": "string",
|
|
103
|
-
"source": { "kind": "column", "column": "status" },
|
|
104
|
-
"filterable": true,
|
|
105
|
-
"groupable": true,
|
|
106
|
-
"examples": ["paid", "refunded"],
|
|
107
|
-
"synonyms": ["state"],
|
|
108
|
-
"sensitivity": "public"
|
|
109
|
-
}
|
|
110
|
-
],
|
|
111
|
-
"measures": [
|
|
112
|
-
{
|
|
113
|
-
"name": "revenue",
|
|
114
|
-
"aggregation": "sum",
|
|
115
|
-
"field": "amount",
|
|
116
|
-
"filters": [],
|
|
117
|
-
"format": "0,0.00",
|
|
118
|
-
"unit": "currency",
|
|
119
|
-
"currency": "USD",
|
|
120
|
-
"sensitivity": "confidential"
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
"filters": [
|
|
124
|
-
{
|
|
125
|
-
"name": "status",
|
|
126
|
-
"field": "status",
|
|
127
|
-
"operators": ["eq", "neq"],
|
|
128
|
-
"examples": ["paid"]
|
|
129
|
-
}
|
|
130
|
-
],
|
|
131
|
-
"metrics": [],
|
|
132
|
-
"relationships": []
|
|
133
|
-
}
|
|
134
|
-
],
|
|
135
|
-
"queries": [],
|
|
136
|
-
"artifacts": []
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
]
|