@hypequery/protocol 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/deployments/codec.d.ts +2 -7
- package/dist/deployments/codec.d.ts.map +1 -1
- package/dist/deployments/codec.js +5 -15
- package/dist/deployments/index.d.ts +1 -1
- package/dist/deployments/index.d.ts.map +1 -1
- package/dist/deployments/limits.d.ts.map +1 -1
- package/dist/deployments/limits.js +1 -3
- package/dist/deployments/types.d.ts +22 -22
- package/dist/deployments/types.d.ts.map +1 -1
- package/dist/deployments/validate.d.ts +1 -0
- package/dist/deployments/validate.d.ts.map +1 -1
- package/dist/deployments/validate.js +112 -154
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/query-implementations/index.d.ts +2 -1
- package/dist/query-implementations/index.d.ts.map +1 -1
- package/dist/query-implementations/index.js +2 -1
- package/dist/query-implementations/validate.d.ts +1 -2
- package/dist/query-implementations/validate.d.ts.map +1 -1
- package/dist/query-implementations/validate.js +0 -33
- package/dist/sql-expressions/validate.d.ts +4 -0
- package/dist/sql-expressions/validate.d.ts.map +1 -0
- package/dist/sql-expressions/validate.js +119 -0
- package/dist/values/validate.d.ts.map +1 -1
- package/dist/values/validate.js +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ This package implements those rules in TypeScript. Python and other implementati
|
|
|
22
22
|
- closed semantic expression and query envelopes
|
|
23
23
|
- portable input and output schemas
|
|
24
24
|
- trusted query implementation artifacts
|
|
25
|
-
- dataset and
|
|
25
|
+
- dataset deployment contracts with base and derived measures
|
|
26
26
|
- closed deployment bundle manifests
|
|
27
27
|
- project/environment release envelopes
|
|
28
28
|
- compiled query settings, cancellation, events, and diagnostics
|
|
@@ -53,7 +53,7 @@ Schema validators cover the declarative Serve/Zod features that can travel betwe
|
|
|
53
53
|
|
|
54
54
|
## Deployment artifacts
|
|
55
55
|
|
|
56
|
-
A deployment combines dataset definitions
|
|
56
|
+
A deployment combines dataset definitions and endpoint policies in one strict versioned envelope. Derived measures live alongside base measures in each dataset; queries and standalone metrics are not deployment targets. Bundle manifests bind declared files by path, byte length, and hash; the deployment verifier accepts only bundles with no runtime artifacts. Release envelopes bind a verified bundle to one explicit project and environment.
|
|
57
57
|
|
|
58
58
|
Canonical encoders and domain-separated SHA-256 identities make these artifacts reproducible across language implementations. Filesystem-safe construction and verification live in `@hypequery/deployment` and the CLI.
|
|
59
59
|
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { ProtocolDeploymentContract, ProtocolDeploymentOptions } from './types.js';
|
|
2
|
-
|
|
3
|
-
export declare const PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN = "hypequery:deployment:v1\0";
|
|
2
|
+
export declare const PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN = "hypequery:deployment:v2\0";
|
|
4
3
|
export interface PreparedProtocolDeploymentContract {
|
|
5
4
|
readonly contract: ProtocolDeploymentContract;
|
|
6
5
|
readonly canonical: string;
|
|
7
6
|
readonly bytes: Uint8Array;
|
|
8
7
|
readonly identity: string;
|
|
9
8
|
}
|
|
10
|
-
/** Validates and serializes once, returning every deployment artifact representation. */
|
|
11
9
|
export declare function prepareProtocolDeploymentContract(input: unknown, options?: ProtocolDeploymentOptions): PreparedProtocolDeploymentContract;
|
|
12
|
-
/** Validates a deployment contract and returns canonical RFC 8785 UTF-8 bytes. */
|
|
13
10
|
export declare function encodeProtocolDeploymentContract(input: unknown, options?: ProtocolDeploymentOptions): Uint8Array;
|
|
14
|
-
/** String form of the canonical deployment contract bytes. */
|
|
15
|
-
export declare function encodeProtocolDeploymentContractToString(input: unknown, options?: ProtocolDeploymentOptions): string;
|
|
16
|
-
/** Domain-separated SHA-256 identity of a validated deployment contract. */
|
|
17
11
|
export declare function hashProtocolDeploymentContract(input: unknown, options?: ProtocolDeploymentOptions): string;
|
|
12
|
+
export declare function encodeProtocolDeploymentContractToString(input: unknown, options?: ProtocolDeploymentOptions): string;
|
|
18
13
|
//# sourceMappingURL=codec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/deployments/codec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAKxF,
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/deployments/codec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAKxF,eAAO,MAAM,mCAAmC,8BAA8B,CAAC;AAE/E,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,kCAAkC,CASpC;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,UAAU,CAEZ;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAER;AAED,wBAAgB,wCAAwC,CACtD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAER"}
|
|
@@ -3,9 +3,7 @@ import { bytesToHex } from '@noble/hashes/utils';
|
|
|
3
3
|
import { serializeJcs } from '../values/jcs.js';
|
|
4
4
|
import { validateProtocolDeploymentContract } from './validate.js';
|
|
5
5
|
const textEncoder = new TextEncoder();
|
|
6
|
-
|
|
7
|
-
export const PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN = 'hypequery:deployment:v1\0';
|
|
8
|
-
/** Validates and serializes once, returning every deployment artifact representation. */
|
|
6
|
+
export const PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN = 'hypequery:deployment:v2\0';
|
|
9
7
|
export function prepareProtocolDeploymentContract(input, options = {}) {
|
|
10
8
|
const contract = validateProtocolDeploymentContract(input, options);
|
|
11
9
|
const canonical = serializeJcs(contract);
|
|
@@ -14,22 +12,14 @@ export function prepareProtocolDeploymentContract(input, options = {}) {
|
|
|
14
12
|
.update(textEncoder.encode(PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN))
|
|
15
13
|
.update(bytes)
|
|
16
14
|
.digest());
|
|
17
|
-
return Object.freeze({
|
|
18
|
-
contract,
|
|
19
|
-
canonical,
|
|
20
|
-
bytes,
|
|
21
|
-
identity,
|
|
22
|
-
});
|
|
15
|
+
return Object.freeze({ contract, canonical, bytes, identity });
|
|
23
16
|
}
|
|
24
|
-
/** Validates a deployment contract and returns canonical RFC 8785 UTF-8 bytes. */
|
|
25
17
|
export function encodeProtocolDeploymentContract(input, options = {}) {
|
|
26
18
|
return prepareProtocolDeploymentContract(input, options).bytes;
|
|
27
19
|
}
|
|
28
|
-
/** String form of the canonical deployment contract bytes. */
|
|
29
|
-
export function encodeProtocolDeploymentContractToString(input, options = {}) {
|
|
30
|
-
return prepareProtocolDeploymentContract(input, options).canonical;
|
|
31
|
-
}
|
|
32
|
-
/** Domain-separated SHA-256 identity of a validated deployment contract. */
|
|
33
20
|
export function hashProtocolDeploymentContract(input, options = {}) {
|
|
34
21
|
return prepareProtocolDeploymentContract(input, options).identity;
|
|
35
22
|
}
|
|
23
|
+
export function encodeProtocolDeploymentContractToString(input, options = {}) {
|
|
24
|
+
return prepareProtocolDeploymentContract(input, options).canonical;
|
|
25
|
+
}
|
|
@@ -3,5 +3,5 @@ export { PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN, encodeProtocolDeploymentContract,
|
|
|
3
3
|
export type { PreparedProtocolDeploymentContract } from './codec.js';
|
|
4
4
|
export { DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS } from './limits.js';
|
|
5
5
|
export { validateProtocolDatasetContract, validateProtocolDeploymentContract, } from './validate.js';
|
|
6
|
-
export type { ProtocolAccessPolicy, ProtocolDatasetContract, ProtocolDatasetDefaults, ProtocolDatasetDimension, ProtocolDatasetFieldSource, ProtocolDatasetFieldType, ProtocolDatasetFilter, ProtocolDatasetFreshness, ProtocolDatasetLimits, ProtocolDatasetMeasure, ProtocolDatasetMetric, ProtocolDatasetRelationship, ProtocolDatasetTenantPolicy, ProtocolSemanticMetadata, ProtocolSemanticSensitivity, ProtocolDeploymentContract, ProtocolDeploymentErrorCode, ProtocolDeploymentLimits, ProtocolDeploymentOptions, ProtocolEndpointPolicy, ProtocolEndpointTenantPolicy, ProtocolMetricDerivation, ProtocolMetricInput,
|
|
6
|
+
export type { ProtocolDatasetDerivedMeasure, ProtocolDeploymentDataset, ProtocolDeploymentMeasure, ProtocolAccessPolicy, ProtocolDatasetContract, ProtocolDatasetDefaults, ProtocolDatasetDimension, ProtocolDatasetFieldSource, ProtocolDatasetFieldType, ProtocolDatasetFilter, ProtocolDatasetFreshness, ProtocolDatasetLimits, ProtocolDatasetMeasure, ProtocolDatasetMetric, ProtocolDatasetRelationship, ProtocolDatasetTenantPolicy, ProtocolSemanticMetadata, ProtocolSemanticSensitivity, ProtocolDeploymentContract, ProtocolDeploymentErrorCode, ProtocolDeploymentLimits, ProtocolDeploymentOptions, ProtocolEndpointPolicy, ProtocolEndpointTenantPolicy, ProtocolMetricDerivation, ProtocolMetricInput, } from './types.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/deployments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,mCAAmC,EACnC,gCAAgC,EAChC,wCAAwC,EACxC,8BAA8B,EAC9B,iCAAiC,GAClC,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/deployments/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,mCAAmC,EACnC,gCAAgC,EAChC,wCAAwC,EACxC,8BAA8B,EAC9B,iCAAiC,GAClC,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,kCAAkC,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,kCAAkC,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,GACnC,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/deployments/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEtF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CAAC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/deployments/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEtF,eAAO,MAAM,kCAAkC,EAAE,QAAQ,CAAC,wBAAwB,CAOhF,CAAC;AAEH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,yBAA8B,GACtC,QAAQ,CAAC,wBAAwB,CAAC,CAcpC"}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export const DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS = Object.freeze({
|
|
2
2
|
maxDatasets: 100,
|
|
3
|
-
maxQueries: 1_000,
|
|
4
|
-
maxArtifacts: 100,
|
|
5
3
|
maxDatasetItems: 1_000,
|
|
6
4
|
maxSemanticMetadataItems: 100,
|
|
7
5
|
maxTextBytes: 4_096,
|
|
@@ -16,7 +14,7 @@ export function resolveDeploymentLimits(options = {}) {
|
|
|
16
14
|
continue;
|
|
17
15
|
const maximum = DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS[key];
|
|
18
16
|
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) {
|
|
19
|
-
throw new RangeError(`${key} must be a positive safe integer no greater than ${maximum} (the deployment contract
|
|
17
|
+
throw new RangeError(`${key} must be a positive safe integer no greater than ${maximum} (the deployment contract maximum)`);
|
|
20
18
|
}
|
|
21
19
|
result[key] = value;
|
|
22
20
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ProtocolExpression, ProtocolTimeGrain } from '../expressions/index.js';
|
|
2
2
|
import type { ProtocolIdentifier, ProtocolQualifiedIdentifier } from '../identifiers/index.js';
|
|
3
|
-
import type {
|
|
4
|
-
import type { ProtocolSchema } from '../schemas/index.js';
|
|
3
|
+
import type { ProtocolSqlExpression } from '../query-implementations/index.js';
|
|
5
4
|
export type ProtocolDatasetFieldType = 'string' | 'number' | 'boolean' | 'timestamp';
|
|
6
5
|
export type ProtocolSemanticSensitivity = 'public' | 'internal' | 'confidential' | 'restricted';
|
|
7
6
|
export interface ProtocolSemanticMetadata {
|
|
@@ -148,34 +147,35 @@ export interface ProtocolDatasetContract extends ProtocolSemanticMetadata {
|
|
|
148
147
|
readonly limits?: ProtocolDatasetLimits;
|
|
149
148
|
readonly endpoint?: ProtocolEndpointPolicy;
|
|
150
149
|
}
|
|
151
|
-
|
|
150
|
+
/** A post-aggregation formula over base measures in the same dataset. */
|
|
151
|
+
export interface ProtocolDatasetDerivedMeasure extends ProtocolSemanticMetadata {
|
|
152
|
+
readonly kind: 'derived';
|
|
152
153
|
readonly name: ProtocolIdentifier;
|
|
153
|
-
|
|
154
|
-
readonly
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
readonly summary?: string;
|
|
154
|
+
/** Authored alias order is retained for deterministic reconstruction. */
|
|
155
|
+
readonly uses: readonly {
|
|
156
|
+
readonly alias: ProtocolIdentifier;
|
|
157
|
+
readonly measure: ProtocolIdentifier;
|
|
158
|
+
}[];
|
|
159
|
+
readonly expression: ProtocolExpression;
|
|
160
|
+
readonly label?: string;
|
|
161
161
|
readonly description?: string;
|
|
162
|
-
readonly tags: readonly string[];
|
|
163
162
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
163
|
+
/** The v2 wire folds authored base and derived measures into one collection. */
|
|
164
|
+
export type ProtocolDeploymentMeasure = ProtocolDatasetMeasure | ProtocolDatasetDerivedMeasure;
|
|
165
|
+
export interface ProtocolDeploymentDataset extends Omit<ProtocolDatasetContract, 'measures' | 'metrics'> {
|
|
166
|
+
readonly measures: readonly ProtocolDeploymentMeasure[];
|
|
167
|
+
readonly metrics?: never;
|
|
167
168
|
}
|
|
169
|
+
/** The deployment contract contains executable datasets and derived measures. */
|
|
168
170
|
export interface ProtocolDeploymentContract {
|
|
169
171
|
readonly kind: 'hypequery-deployment';
|
|
170
|
-
readonly version:
|
|
171
|
-
readonly datasets: readonly
|
|
172
|
-
readonly queries
|
|
173
|
-
readonly artifacts
|
|
172
|
+
readonly version: 2;
|
|
173
|
+
readonly datasets: readonly ProtocolDeploymentDataset[];
|
|
174
|
+
readonly queries?: never;
|
|
175
|
+
readonly artifacts?: never;
|
|
174
176
|
}
|
|
175
177
|
export interface ProtocolDeploymentLimits {
|
|
176
178
|
readonly maxDatasets: number;
|
|
177
|
-
readonly maxQueries: number;
|
|
178
|
-
readonly maxArtifacts: number;
|
|
179
179
|
readonly maxDatasetItems: number;
|
|
180
180
|
/**
|
|
181
181
|
* Ceiling on each semantic-metadata collection (`examples`, `synonyms`, and
|
|
@@ -193,7 +193,7 @@ export interface ProtocolDeploymentLimits {
|
|
|
193
193
|
*
|
|
194
194
|
* Each configured value must be a positive safe integer no greater than the
|
|
195
195
|
* corresponding value in `DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS`. These options
|
|
196
|
-
* may tighten the deployment
|
|
196
|
+
* may tighten the deployment contract limits, but cannot raise
|
|
197
197
|
* them; they are not deployment capacity settings.
|
|
198
198
|
*/
|
|
199
199
|
export interface ProtocolDeploymentOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/deployments/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAC/F,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/deployments/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAC/F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE/E,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AACrF,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,UAAU,GAAG,cAAc,GAAG,YAAY,CAAC;AAEhG,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,2BAA2B,CAAC;CACpD;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACpD,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;CACxC;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IACE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;AAEN,MAAM,MAAM,4BAA4B,GACpC;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GACjC;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,QAAQ,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEN,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,4BAA4B,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,2BAA2B,GACnC;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAEtC,MAAM,MAAM,0BAA0B,GAClC;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD,qBAAqB,CAAC;AAE1B,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACxE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAuB,SAAQ,wBAAwB;IACtE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,EAChB,KAAK,GAAG,OAAO,GAAG,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GACzD,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC/D,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,CACzB,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAC1C,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CACtC,EAAE,CAAC;IACJ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;IAClD,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAC3C,QAAQ,CAAC,EAAE,EAAE,2BAA2B,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;CACzC;AAED,MAAM,WAAW,qBAAsB,SAAQ,wBAAwB;IACrE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAC9D,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,wBAAwB,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,2BAA2B,EAAE,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,QAAQ,CAAC,MAAM,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,wBAAwB,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACjD,QAAQ,CAAC,UAAU,EAAE,SAAS,wBAAwB,EAAE,CAAC;IACzD,QAAQ,CAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,SAAS,2BAA2B,EAAE,CAAC;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;CAC5C;AAED,yEAAyE;AACzE,MAAM,WAAW,6BAA8B,SAAQ,wBAAwB;IAC7E,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,SAAS;QACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;QACnC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC;KACtC,EAAE,CAAC;IACJ,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,gFAAgF;AAChF,MAAM,MAAM,yBAAyB,GAAG,sBAAsB,GAAG,6BAA6B,CAAC;AAE/F,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,uBAAuB,EAAE,UAAU,GAAG,SAAS,CAAC;IACtG,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;CAC1B;AAED,iFAAiF;AACjF,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACxD,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IACzB,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,2BAA2B,GACnC,oBAAoB,GACpB,6BAA6B,GAC7B,+BAA+B,GAC/B,kCAAkC,GAClC,6BAA6B,GAC7B,iCAAiC,GACjC,8BAA8B,GAC9B,yBAAyB,GACzB,6BAA6B,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProtocolDatasetContract, ProtocolDeploymentContract, ProtocolDeploymentOptions } from './types.js';
|
|
2
2
|
export declare function validateProtocolDatasetContract(input: unknown, options?: ProtocolDeploymentOptions): ProtocolDatasetContract;
|
|
3
|
+
/** Validate the deployment contract. Unsupported fields are forbidden, even when empty. */
|
|
3
4
|
export declare function validateProtocolDeploymentContract(input: unknown, options?: ProtocolDeploymentOptions): ProtocolDeploymentContract;
|
|
4
5
|
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/deployments/validate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/deployments/validate.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAEV,uBAAuB,EAEvB,0BAA0B,EAa1B,yBAAyB,EAG1B,MAAM,YAAY,CAAC;AAqwBpB,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,uBAAuB,CAEzB;AA8ID,2FAA2F;AAC3F,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,yBAA8B,GACtC,0BAA0B,CAU5B"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ProtocolExpressionError, validateProtocolExpression } from '../expressions/index.js';
|
|
2
2
|
import { ProtocolIdentifierError, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, } from '../identifiers/index.js';
|
|
3
|
-
import {
|
|
4
|
-
import { ProtocolSchemaError, validateProtocolSchema, } from '../schemas/index.js';
|
|
3
|
+
import { validateProtocolSqlExpression } from '../sql-expressions/validate.js';
|
|
5
4
|
import { deploymentError } from './errors.js';
|
|
6
5
|
import { resolveDeploymentLimits } from './limits.js';
|
|
7
6
|
const textEncoder = new TextEncoder();
|
|
8
|
-
const SHA256_PATTERN = /^[0-9a-f]{64}$/;
|
|
9
7
|
const AGGREGATIONS = new Set([
|
|
10
8
|
'sum', 'count', 'countDistinct', 'avg', 'min', 'max',
|
|
11
9
|
'argMax', 'argMin', 'percentile', 'stddev', 'variance',
|
|
@@ -51,8 +49,10 @@ function requireArray(input, path, maxItems) {
|
|
|
51
49
|
deploymentError('HQ_DEPLOYMENT_UNSAFE_OBJECT', `${path}[${index}]`);
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
|
-
if (Object.keys(input).length !== input.length
|
|
52
|
+
if (Object.keys(input).length !== input.length
|
|
53
|
+
|| Object.getOwnPropertyNames(input).length !== input.length + 1) {
|
|
55
54
|
deploymentError('HQ_DEPLOYMENT_UNSAFE_OBJECT', path);
|
|
55
|
+
}
|
|
56
56
|
return input;
|
|
57
57
|
}
|
|
58
58
|
function exactFields(value, required, optional, path) {
|
|
@@ -179,9 +179,9 @@ function validateEndpointTenant(input, path, limits) {
|
|
|
179
179
|
deploymentError('HQ_DEPLOYMENT_TYPE', `${path}.kind`);
|
|
180
180
|
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.kind`);
|
|
181
181
|
}
|
|
182
|
-
function validateEndpoint(input, path, limits
|
|
182
|
+
function validateEndpoint(input, path, limits) {
|
|
183
183
|
const value = requireRecord(input, path);
|
|
184
|
-
exactFields(value,
|
|
184
|
+
exactFields(value, ['access', 'tenant'], ['cacheTtlMs', 'maxLimit', 'path'], path);
|
|
185
185
|
const result = {
|
|
186
186
|
access: validateAccess(value.access, `${path}.access`, limits),
|
|
187
187
|
tenant: validateEndpointTenant(value.tenant, `${path}.tenant`, limits),
|
|
@@ -190,22 +190,12 @@ function validateEndpoint(input, path, limits, transport = false) {
|
|
|
190
190
|
result.cacheTtlMs = positiveInteger(value.cacheTtlMs, `${path}.cacheTtlMs`);
|
|
191
191
|
if (value.maxLimit !== undefined)
|
|
192
192
|
result.maxLimit = positiveInteger(value.maxLimit, `${path}.maxLimit`);
|
|
193
|
-
if (
|
|
193
|
+
if (value.path !== undefined) {
|
|
194
194
|
const endpointPath = boundedText(value.path, `${path}.path`, limits.maxPathBytes);
|
|
195
195
|
if (!endpointPath.startsWith('/'))
|
|
196
196
|
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.path`);
|
|
197
197
|
result.path = endpointPath;
|
|
198
198
|
}
|
|
199
|
-
if (transport) {
|
|
200
|
-
if (!['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'].includes(value.method)) {
|
|
201
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.method`);
|
|
202
|
-
}
|
|
203
|
-
const endpointPath = boundedText(value.path, `${path}.path`, limits.maxPathBytes);
|
|
204
|
-
if (!endpointPath.startsWith('/'))
|
|
205
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.path`);
|
|
206
|
-
result.method = value.method;
|
|
207
|
-
result.path = endpointPath;
|
|
208
|
-
}
|
|
209
199
|
return freezeRecord(result);
|
|
210
200
|
}
|
|
211
201
|
function validateTenant(input, path, limits) {
|
|
@@ -230,9 +220,7 @@ function nested(action, path) {
|
|
|
230
220
|
return action();
|
|
231
221
|
}
|
|
232
222
|
catch (error) {
|
|
233
|
-
if (error instanceof ProtocolExpressionError
|
|
234
|
-
|| error instanceof ProtocolQueryImplementationError
|
|
235
|
-
|| error instanceof ProtocolSchemaError) {
|
|
223
|
+
if (error instanceof ProtocolExpressionError) {
|
|
236
224
|
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', path);
|
|
237
225
|
}
|
|
238
226
|
throw error;
|
|
@@ -576,13 +564,13 @@ function validateDefaults(input, path, limits) {
|
|
|
576
564
|
return freezeRecord(result);
|
|
577
565
|
}
|
|
578
566
|
function namedItems(input, path, maxItems, validate) {
|
|
579
|
-
const items = requireArray(input, path, maxItems).map((value, index) => validate(value, `${path}[${index}]
|
|
567
|
+
const items = requireArray(input, path, maxItems).map((value, index) => validate(value, `${path}[${index}]`, index));
|
|
580
568
|
if (new Set(items.map(item => item.name)).size !== items.length) {
|
|
581
569
|
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', path);
|
|
582
570
|
}
|
|
583
571
|
return Object.freeze(items);
|
|
584
572
|
}
|
|
585
|
-
function validateDataset(input, path, limits) {
|
|
573
|
+
function validateDataset(input, path, limits, measureIndices) {
|
|
586
574
|
const value = requireRecord(input, path);
|
|
587
575
|
exactFields(value, ['name', 'source', 'tenant', 'dimensions', 'measures', 'filters', 'metrics', 'relationships'], [
|
|
588
576
|
'description', 'freshness', 'owner', 'defaults',
|
|
@@ -594,7 +582,7 @@ function validateDataset(input, path, limits) {
|
|
|
594
582
|
source: boundedText(value.source, `${path}.source`, limits.maxSourceBytes),
|
|
595
583
|
tenant: validateTenant(value.tenant, `${path}.tenant`, limits),
|
|
596
584
|
dimensions: namedItems(value.dimensions, `${path}.dimensions`, limits.maxDatasetItems, (item, itemPath) => validateDimension(item, itemPath, limits)),
|
|
597
|
-
measures: namedItems(value.measures, `${path}.measures`, limits.maxDatasetItems, (item, itemPath) => validateMeasure(item, itemPath
|
|
585
|
+
measures: namedItems(value.measures, `${path}.measures`, limits.maxDatasetItems, (item, itemPath, index) => validateMeasure(item, measureIndices === undefined ? itemPath : `${path}.measures[${measureIndices[index]}]`, limits)),
|
|
598
586
|
filters: namedItems(value.filters, `${path}.filters`, limits.maxDatasetItems, (item, itemPath) => validateFilter(item, itemPath, limits)),
|
|
599
587
|
metrics: namedItems(value.metrics, `${path}.metrics`, limits.maxDatasetItems, (item, itemPath) => validateMetric(item, itemPath, limits)),
|
|
600
588
|
relationships: namedItems(value.relationships, `${path}.relationships`, limits.maxDatasetItems, (item, itemPath) => validateRelationship(item, itemPath)),
|
|
@@ -619,157 +607,127 @@ function validateDataset(input, path, limits) {
|
|
|
619
607
|
export function validateProtocolDatasetContract(input, options = {}) {
|
|
620
608
|
return validateDataset(input, '$', resolveDeploymentLimits(options));
|
|
621
609
|
}
|
|
622
|
-
function
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
const result = {
|
|
626
|
-
name: identifier(value.name, `${path}.name`),
|
|
627
|
-
input: nested(() => validateProtocolSchema(value.input), `${path}.input`),
|
|
628
|
-
output: nested(() => validateProtocolSchema(value.output), `${path}.output`),
|
|
629
|
-
implementation: nested(() => validateProtocolQueryImplementation(value.implementation), `${path}.implementation`),
|
|
630
|
-
endpoint: validateEndpoint(value.endpoint, `${path}.endpoint`, limits, true),
|
|
631
|
-
tags: uniqueStrings(value.tags, `${path}.tags`, limits.maxDatasetItems, (tag, tagPath) => boundedText(tag, tagPath, limits.maxTextBytes)),
|
|
632
|
-
};
|
|
633
|
-
optionalText(value.summary, 'summary', result, path, limits);
|
|
634
|
-
optionalText(value.description, 'description', result, path, limits);
|
|
635
|
-
return freezeRecord(result);
|
|
636
|
-
}
|
|
637
|
-
function validateArtifact(input, path) {
|
|
638
|
-
const value = requireRecord(input, path);
|
|
639
|
-
exactFields(value, ['runtime', 'artifactSha256'], [], path);
|
|
640
|
-
if (value.runtime !== 'node' && value.runtime !== 'python') {
|
|
641
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.runtime`);
|
|
642
|
-
}
|
|
643
|
-
if (typeof value.artifactSha256 !== 'string' || !SHA256_PATTERN.test(value.artifactSha256)) {
|
|
644
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.artifactSha256`);
|
|
645
|
-
}
|
|
646
|
-
return freezeRecord({
|
|
647
|
-
runtime: value.runtime,
|
|
648
|
-
artifactSha256: value.artifactSha256,
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
function validateReferences(contract) {
|
|
652
|
-
const datasets = new Map(contract.datasets.map(dataset => [dataset.name, dataset]));
|
|
653
|
-
for (const [datasetIndex, dataset] of contract.datasets.entries()) {
|
|
610
|
+
function validateDatasetReferences(datasets) {
|
|
611
|
+
const names = new Set(datasets.map(dataset => dataset.name));
|
|
612
|
+
for (const [index, dataset] of datasets.entries()) {
|
|
654
613
|
if (dataset.defaults?.dimensions?.some(name => (!dataset.dimensions.some(dimension => dimension.name === name && dimension.groupable)))) {
|
|
655
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${
|
|
614
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${index}].defaults.dimensions`);
|
|
656
615
|
}
|
|
657
616
|
if (dataset.defaults?.timeGrain !== undefined && dataset.timeField === undefined) {
|
|
658
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${
|
|
617
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${index}].defaults.timeGrain`);
|
|
659
618
|
}
|
|
660
619
|
for (const [relationshipIndex, relationship] of dataset.relationships.entries()) {
|
|
661
|
-
if (!
|
|
662
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
const filters = new Set(dataset.filters.map(filter => filter.name));
|
|
666
|
-
const hasDimension = (name) => {
|
|
667
|
-
const [head, ...tail] = name.split('.');
|
|
668
|
-
if (tail.length === 0)
|
|
669
|
-
return dataset.dimensions.some(dimension => dimension.name === head);
|
|
670
|
-
const relationship = dataset.relationships.find(candidate => candidate.name === head && candidate.queryable);
|
|
671
|
-
const target = relationship ? datasets.get(relationship.target) : undefined;
|
|
672
|
-
return target?.dimensions.some(dimension => dimension.name === tail.join('.')) ?? false;
|
|
673
|
-
};
|
|
674
|
-
for (const [metricIndex, metric] of dataset.metrics.entries()) {
|
|
675
|
-
if (metric.dimensions.some(dimension => !hasDimension(dimension))
|
|
676
|
-
|| metric.filters.some(filter => !filters.has(filter))) {
|
|
677
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${datasetIndex}].metrics[${metricIndex}]`);
|
|
678
|
-
}
|
|
679
|
-
if ((metric.kind === 'grained-metric' || metric.grains.length > 0)
|
|
680
|
-
&& dataset.timeField === undefined) {
|
|
681
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${datasetIndex}].metrics[${metricIndex}].grains`);
|
|
682
|
-
}
|
|
683
|
-
// Biconditional, as for a compiled-SQL query below. An endpoint that
|
|
684
|
-
// requires a tenant over a dataset carrying no tenant field resolves one
|
|
685
|
-
// and then has no column to scope by, so the query reads every tenant
|
|
686
|
-
// while both layers believe tenancy was enforced.
|
|
687
|
-
if ((dataset.tenant.kind === 'required') !== (metric.endpoint.tenant.kind === 'required')) {
|
|
688
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${datasetIndex}].metrics[${metricIndex}].endpoint.tenant`);
|
|
620
|
+
if (!names.has(relationship.target)) {
|
|
621
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${index}].relationships[${relationshipIndex}].target`);
|
|
689
622
|
}
|
|
690
623
|
}
|
|
691
624
|
if (dataset.endpoint !== undefined
|
|
692
625
|
&& (dataset.tenant.kind === 'required') !== (dataset.endpoint.tenant.kind === 'required')) {
|
|
693
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${
|
|
626
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.datasets[${index}].endpoint.tenant`);
|
|
694
627
|
}
|
|
695
628
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (query.implementation.kind === 'semantic-plan') {
|
|
716
|
-
const dataset = datasets.get(query.implementation.query.dataset);
|
|
717
|
-
if (!dataset) {
|
|
718
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.queries[${queryIndex}].implementation.query.dataset`);
|
|
719
|
-
}
|
|
720
|
-
if (dataset.tenant.kind === 'required' && query.endpoint.tenant.kind !== 'required') {
|
|
721
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `$.queries[${queryIndex}].endpoint.tenant`);
|
|
722
|
-
}
|
|
723
|
-
}
|
|
629
|
+
}
|
|
630
|
+
function formulaReferences(expression, names) {
|
|
631
|
+
switch (expression.kind) {
|
|
632
|
+
case 'reference':
|
|
633
|
+
names.add(expression.name);
|
|
634
|
+
return;
|
|
635
|
+
case 'binary':
|
|
636
|
+
formulaReferences(expression.left, names);
|
|
637
|
+
formulaReferences(expression.right, names);
|
|
638
|
+
return;
|
|
639
|
+
case 'call':
|
|
640
|
+
expression.args.forEach(argument => formulaReferences(argument, names));
|
|
641
|
+
return;
|
|
642
|
+
default:
|
|
643
|
+
// validateFormulaGrammar has already rejected every other node.
|
|
644
|
+
return;
|
|
724
645
|
}
|
|
725
646
|
}
|
|
726
|
-
function
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
if (
|
|
732
|
-
|
|
647
|
+
function validateDatasetDerivedMeasure(input, path, limits) {
|
|
648
|
+
const value = requireRecord(input, path);
|
|
649
|
+
exactFields(value, ['kind', 'name', 'uses', 'expression'], [
|
|
650
|
+
'label', 'description', ...SEMANTIC_METADATA_FIELDS,
|
|
651
|
+
], path);
|
|
652
|
+
if (value.kind !== 'derived')
|
|
653
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.kind`);
|
|
654
|
+
const uses = requireArray(value.uses, `${path}.uses`, limits.maxDatasetItems)
|
|
655
|
+
.map((inputUse, index) => {
|
|
656
|
+
const usePath = `${path}.uses[${index}]`;
|
|
657
|
+
const use = requireRecord(inputUse, usePath);
|
|
658
|
+
exactFields(use, ['alias', 'measure'], [], usePath);
|
|
659
|
+
return freezeRecord({
|
|
660
|
+
alias: identifier(use.alias, `${usePath}.alias`),
|
|
661
|
+
measure: identifier(use.measure, `${usePath}.measure`),
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
if (uses.length === 0 || new Set(uses.map(use => use.alias)).size !== uses.length) {
|
|
665
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `${path}.uses`);
|
|
733
666
|
}
|
|
734
|
-
|
|
735
|
-
|
|
667
|
+
const expression = nested(() => validateProtocolExpression(value.expression), `${path}.expression`);
|
|
668
|
+
validateFormulaGrammar(expression, `${path}.expression`);
|
|
669
|
+
if (expression.kind === 'reference') {
|
|
670
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `${path}.expression`);
|
|
736
671
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
672
|
+
const references = new Set();
|
|
673
|
+
formulaReferences(expression, references);
|
|
674
|
+
if (references.size !== uses.length || uses.some(use => !references.has(use.alias))) {
|
|
675
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `${path}.expression`);
|
|
676
|
+
}
|
|
677
|
+
const result = {
|
|
678
|
+
kind: 'derived',
|
|
679
|
+
name: identifier(value.name, `${path}.name`),
|
|
680
|
+
uses: Object.freeze(uses),
|
|
681
|
+
expression,
|
|
682
|
+
};
|
|
683
|
+
optionalText(value.label, 'label', result, path, limits);
|
|
684
|
+
optionalText(value.description, 'description', result, path, limits);
|
|
685
|
+
validateSemanticMetadata(value, result, path, limits);
|
|
686
|
+
return freezeRecord(result);
|
|
687
|
+
}
|
|
688
|
+
function validateDeploymentDataset(input, path, limits) {
|
|
689
|
+
const value = requireRecord(input, path);
|
|
690
|
+
exactFields(value, ['name', 'source', 'tenant', 'dimensions', 'measures', 'filters', 'relationships'], [
|
|
691
|
+
'description', 'freshness', 'owner', 'defaults',
|
|
692
|
+
...SEMANTIC_METADATA_FIELDS, 'timeField', 'limits', 'endpoint',
|
|
693
|
+
], path);
|
|
694
|
+
const measures = requireArray(value.measures, `${path}.measures`, limits.maxDatasetItems)
|
|
695
|
+
.map((measure, index) => requireRecord(measure, `${path}.measures[${index}]`));
|
|
696
|
+
// Preserve original indices when validating base measures separately.
|
|
697
|
+
const baseEntries = measures.flatMap((measure, index) => (measure.kind === 'derived'
|
|
698
|
+
? [] : [{ measure, index }]));
|
|
699
|
+
const validated = validateDataset({ ...value, measures: baseEntries.map(entry => entry.measure), metrics: [] }, path, limits, baseEntries.map(entry => entry.index));
|
|
700
|
+
const derived = measures.map((measure, index) => (measure.kind === 'derived'
|
|
701
|
+
? validateDatasetDerivedMeasure(measure, `${path}.measures[${index}]`, limits)
|
|
702
|
+
: undefined));
|
|
703
|
+
const baseByName = new Map(validated.measures.map(measure => [measure.name, measure]));
|
|
704
|
+
let baseIndex = 0;
|
|
705
|
+
const ordered = measures.map((_, index) => (derived[index] ?? validated.measures[baseIndex++]));
|
|
706
|
+
if (new Set(ordered.map(measure => measure.name)).size !== measures.length) {
|
|
707
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `${path}.measures`);
|
|
708
|
+
}
|
|
709
|
+
for (const [index, item] of derived.entries()) {
|
|
710
|
+
if (!item)
|
|
711
|
+
continue;
|
|
712
|
+
for (const [useIndex, use] of item.uses.entries()) {
|
|
713
|
+
if (!baseByName.has(use.measure)) {
|
|
714
|
+
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', `${path}.measures[${index}].uses[${useIndex}].measure`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
const { metrics: _metrics, ...dataset } = validated;
|
|
719
|
+
return freezeRecord({ ...dataset, measures: Object.freeze(ordered) });
|
|
742
720
|
}
|
|
721
|
+
/** Validate the deployment contract. Unsupported fields are forbidden, even when empty. */
|
|
743
722
|
export function validateProtocolDeploymentContract(input, options = {}) {
|
|
744
723
|
const limits = resolveDeploymentLimits(options);
|
|
745
724
|
const value = requireRecord(input, '$');
|
|
746
|
-
exactFields(value, ['kind', 'version', 'datasets'
|
|
725
|
+
exactFields(value, ['kind', 'version', 'datasets'], [], '$');
|
|
747
726
|
if (value.kind !== 'hypequery-deployment')
|
|
748
727
|
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', '$.kind');
|
|
749
|
-
if (value.version !==
|
|
728
|
+
if (value.version !== 2)
|
|
750
729
|
deploymentError('HQ_DEPLOYMENT_INVALID_VERSION', '$.version');
|
|
751
|
-
const datasets = namedItems(value.datasets, '$.datasets', limits.maxDatasets, (
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
.map((artifact, index) => validateArtifact(artifact, `$.artifacts[${index}]`)));
|
|
755
|
-
if (new Set(artifacts.map(artifact => artifact.artifactSha256)).size !== artifacts.length) {
|
|
756
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_REFERENCE', '$.artifacts');
|
|
757
|
-
}
|
|
758
|
-
const result = freezeRecord({
|
|
759
|
-
kind: 'hypequery-deployment',
|
|
760
|
-
version: 1,
|
|
761
|
-
datasets,
|
|
762
|
-
queries,
|
|
763
|
-
artifacts,
|
|
764
|
-
});
|
|
765
|
-
const routes = new Set();
|
|
766
|
-
for (const [queryIndex, query] of queries.entries()) {
|
|
767
|
-
const route = `${query.endpoint.method}\0${query.endpoint.path}`;
|
|
768
|
-
if (routes.has(route)) {
|
|
769
|
-
deploymentError('HQ_DEPLOYMENT_INVALID_VALUE', `$.queries[${queryIndex}].endpoint`);
|
|
770
|
-
}
|
|
771
|
-
routes.add(route);
|
|
772
|
-
}
|
|
773
|
-
validateReferences(result);
|
|
774
|
-
return result;
|
|
730
|
+
const datasets = namedItems(value.datasets, '$.datasets', limits.maxDatasets, (item, path) => validateDeploymentDataset(item, path, limits));
|
|
731
|
+
validateDatasetReferences(datasets);
|
|
732
|
+
return freezeRecord({ kind: 'hypequery-deployment', version: 2, datasets });
|
|
775
733
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export { DEFAULT_PROTOCOL_DEPLOYMENT_RELEASE_LIMITS, PROTOCOL_DEPLOYMENT_RELEASE
|
|
|
18
18
|
export type { PreparedProtocolDeploymentReleaseEnvelope, ProtocolDeploymentReleaseEnvelope, ProtocolDeploymentReleaseErrorCode, ProtocolDeploymentReleaseLimits, ProtocolDeploymentReleaseOptions, ProtocolDeploymentReleaseTarget, } from './releases/index.js';
|
|
19
19
|
export type { PreparedProtocolDeploymentBundleManifest, ProtocolDeploymentBundleArtifact, ProtocolDeploymentBundleDeployment, ProtocolDeploymentBundleErrorCode, ProtocolDeploymentBundleFile, ProtocolDeploymentBundleLimits, ProtocolDeploymentBundleManifest, ProtocolDeploymentBundleOptions, } from './bundles/index.js';
|
|
20
20
|
export { DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS, PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN, ProtocolDeploymentError, encodeProtocolDeploymentContract, encodeProtocolDeploymentContractToString, hashProtocolDeploymentContract, prepareProtocolDeploymentContract, validateProtocolDatasetContract, validateProtocolDeploymentContract, } from './deployments/index.js';
|
|
21
|
-
export type { PreparedProtocolDeploymentContract, ProtocolAccessPolicy, ProtocolDatasetContract, ProtocolDatasetDefaults, ProtocolDatasetDimension, ProtocolDatasetFieldSource, ProtocolDatasetFieldType, ProtocolDatasetFilter, ProtocolDatasetFreshness, ProtocolDatasetLimits, ProtocolDatasetMeasure, ProtocolDatasetMetric, ProtocolDatasetRelationship, ProtocolDatasetTenantPolicy, ProtocolSemanticMetadata, ProtocolSemanticSensitivity, ProtocolDeploymentContract, ProtocolDeploymentErrorCode, ProtocolDeploymentLimits, ProtocolDeploymentOptions, ProtocolEndpointPolicy, ProtocolEndpointTenantPolicy, ProtocolMetricDerivation, ProtocolMetricInput,
|
|
21
|
+
export type { ProtocolDatasetDerivedMeasure, ProtocolDeploymentDataset, ProtocolDeploymentMeasure, PreparedProtocolDeploymentContract, ProtocolAccessPolicy, ProtocolDatasetContract, ProtocolDatasetDefaults, ProtocolDatasetDimension, ProtocolDatasetFieldSource, ProtocolDatasetFieldType, ProtocolDatasetFilter, ProtocolDatasetFreshness, ProtocolDatasetLimits, ProtocolDatasetMeasure, ProtocolDatasetMetric, ProtocolDatasetRelationship, ProtocolDatasetTenantPolicy, ProtocolSemanticMetadata, ProtocolSemanticSensitivity, ProtocolDeploymentContract, ProtocolDeploymentErrorCode, ProtocolDeploymentLimits, ProtocolDeploymentOptions, ProtocolEndpointPolicy, ProtocolEndpointTenantPolicy, ProtocolMetricDerivation, ProtocolMetricInput, } from './deployments/index.js';
|
|
22
22
|
export type { ProtocolQueryImplementation, ProtocolQueryImplementationErrorCode, ProtocolQueryImplementationLimits, ProtocolQueryImplementationOptions, ProtocolSqlDialect, ProtocolSqlExpression, ProtocolSqlParameter, ProtocolSqlParameterSource, ProtocolSqlTenantPolicy, } from './query-implementations/index.js';
|
|
23
23
|
export { PROTOCOL_SEMANTIC_FAILURE_MESSAGES } from './invocations/failure-messages.js';
|
|
24
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { ProtocolQueryImplementationError } from './errors.js';
|
|
2
2
|
export { DEFAULT_PROTOCOL_QUERY_IMPLEMENTATION_LIMITS } from './limits.js';
|
|
3
|
-
export { validateProtocolQueryImplementation,
|
|
3
|
+
export { validateProtocolQueryImplementation, } from './validate.js';
|
|
4
|
+
export { validateProtocolSqlExpression } from '../sql-expressions/validate.js';
|
|
4
5
|
export type { ProtocolQueryImplementation, ProtocolQueryImplementationErrorCode, ProtocolQueryImplementationLimits, ProtocolQueryImplementationOptions, ProtocolSqlDialect, ProtocolSqlExpression, ProtocolSqlParameter, ProtocolSqlParameterSource, ProtocolSqlTenantPolicy, } from './types.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query-implementations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,4CAA4C,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,mCAAmC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query-implementations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,4CAA4C,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,mCAAmC,GACpC,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC/E,YAAY,EACV,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,kCAAkC,EAClC,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,YAAY,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ProtocolQueryImplementationError } from './errors.js';
|
|
2
2
|
export { DEFAULT_PROTOCOL_QUERY_IMPLEMENTATION_LIMITS } from './limits.js';
|
|
3
|
-
export { validateProtocolQueryImplementation,
|
|
3
|
+
export { validateProtocolQueryImplementation, } from './validate.js';
|
|
4
|
+
export { validateProtocolSqlExpression } from '../sql-expressions/validate.js';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ProtocolQueryImplementation, ProtocolQueryImplementationOptions
|
|
2
|
-
export declare function validateProtocolSqlExpression(input: unknown, options?: ProtocolQueryImplementationOptions): ProtocolSqlExpression;
|
|
1
|
+
import type { ProtocolQueryImplementation, ProtocolQueryImplementationOptions } from './types.js';
|
|
3
2
|
export declare function validateProtocolQueryImplementation(input: unknown, options?: ProtocolQueryImplementationOptions): ProtocolQueryImplementation;
|
|
4
3
|
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/query-implementations/validate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/query-implementations/validate.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,2BAA2B,EAE3B,kCAAkC,EAInC,MAAM,YAAY,CAAC;AAqLpB,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,kCAAuC,GAC/C,2BAA2B,CAsD7B"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ProtocolExpressionError, validateProtocolSemanticQuery } from '../expressions/index.js';
|
|
2
2
|
import { ProtocolIdentifierError, parseProtocolIdentifier, parseProtocolQualifiedIdentifier, } from '../identifiers/index.js';
|
|
3
|
-
import { ProtocolSchemaError, validateProtocolSchema } from '../schemas/index.js';
|
|
4
3
|
import { queryImplementationError } from './errors.js';
|
|
5
4
|
import { resolveQueryImplementationLimits } from './limits.js';
|
|
6
5
|
const textEncoder = new TextEncoder();
|
|
@@ -157,38 +156,6 @@ function validateReadSources(input, path, limits) {
|
|
|
157
156
|
}
|
|
158
157
|
return Object.freeze(result);
|
|
159
158
|
}
|
|
160
|
-
export function validateProtocolSqlExpression(input, options = {}) {
|
|
161
|
-
const limits = resolveQueryImplementationLimits(options);
|
|
162
|
-
const value = requireRecord(input, '$');
|
|
163
|
-
exactFields(value, ['kind', 'dialect', 'sql', 'output', 'dependencies'], [], '$');
|
|
164
|
-
if (value.kind !== 'sql-expression') {
|
|
165
|
-
if (typeof value.kind !== 'string')
|
|
166
|
-
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', '$.kind');
|
|
167
|
-
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNKNOWN_KIND', '$.kind');
|
|
168
|
-
}
|
|
169
|
-
const dependencies = requireArray(value.dependencies, '$.dependencies', limits.maxCollectionItems)
|
|
170
|
-
.map((dependency, index) => identifier(dependency, `$.dependencies[${index}]`, true));
|
|
171
|
-
if (new Set(dependencies).size !== dependencies.length) {
|
|
172
|
-
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', '$.dependencies');
|
|
173
|
-
}
|
|
174
|
-
let output;
|
|
175
|
-
try {
|
|
176
|
-
output = validateProtocolSchema(value.output);
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
if (error instanceof ProtocolSchemaError) {
|
|
180
|
-
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', '$.output');
|
|
181
|
-
}
|
|
182
|
-
throw error;
|
|
183
|
-
}
|
|
184
|
-
return freezeRecord({
|
|
185
|
-
kind: 'sql-expression',
|
|
186
|
-
dialect: dialect(value.dialect, '$.dialect'),
|
|
187
|
-
sql: boundedText(value.sql, '$.sql', limits.maxExpressionBytes, true),
|
|
188
|
-
output,
|
|
189
|
-
dependencies: Object.freeze(dependencies),
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
159
|
export function validateProtocolQueryImplementation(input, options = {}) {
|
|
193
160
|
const limits = resolveQueryImplementationLimits(options);
|
|
194
161
|
const value = requireRecord(input, '$');
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProtocolQueryImplementationOptions, ProtocolSqlExpression } from '../query-implementations/types.js';
|
|
2
|
+
/** Kept under query-implementation's stable error and limit policy for v1 callers. */
|
|
3
|
+
export declare function validateProtocolSqlExpression(input: unknown, options?: ProtocolQueryImplementationOptions): ProtocolSqlExpression;
|
|
4
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/sql-expressions/validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,kCAAkC,EAClC,qBAAqB,EACtB,MAAM,mCAAmC,CAAC;AAgF3C,sFAAsF;AACtF,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,kCAAuC,GAC/C,qBAAqB,CAgCvB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** SQL-backed dataset fields and named-query implementations share this validator. */
|
|
2
|
+
import { ProtocolIdentifierError, parseProtocolQualifiedIdentifier } from '../identifiers/index.js';
|
|
3
|
+
import { ProtocolSchemaError, validateProtocolSchema } from '../schemas/index.js';
|
|
4
|
+
import { queryImplementationError } from '../query-implementations/errors.js';
|
|
5
|
+
import { resolveQueryImplementationLimits } from '../query-implementations/limits.js';
|
|
6
|
+
const textEncoder = new TextEncoder();
|
|
7
|
+
function requireRecord(input, path) {
|
|
8
|
+
if (typeof input !== 'object' || input === null || Array.isArray(input)) {
|
|
9
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', path);
|
|
10
|
+
}
|
|
11
|
+
const prototype = Object.getPrototypeOf(input);
|
|
12
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
13
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', path);
|
|
14
|
+
}
|
|
15
|
+
if (Object.getOwnPropertySymbols(input).length > 0) {
|
|
16
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', path);
|
|
17
|
+
}
|
|
18
|
+
for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(input))) {
|
|
19
|
+
if (!descriptor.enumerable || !('value' in descriptor)) {
|
|
20
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', path);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return input;
|
|
24
|
+
}
|
|
25
|
+
function requireArray(input, path, maxItems) {
|
|
26
|
+
if (!Array.isArray(input))
|
|
27
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', path);
|
|
28
|
+
if (Object.getPrototypeOf(input) !== Array.prototype || Object.getOwnPropertySymbols(input).length > 0) {
|
|
29
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', path);
|
|
30
|
+
}
|
|
31
|
+
if (input.length > maxItems)
|
|
32
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TOO_MANY_ITEMS', path);
|
|
33
|
+
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
34
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
35
|
+
const descriptor = descriptors[String(index)];
|
|
36
|
+
if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) {
|
|
37
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', `${path}[${index}]`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (Object.keys(input).length !== input.length) {
|
|
41
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNSAFE_OBJECT', path);
|
|
42
|
+
}
|
|
43
|
+
return input;
|
|
44
|
+
}
|
|
45
|
+
function exactFields(value, required, path) {
|
|
46
|
+
const allowed = new Set(required);
|
|
47
|
+
for (const key of Object.keys(value)) {
|
|
48
|
+
if (!allowed.has(key))
|
|
49
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNKNOWN_FIELD', `${path}.${key}`);
|
|
50
|
+
}
|
|
51
|
+
for (const key of required) {
|
|
52
|
+
if (!Object.hasOwn(value, key))
|
|
53
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', `${path}.${key}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function qualifiedIdentifier(value, path) {
|
|
57
|
+
try {
|
|
58
|
+
return parseProtocolQualifiedIdentifier(value);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof ProtocolIdentifierError) {
|
|
62
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_IDENTIFIER', path);
|
|
63
|
+
}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function sqlText(value, path, maxBytes) {
|
|
68
|
+
if (typeof value !== 'string')
|
|
69
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', path);
|
|
70
|
+
if (value.trim().length === 0)
|
|
71
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', path);
|
|
72
|
+
for (const character of value) {
|
|
73
|
+
const code = character.codePointAt(0);
|
|
74
|
+
if ((code <= 0x1f && code !== 0x09 && code !== 0x0a && code !== 0x0d)
|
|
75
|
+
|| code === 0x7f || (code >= 0x80 && code <= 0x9f)) {
|
|
76
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', path);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (value.length > maxBytes || textEncoder.encode(value).byteLength > maxBytes) {
|
|
80
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TOO_LARGE', path);
|
|
81
|
+
}
|
|
82
|
+
return value;
|
|
83
|
+
}
|
|
84
|
+
/** Kept under query-implementation's stable error and limit policy for v1 callers. */
|
|
85
|
+
export function validateProtocolSqlExpression(input, options = {}) {
|
|
86
|
+
const limits = resolveQueryImplementationLimits(options);
|
|
87
|
+
const value = requireRecord(input, '$');
|
|
88
|
+
exactFields(value, ['kind', 'dialect', 'sql', 'output', 'dependencies'], '$');
|
|
89
|
+
if (value.kind !== 'sql-expression') {
|
|
90
|
+
if (typeof value.kind !== 'string')
|
|
91
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_TYPE', '$.kind');
|
|
92
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_UNKNOWN_KIND', '$.kind');
|
|
93
|
+
}
|
|
94
|
+
const dependencies = requireArray(value.dependencies, '$.dependencies', limits.maxCollectionItems)
|
|
95
|
+
.map((dependency, index) => qualifiedIdentifier(dependency, `$.dependencies[${index}]`));
|
|
96
|
+
if (new Set(dependencies).size !== dependencies.length) {
|
|
97
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', '$.dependencies');
|
|
98
|
+
}
|
|
99
|
+
let output;
|
|
100
|
+
try {
|
|
101
|
+
output = validateProtocolSchema(value.output);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
if (error instanceof ProtocolSchemaError) {
|
|
105
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', '$.output');
|
|
106
|
+
}
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
if (value.dialect !== 'clickhouse') {
|
|
110
|
+
queryImplementationError('HQ_QUERY_IMPLEMENTATION_INVALID_VALUE', '$.dialect');
|
|
111
|
+
}
|
|
112
|
+
return Object.freeze(Object.assign(Object.create(null), {
|
|
113
|
+
kind: 'sql-expression',
|
|
114
|
+
dialect: 'clickhouse',
|
|
115
|
+
sql: sqlText(value.sql, '$.sql', limits.maxExpressionBytes),
|
|
116
|
+
output,
|
|
117
|
+
dependencies: Object.freeze(dependencies),
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/values/validate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/values/validate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAuWpB,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAOhB;AAYD,kFAAkF;AAClF,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,EACtC,sBAAsB,CAAC,EAAE,MAAM,GAC9B,cAAc,CAGhB;AAED,6EAA6E;AAC7E,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,QAAQ,CAAC,oBAAoB,CAAC,EACtC,sBAAsB,CAAC,EAAE,MAAM,GAC9B,cAAc,CAEhB"}
|
package/dist/values/validate.js
CHANGED
|
@@ -52,8 +52,10 @@ function validateUnicode(value, path, maxBytes) {
|
|
|
52
52
|
valueError('HQ_VALUE_CONTROL_CHARACTER', path);
|
|
53
53
|
}
|
|
54
54
|
if (code >= 0xd800 && code <= 0xdbff) {
|
|
55
|
+
// charCodeAt past the end is NaN, which fails every range comparison,
|
|
56
|
+
// so an unpaired high surrogate at the end must be rejected explicitly.
|
|
55
57
|
const low = value.charCodeAt(index + 1);
|
|
56
|
-
if (low
|
|
58
|
+
if (!(low >= 0xdc00 && low <= 0xdfff)) {
|
|
57
59
|
valueError('HQ_VALUE_INVALID_UNICODE', path);
|
|
58
60
|
}
|
|
59
61
|
index += 1;
|