@hypequery/protocol-conformance 0.11.1 → 0.12.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.
@@ -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;AA2BD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAyFzD;AAkBD,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,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-v1", "deployment-bundles-v1", "deployment-releases-v1", "semantic-invocations-v1"];
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;AAe9D,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":"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, materializeDeployment, materializeDiagnostics, materializeEvent, materializeSemanticInvocation, materializeExpression, materializeIdentifier, materializeImplementation, materializeRelease, materializeSchema, materializeTaggedValue, } from './generators.js';
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-v1',
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-v1':
85
- return handleDeployment(role, c);
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 handleDeployment(role, c) {
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(validationInput(c, materializeDeployment));
219
+ validateProtocolDeploymentContract(c.value);
220
220
  return ACCEPT;
221
221
  });
222
222
  }
@@ -0,0 +1,15 @@
1
+ # Deployment contract v2 fixtures
2
+
3
+ `success.json` holds contracts every implementation must accept, `identity.json`
4
+ pins the canonical bytes and SHA-256 of the success case sharing its id, and
5
+ `rejections.json` pins a stable failure code for each rule the contract states.
6
+
7
+ Acceptance of RFC 0006 added the rejection corpus. Before it, the family had one
8
+ success and one identity case, which cannot tell a faithful validator from one
9
+ that accepts contracts another implementation rejects — the corpus now covers
10
+ the envelope's forbidden fields, the null-versus-absent distinction, relationship
11
+ and tenant agreement, measure shape, semantic metadata, defaults, endpoint
12
+ policy, and derived-measure rules.
13
+
14
+ Every case was checked against both the TypeScript and Python implementations
15
+ before being recorded; none of them changed either implementation's behaviour.
@@ -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
+ ]