@hypequery/protocol 0.3.0 → 0.4.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 +10 -4
- package/dist/bundles/codec.d.ts +13 -0
- package/dist/bundles/codec.d.ts.map +1 -0
- package/dist/bundles/codec.js +25 -0
- package/dist/bundles/errors.d.ts +8 -0
- package/dist/bundles/errors.d.ts.map +1 -0
- package/dist/bundles/errors.js +13 -0
- package/dist/bundles/index.d.ts +7 -0
- package/dist/bundles/index.d.ts.map +1 -0
- package/dist/bundles/index.js +4 -0
- package/dist/bundles/limits.d.ts +4 -0
- package/dist/bundles/limits.d.ts.map +1 -0
- package/dist/bundles/limits.js +22 -0
- package/dist/bundles/types.d.ts +35 -0
- package/dist/bundles/types.d.ts.map +1 -0
- package/dist/bundles/types.js +1 -0
- package/dist/bundles/validate.d.ts +3 -0
- package/dist/bundles/validate.d.ts.map +1 -0
- package/dist/bundles/validate.js +155 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,10 +6,10 @@ Hypequery artifacts.
|
|
|
6
6
|
## Current status
|
|
7
7
|
|
|
8
8
|
This package contains proposed version 1 tagged values, identifiers,
|
|
9
|
-
expressions, query schemas and implementations,
|
|
10
|
-
|
|
11
|
-
and conformance fixtures are reviewed; these
|
|
12
|
-
stable Cloud protocol.
|
|
9
|
+
expressions, query schemas and implementations, Dataset deployment contracts,
|
|
10
|
+
and deployment bundle manifests. The API remains pre-stable while the
|
|
11
|
+
language-neutral specifications and conformance fixtures are reviewed; these
|
|
12
|
+
drafts do not yet establish a stable Cloud protocol.
|
|
13
13
|
|
|
14
14
|
The normative source is
|
|
15
15
|
[`specs/security-protocol`](../../specs/security-protocol/README.md).
|
|
@@ -77,6 +77,12 @@ the protocol package remains deterministic and framework-independent.
|
|
|
77
77
|
Validated envelopes can be encoded as canonical RFC 8785 bytes and identified
|
|
78
78
|
with the deployment-v1 domain-separated SHA-256 digest.
|
|
79
79
|
|
|
80
|
+
The proposed deployment-bundle surface validates the portable manifest that
|
|
81
|
+
binds a deployment identity to exact deployment and runtime artifact files. It
|
|
82
|
+
provides canonical encoding and a separate bundle-v1 identity. Filesystem-safe
|
|
83
|
+
writing and byte verification remain in the CLI because this package performs
|
|
84
|
+
no I/O.
|
|
85
|
+
|
|
80
86
|
## Runtime compatibility
|
|
81
87
|
|
|
82
88
|
This package is ESM-only. Consumers must load it with `import`; CommonJS
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ProtocolDeploymentBundleManifest, ProtocolDeploymentBundleOptions } from './types.js';
|
|
2
|
+
export declare const PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN = "hypequery:deployment-bundle:v1\0";
|
|
3
|
+
export interface PreparedProtocolDeploymentBundleManifest {
|
|
4
|
+
readonly manifest: ProtocolDeploymentBundleManifest;
|
|
5
|
+
readonly canonical: string;
|
|
6
|
+
readonly bytes: Uint8Array;
|
|
7
|
+
readonly identity: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function prepareProtocolDeploymentBundleManifest(input: unknown, options?: ProtocolDeploymentBundleOptions): PreparedProtocolDeploymentBundleManifest;
|
|
10
|
+
export declare function encodeProtocolDeploymentBundleManifest(input: unknown, options?: ProtocolDeploymentBundleOptions): Uint8Array;
|
|
11
|
+
export declare function encodeProtocolDeploymentBundleManifestToString(input: unknown, options?: ProtocolDeploymentBundleOptions): string;
|
|
12
|
+
export declare function hashProtocolDeploymentBundleManifest(input: unknown, options?: ProtocolDeploymentBundleOptions): string;
|
|
13
|
+
//# sourceMappingURL=codec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/bundles/codec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gCAAgC,EAChC,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAKpB,eAAO,MAAM,0CAA0C,qCAAqC,CAAC;AAE7F,MAAM,WAAW,wCAAwC;IACvD,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,uCAAuC,CACrD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,+BAAoC,GAC5C,wCAAwC,CAS1C;AAED,wBAAgB,sCAAsC,CACpD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,+BAAoC,GAC5C,UAAU,CAEZ;AAED,wBAAgB,8CAA8C,CAC5D,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAER;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,+BAAoC,GAC5C,MAAM,CAER"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { sha256 } from '@noble/hashes/sha2';
|
|
2
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
3
|
+
import { serializeJcs } from '../values/jcs.js';
|
|
4
|
+
import { validateProtocolDeploymentBundleManifest } from './validate.js';
|
|
5
|
+
const textEncoder = new TextEncoder();
|
|
6
|
+
export const PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN = 'hypequery:deployment-bundle:v1\0';
|
|
7
|
+
export function prepareProtocolDeploymentBundleManifest(input, options = {}) {
|
|
8
|
+
const manifest = validateProtocolDeploymentBundleManifest(input, options);
|
|
9
|
+
const canonical = serializeJcs(manifest);
|
|
10
|
+
const bytes = textEncoder.encode(canonical);
|
|
11
|
+
const identity = bytesToHex(sha256.create()
|
|
12
|
+
.update(textEncoder.encode(PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN))
|
|
13
|
+
.update(bytes)
|
|
14
|
+
.digest());
|
|
15
|
+
return Object.freeze({ manifest, canonical, bytes, identity });
|
|
16
|
+
}
|
|
17
|
+
export function encodeProtocolDeploymentBundleManifest(input, options = {}) {
|
|
18
|
+
return prepareProtocolDeploymentBundleManifest(input, options).bytes;
|
|
19
|
+
}
|
|
20
|
+
export function encodeProtocolDeploymentBundleManifestToString(input, options = {}) {
|
|
21
|
+
return prepareProtocolDeploymentBundleManifest(input, options).canonical;
|
|
22
|
+
}
|
|
23
|
+
export function hashProtocolDeploymentBundleManifest(input, options = {}) {
|
|
24
|
+
return prepareProtocolDeploymentBundleManifest(input, options).identity;
|
|
25
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProtocolDeploymentBundleErrorCode } from './types.js';
|
|
2
|
+
export declare class ProtocolDeploymentBundleError extends TypeError {
|
|
3
|
+
readonly code: ProtocolDeploymentBundleErrorCode;
|
|
4
|
+
readonly path: string;
|
|
5
|
+
constructor(code: ProtocolDeploymentBundleErrorCode, path?: string);
|
|
6
|
+
}
|
|
7
|
+
export declare function bundleError(code: ProtocolDeploymentBundleErrorCode, path?: string): never;
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/bundles/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAEpE,qBAAa,6BAA8B,SAAQ,SAAS;IAC1D,QAAQ,CAAC,IAAI,EAAE,iCAAiC,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,IAAI,EAAE,iCAAiC,EAAE,IAAI,SAAM;CAMhE;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,iCAAiC,EACvC,IAAI,SAAM,GACT,KAAK,CAEP"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export class ProtocolDeploymentBundleError extends TypeError {
|
|
2
|
+
code;
|
|
3
|
+
path;
|
|
4
|
+
constructor(code, path = '$') {
|
|
5
|
+
super(`${code} at ${path}`);
|
|
6
|
+
this.name = 'ProtocolDeploymentBundleError';
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.path = path;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export function bundleError(code, path = '$') {
|
|
12
|
+
throw new ProtocolDeploymentBundleError(code, path);
|
|
13
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ProtocolDeploymentBundleError } from './errors.js';
|
|
2
|
+
export { PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN, encodeProtocolDeploymentBundleManifest, encodeProtocolDeploymentBundleManifestToString, hashProtocolDeploymentBundleManifest, prepareProtocolDeploymentBundleManifest, } from './codec.js';
|
|
3
|
+
export type { PreparedProtocolDeploymentBundleManifest } from './codec.js';
|
|
4
|
+
export { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS } from './limits.js';
|
|
5
|
+
export { validateProtocolDeploymentBundleManifest } from './validate.js';
|
|
6
|
+
export type { ProtocolDeploymentBundleArtifact, ProtocolDeploymentBundleDeployment, ProtocolDeploymentBundleErrorCode, ProtocolDeploymentBundleFile, ProtocolDeploymentBundleLimits, ProtocolDeploymentBundleManifest, ProtocolDeploymentBundleOptions, } from './types.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bundles/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,0CAA0C,EAC1C,sCAAsC,EACtC,8CAA8C,EAC9C,oCAAoC,EACpC,uCAAuC,GACxC,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,wCAAwC,EAAE,MAAM,YAAY,CAAC;AAC3E,OAAO,EAAE,yCAAyC,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,wCAAwC,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EACV,gCAAgC,EAChC,kCAAkC,EAClC,iCAAiC,EACjC,4BAA4B,EAC5B,8BAA8B,EAC9B,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ProtocolDeploymentBundleError } from './errors.js';
|
|
2
|
+
export { PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN, encodeProtocolDeploymentBundleManifest, encodeProtocolDeploymentBundleManifestToString, hashProtocolDeploymentBundleManifest, prepareProtocolDeploymentBundleManifest, } from './codec.js';
|
|
3
|
+
export { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS } from './limits.js';
|
|
4
|
+
export { validateProtocolDeploymentBundleManifest } from './validate.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProtocolDeploymentBundleLimits, ProtocolDeploymentBundleOptions } from './types.js';
|
|
2
|
+
export declare const DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS: Readonly<ProtocolDeploymentBundleLimits>;
|
|
3
|
+
export declare function resolveDeploymentBundleLimits(options?: ProtocolDeploymentBundleOptions): Readonly<ProtocolDeploymentBundleLimits>;
|
|
4
|
+
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/bundles/limits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,8BAA8B,EAC9B,+BAA+B,EAChC,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,yCAAyC,EACtD,QAAQ,CAAC,8BAA8B,CAMrC,CAAC;AAEH,wBAAgB,6BAA6B,CAC3C,OAAO,GAAE,+BAAoC,GAC5C,QAAQ,CAAC,8BAA8B,CAAC,CAe1C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS = Object.freeze({
|
|
2
|
+
maxArtifacts: 100,
|
|
3
|
+
maxPathBytes: 1_024,
|
|
4
|
+
maxDeploymentBytes: 16 * 1_024 * 1_024,
|
|
5
|
+
maxArtifactBytes: 128 * 1_024 * 1_024,
|
|
6
|
+
maxTotalBytes: 256 * 1_024 * 1_024,
|
|
7
|
+
});
|
|
8
|
+
export function resolveDeploymentBundleLimits(options = {}) {
|
|
9
|
+
const result = { ...DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS };
|
|
10
|
+
for (const key of Object.keys(result)) {
|
|
11
|
+
const value = options.limits?.[key];
|
|
12
|
+
if (value === undefined)
|
|
13
|
+
continue;
|
|
14
|
+
const maximum = DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS[key];
|
|
15
|
+
if (!Number.isSafeInteger(value) || value < 1 || value > maximum) {
|
|
16
|
+
throw new RangeError(`${key} must be a positive safe integer no greater than ${maximum} `
|
|
17
|
+
+ '(the deployment bundle v1 maximum)');
|
|
18
|
+
}
|
|
19
|
+
result[key] = value;
|
|
20
|
+
}
|
|
21
|
+
return Object.freeze(result);
|
|
22
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export interface ProtocolDeploymentBundleFile {
|
|
2
|
+
readonly path: string;
|
|
3
|
+
readonly sha256: string;
|
|
4
|
+
readonly byteLength: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ProtocolDeploymentBundleDeployment extends ProtocolDeploymentBundleFile {
|
|
7
|
+
readonly identity: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ProtocolDeploymentBundleArtifact extends ProtocolDeploymentBundleFile {
|
|
10
|
+
readonly runtime: 'node' | 'python';
|
|
11
|
+
}
|
|
12
|
+
export interface ProtocolDeploymentBundleManifest {
|
|
13
|
+
readonly kind: 'hypequery-deployment-bundle';
|
|
14
|
+
readonly version: 1;
|
|
15
|
+
readonly deployment: ProtocolDeploymentBundleDeployment;
|
|
16
|
+
readonly artifacts: readonly ProtocolDeploymentBundleArtifact[];
|
|
17
|
+
}
|
|
18
|
+
export interface ProtocolDeploymentBundleLimits {
|
|
19
|
+
readonly maxArtifacts: number;
|
|
20
|
+
readonly maxPathBytes: number;
|
|
21
|
+
readonly maxDeploymentBytes: number;
|
|
22
|
+
readonly maxArtifactBytes: number;
|
|
23
|
+
readonly maxTotalBytes: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validation budgets for a deployment bundle manifest.
|
|
27
|
+
*
|
|
28
|
+
* Values may tighten the fixed bundle-v1 safety ceilings but cannot raise
|
|
29
|
+
* them. These are parser budgets, not deployment capacity settings.
|
|
30
|
+
*/
|
|
31
|
+
export interface ProtocolDeploymentBundleOptions {
|
|
32
|
+
readonly limits?: Partial<ProtocolDeploymentBundleLimits>;
|
|
33
|
+
}
|
|
34
|
+
export type ProtocolDeploymentBundleErrorCode = 'HQ_BUNDLE_TYPE' | 'HQ_BUNDLE_UNKNOWN_FIELD' | 'HQ_BUNDLE_INVALID_VERSION' | 'HQ_BUNDLE_INVALID_VALUE' | 'HQ_BUNDLE_INVALID_PATH' | 'HQ_BUNDLE_INVALID_REFERENCE' | 'HQ_BUNDLE_TOO_MANY_ITEMS' | 'HQ_BUNDLE_TOO_LARGE' | 'HQ_BUNDLE_UNSAFE_OBJECT';
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/bundles/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kCAAmC,SAAQ,4BAA4B;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gCAAiC,SAAQ,4BAA4B;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;CACrC;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,IAAI,EAAE,6BAA6B,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,kCAAkC,CAAC;IACxD,QAAQ,CAAC,SAAS,EAAE,SAAS,gCAAgC,EAAE,CAAC;CACjE;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC3D;AAED,MAAM,MAAM,iCAAiC,GACzC,gBAAgB,GAChB,yBAAyB,GACzB,2BAA2B,GAC3B,yBAAyB,GACzB,wBAAwB,GACxB,6BAA6B,GAC7B,0BAA0B,GAC1B,qBAAqB,GACrB,yBAAyB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProtocolDeploymentBundleManifest, ProtocolDeploymentBundleOptions } from './types.js';
|
|
2
|
+
export declare function validateProtocolDeploymentBundleManifest(input: unknown, options?: ProtocolDeploymentBundleOptions): ProtocolDeploymentBundleManifest;
|
|
3
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/bundles/validate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,gCAAgC,EAChC,+BAA+B,EAChC,MAAM,YAAY,CAAC;AA4HpB,wBAAgB,wCAAwC,CACtD,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,+BAAoC,GAC5C,gCAAgC,CAwClC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { bundleError } from './errors.js';
|
|
2
|
+
import { resolveDeploymentBundleLimits } from './limits.js';
|
|
3
|
+
const textEncoder = new TextEncoder();
|
|
4
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/;
|
|
5
|
+
const PATH_SEGMENT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
6
|
+
const WINDOWS_RESERVED_NAME = /^(?:CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(?:\.|$)/i;
|
|
7
|
+
function requireRecord(input, path) {
|
|
8
|
+
if (typeof input !== 'object' || input === null || Array.isArray(input)) {
|
|
9
|
+
bundleError('HQ_BUNDLE_TYPE', path);
|
|
10
|
+
}
|
|
11
|
+
const prototype = Object.getPrototypeOf(input);
|
|
12
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
13
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', path);
|
|
14
|
+
}
|
|
15
|
+
if (Object.getOwnPropertySymbols(input).length > 0) {
|
|
16
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', path);
|
|
17
|
+
}
|
|
18
|
+
for (const descriptor of Object.values(Object.getOwnPropertyDescriptors(input))) {
|
|
19
|
+
if (!descriptor.enumerable || !('value' in descriptor)) {
|
|
20
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', path);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return input;
|
|
24
|
+
}
|
|
25
|
+
function requireArray(input, path, maxItems) {
|
|
26
|
+
if (!Array.isArray(input))
|
|
27
|
+
bundleError('HQ_BUNDLE_TYPE', path);
|
|
28
|
+
if (Object.getPrototypeOf(input) !== Array.prototype
|
|
29
|
+
|| Object.getOwnPropertySymbols(input).length > 0) {
|
|
30
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', path);
|
|
31
|
+
}
|
|
32
|
+
if (input.length > maxItems)
|
|
33
|
+
bundleError('HQ_BUNDLE_TOO_MANY_ITEMS', path);
|
|
34
|
+
const descriptors = Object.getOwnPropertyDescriptors(input);
|
|
35
|
+
for (let index = 0; index < input.length; index += 1) {
|
|
36
|
+
const descriptor = descriptors[String(index)];
|
|
37
|
+
if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) {
|
|
38
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', `${path}[${index}]`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (Object.keys(input).length !== input.length
|
|
42
|
+
|| Object.getOwnPropertyNames(input).length !== input.length + 1) {
|
|
43
|
+
bundleError('HQ_BUNDLE_UNSAFE_OBJECT', path);
|
|
44
|
+
}
|
|
45
|
+
return input;
|
|
46
|
+
}
|
|
47
|
+
function exactFields(value, required, path) {
|
|
48
|
+
const allowed = new Set(required);
|
|
49
|
+
for (const key of Object.keys(value)) {
|
|
50
|
+
if (!allowed.has(key))
|
|
51
|
+
bundleError('HQ_BUNDLE_UNKNOWN_FIELD', `${path}.${key}`);
|
|
52
|
+
}
|
|
53
|
+
for (const key of required) {
|
|
54
|
+
if (!Object.hasOwn(value, key))
|
|
55
|
+
bundleError('HQ_BUNDLE_TYPE', `${path}.${key}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function freezeRecord(entries) {
|
|
59
|
+
return Object.freeze(Object.assign(Object.create(null), entries));
|
|
60
|
+
}
|
|
61
|
+
function digest(value, path) {
|
|
62
|
+
if (typeof value !== 'string')
|
|
63
|
+
bundleError('HQ_BUNDLE_TYPE', path);
|
|
64
|
+
if (!SHA256_PATTERN.test(value))
|
|
65
|
+
bundleError('HQ_BUNDLE_INVALID_VALUE', path);
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
function byteLength(value, path, maximum) {
|
|
69
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
70
|
+
bundleError('HQ_BUNDLE_INVALID_VALUE', path);
|
|
71
|
+
}
|
|
72
|
+
if (value > maximum)
|
|
73
|
+
bundleError('HQ_BUNDLE_TOO_LARGE', path);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
function relativePath(value, path, maxBytes) {
|
|
77
|
+
if (typeof value !== 'string')
|
|
78
|
+
bundleError('HQ_BUNDLE_TYPE', path);
|
|
79
|
+
if (value.length > maxBytes || textEncoder.encode(value).byteLength > maxBytes) {
|
|
80
|
+
bundleError('HQ_BUNDLE_TOO_LARGE', path);
|
|
81
|
+
}
|
|
82
|
+
const segments = value.split('/');
|
|
83
|
+
if (segments.some(segment => !PATH_SEGMENT_PATTERN.test(segment)
|
|
84
|
+
|| segment.endsWith('.')
|
|
85
|
+
|| WINDOWS_RESERVED_NAME.test(segment))) {
|
|
86
|
+
bundleError('HQ_BUNDLE_INVALID_PATH', path);
|
|
87
|
+
}
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
function validateDeployment(input, path, limits) {
|
|
91
|
+
const value = requireRecord(input, path);
|
|
92
|
+
exactFields(value, ['path', 'identity', 'sha256', 'byteLength'], path);
|
|
93
|
+
return freezeRecord({
|
|
94
|
+
path: relativePath(value.path, `${path}.path`, limits.maxPathBytes),
|
|
95
|
+
identity: digest(value.identity, `${path}.identity`),
|
|
96
|
+
sha256: digest(value.sha256, `${path}.sha256`),
|
|
97
|
+
byteLength: byteLength(value.byteLength, `${path}.byteLength`, limits.maxDeploymentBytes),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function validateArtifact(input, path, limits) {
|
|
101
|
+
const value = requireRecord(input, path);
|
|
102
|
+
exactFields(value, ['runtime', 'path', 'sha256', 'byteLength'], path);
|
|
103
|
+
if (value.runtime !== 'node' && value.runtime !== 'python') {
|
|
104
|
+
if (typeof value.runtime !== 'string')
|
|
105
|
+
bundleError('HQ_BUNDLE_TYPE', `${path}.runtime`);
|
|
106
|
+
bundleError('HQ_BUNDLE_INVALID_VALUE', `${path}.runtime`);
|
|
107
|
+
}
|
|
108
|
+
return freezeRecord({
|
|
109
|
+
runtime: value.runtime,
|
|
110
|
+
path: relativePath(value.path, `${path}.path`, limits.maxPathBytes),
|
|
111
|
+
sha256: digest(value.sha256, `${path}.sha256`),
|
|
112
|
+
byteLength: byteLength(value.byteLength, `${path}.byteLength`, limits.maxArtifactBytes),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export function validateProtocolDeploymentBundleManifest(input, options = {}) {
|
|
116
|
+
const limits = resolveDeploymentBundleLimits(options);
|
|
117
|
+
const value = requireRecord(input, '$');
|
|
118
|
+
exactFields(value, ['kind', 'version', 'deployment', 'artifacts'], '$');
|
|
119
|
+
if (value.kind !== 'hypequery-deployment-bundle') {
|
|
120
|
+
if (typeof value.kind !== 'string')
|
|
121
|
+
bundleError('HQ_BUNDLE_TYPE', '$.kind');
|
|
122
|
+
bundleError('HQ_BUNDLE_INVALID_VALUE', '$.kind');
|
|
123
|
+
}
|
|
124
|
+
if (value.version !== 1) {
|
|
125
|
+
if (typeof value.version !== 'number')
|
|
126
|
+
bundleError('HQ_BUNDLE_TYPE', '$.version');
|
|
127
|
+
bundleError('HQ_BUNDLE_INVALID_VERSION', '$.version');
|
|
128
|
+
}
|
|
129
|
+
const deployment = validateDeployment(value.deployment, '$.deployment', limits);
|
|
130
|
+
const artifacts = Object.freeze(requireArray(value.artifacts, '$.artifacts', limits.maxArtifacts)
|
|
131
|
+
.map((artifact, index) => validateArtifact(artifact, `$.artifacts[${index}]`, limits)));
|
|
132
|
+
const paths = [deployment.path, ...artifacts.map(artifact => artifact.path)];
|
|
133
|
+
if (new Set(paths).size !== paths.length
|
|
134
|
+
|| new Set(paths.map(bundlePath => bundlePath.toLowerCase())).size !== paths.length) {
|
|
135
|
+
bundleError('HQ_BUNDLE_INVALID_REFERENCE', '$.artifacts');
|
|
136
|
+
}
|
|
137
|
+
if (new Set(artifacts.map(artifact => artifact.sha256)).size !== artifacts.length) {
|
|
138
|
+
bundleError('HQ_BUNDLE_INVALID_REFERENCE', '$.artifacts');
|
|
139
|
+
}
|
|
140
|
+
const sortedPaths = artifacts.map(artifact => artifact.path).sort();
|
|
141
|
+
if (artifacts.some((artifact, index) => artifact.path !== sortedPaths[index])) {
|
|
142
|
+
bundleError('HQ_BUNDLE_INVALID_VALUE', '$.artifacts');
|
|
143
|
+
}
|
|
144
|
+
const totalBytes = deployment.byteLength
|
|
145
|
+
+ artifacts.reduce((total, artifact) => total + artifact.byteLength, 0);
|
|
146
|
+
if (!Number.isSafeInteger(totalBytes) || totalBytes > limits.maxTotalBytes) {
|
|
147
|
+
bundleError('HQ_BUNDLE_TOO_LARGE', '$');
|
|
148
|
+
}
|
|
149
|
+
return freezeRecord({
|
|
150
|
+
kind: 'hypequery-deployment-bundle',
|
|
151
|
+
version: 1,
|
|
152
|
+
deployment,
|
|
153
|
+
artifacts,
|
|
154
|
+
});
|
|
155
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export type { ProtocolSchema, ProtocolSchemaErrorCode, ProtocolSchemaLimits, Pro
|
|
|
7
7
|
export type { ProtocolAggregation, ProtocolBinaryOperator, ProtocolComparisonOperator, ProtocolDatasetQuery, ProtocolExpression, ProtocolExpressionErrorCode, ProtocolExpressionLimits, ProtocolExpressionOptions, ProtocolFunctionName, ProtocolMetricQuery, ProtocolOrderBy, ProtocolSemanticQuery, ProtocolTimeGrain, } from './expressions/index.js';
|
|
8
8
|
export type { ProtocolIdentifier, ProtocolIdentifierErrorCode, ProtocolQualifiedIdentifier, } from './identifiers/index.js';
|
|
9
9
|
export { DEFAULT_PROTOCOL_QUERY_IMPLEMENTATION_LIMITS, ProtocolQueryImplementationError, validateProtocolQueryImplementation, validateProtocolSqlExpression, } from './query-implementations/index.js';
|
|
10
|
+
export { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS, PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN, ProtocolDeploymentBundleError, encodeProtocolDeploymentBundleManifest, encodeProtocolDeploymentBundleManifestToString, hashProtocolDeploymentBundleManifest, prepareProtocolDeploymentBundleManifest, validateProtocolDeploymentBundleManifest, } from './bundles/index.js';
|
|
11
|
+
export type { PreparedProtocolDeploymentBundleManifest, ProtocolDeploymentBundleArtifact, ProtocolDeploymentBundleDeployment, ProtocolDeploymentBundleErrorCode, ProtocolDeploymentBundleFile, ProtocolDeploymentBundleLimits, ProtocolDeploymentBundleManifest, ProtocolDeploymentBundleOptions, } from './bundles/index.js';
|
|
10
12
|
export { DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS, PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN, ProtocolDeploymentError, encodeProtocolDeploymentContract, encodeProtocolDeploymentContractToString, hashProtocolDeploymentContract, prepareProtocolDeploymentContract, validateProtocolDatasetContract, validateProtocolDeploymentContract, } from './deployments/index.js';
|
|
11
13
|
export type { PreparedProtocolDeploymentContract, ProtocolAccessPolicy, ProtocolDatasetContract, ProtocolDatasetDimension, ProtocolDatasetFieldSource, ProtocolDatasetFieldType, ProtocolDatasetFilter, ProtocolDatasetLimits, ProtocolDatasetMeasure, ProtocolDatasetMetric, ProtocolDatasetRelationship, ProtocolDatasetTenantPolicy, ProtocolDeploymentContract, ProtocolDeploymentErrorCode, ProtocolDeploymentLimits, ProtocolDeploymentOptions, ProtocolEndpointPolicy, ProtocolEndpointTenantPolicy, ProtocolNamedQueryContract, ProtocolRuntimeArtifact, } from './deployments/index.js';
|
|
12
14
|
export type { ProtocolQueryImplementation, ProtocolQueryImplementationErrorCode, ProtocolQueryImplementationLimits, ProtocolQueryImplementationOptions, ProtocolSqlDialect, ProtocolSqlExpression, ProtocolSqlParameter, ProtocolSqlParameterSource, ProtocolSqlTenantPolicy, } from './query-implementations/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,6BAA6B,EAC7B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,kCAAkC,EAClC,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,8BAA8B,EAC9B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4CAA4C,EAC5C,gCAAgC,EAChC,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,kCAAkC,EAClC,mCAAmC,EACnC,uBAAuB,EACvB,gCAAgC,EAChC,wCAAwC,EACxC,8BAA8B,EAC9B,iCAAiC,EACjC,+BAA+B,EAC/B,kCAAkC,GACnC,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,kCAAkC,EAClC,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,kCAAkC,EAClC,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,4BAA4B,EAC5B,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,6BAA6B,EAC7B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,kCAAkC,EAClC,uBAAuB,EACvB,0BAA0B,EAC1B,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,8BAA8B,EAC9B,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,kBAAkB,EAClB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4CAA4C,EAC5C,gCAAgC,EAChC,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACL,yCAAyC,EACzC,0CAA0C,EAC1C,6BAA6B,EAC7B,sCAAsC,EACtC,8CAA8C,EAC9C,oCAAoC,EACpC,uCAAuC,EACvC,wCAAwC,GACzC,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EACV,wCAAwC,EACxC,gCAAgC,EAChC,kCAAkC,EAClC,iCAAiC,EACjC,4BAA4B,EAC5B,8BAA8B,EAC9B,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,kCAAkC,EAClC,mCAAmC,EACnC,uBAAuB,EACvB,gCAAgC,EAChC,wCAAwC,EACxC,8BAA8B,EAC9B,iCAAiC,EACjC,+BAA+B,EAC/B,kCAAkC,GACnC,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,kCAAkC,EAClC,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,yBAAyB,EACzB,sBAAsB,EACtB,4BAA4B,EAC5B,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EACV,2BAA2B,EAC3B,oCAAoC,EACpC,iCAAiC,EACjC,kCAAkC,EAClC,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,0BAA0B,EAC1B,uBAAuB,GACxB,MAAM,kCAAkC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,5 @@ export { PROTOCOL_IDENTIFIER_LIMITS, ProtocolIdentifierError, isProtocolIdentifi
|
|
|
3
3
|
export { DEFAULT_PROTOCOL_EXPRESSION_LIMITS, ProtocolExpressionError, validateProtocolExpression, validateProtocolSemanticQuery, } from './expressions/index.js';
|
|
4
4
|
export { DEFAULT_PROTOCOL_SCHEMA_LIMITS, ProtocolSchemaError, validateProtocolSchema, } from './schemas/index.js';
|
|
5
5
|
export { DEFAULT_PROTOCOL_QUERY_IMPLEMENTATION_LIMITS, ProtocolQueryImplementationError, validateProtocolQueryImplementation, validateProtocolSqlExpression, } from './query-implementations/index.js';
|
|
6
|
+
export { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS, PROTOCOL_DEPLOYMENT_BUNDLE_IDENTITY_DOMAIN, ProtocolDeploymentBundleError, encodeProtocolDeploymentBundleManifest, encodeProtocolDeploymentBundleManifestToString, hashProtocolDeploymentBundleManifest, prepareProtocolDeploymentBundleManifest, validateProtocolDeploymentBundleManifest, } from './bundles/index.js';
|
|
6
7
|
export { DEFAULT_PROTOCOL_DEPLOYMENT_LIMITS, PROTOCOL_DEPLOYMENT_IDENTITY_DOMAIN, ProtocolDeploymentError, encodeProtocolDeploymentContract, encodeProtocolDeploymentContractToString, hashProtocolDeploymentContract, prepareProtocolDeploymentContract, validateProtocolDatasetContract, validateProtocolDeploymentContract, } from './deployments/index.js';
|