@hypequery/deployment 0.8.0 → 0.9.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 +5 -31
- package/dist/activation.d.ts.map +1 -1
- package/dist/activation.js +2 -1
- package/dist/authorized-contract.d.ts +20 -49
- package/dist/authorized-contract.d.ts.map +1 -1
- package/dist/authorized-contract.js +0 -0
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +10 -36
- package/dist/control-plane-limits.js +1 -1
- package/dist/filesystem-store.d.ts.map +1 -1
- package/dist/filesystem-store.js +7 -22
- package/dist/index.d.ts +1 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -10
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +8 -5
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +5 -2
- package/dist/principal.d.ts +11 -0
- package/dist/principal.d.ts.map +1 -0
- package/dist/principal.js +1 -0
- package/dist/semantic-data-plane.d.ts +13 -17
- package/dist/semantic-data-plane.d.ts.map +1 -1
- package/dist/semantic-data-plane.js +30 -20
- package/dist/semantic-operation-validation.d.ts +2 -2
- package/dist/semantic-operation-validation.d.ts.map +1 -1
- package/dist/semantic-operation-validation.js +16 -36
- package/dist/utils/read-bounded-file.d.ts +4 -0
- package/dist/utils/read-bounded-file.d.ts.map +1 -0
- package/dist/utils/read-bounded-file.js +18 -0
- package/package.json +4 -4
- package/dist/data-plane-adapters.d.ts +0 -18
- package/dist/data-plane-adapters.d.ts.map +0 -1
- package/dist/data-plane-adapters.js +0 -304
- package/dist/data-plane-limits.d.ts +0 -5
- package/dist/data-plane-limits.d.ts.map +0 -1
- package/dist/data-plane-limits.js +0 -5
- package/dist/data-plane-runtime.d.ts +0 -13
- package/dist/data-plane-runtime.d.ts.map +0 -1
- package/dist/data-plane-runtime.js +0 -12
- package/dist/data-plane.d.ts +0 -84
- package/dist/data-plane.d.ts.map +0 -1
- package/dist/data-plane.js +0 -209
- package/dist/filesystem-host.d.ts +0 -51
- package/dist/filesystem-host.d.ts.map +0 -1
- package/dist/filesystem-host.js +0 -73
- package/dist/host.d.ts +0 -40
- package/dist/host.d.ts.map +0 -1
- package/dist/host.js +0 -183
- package/dist/node-runtime-factory.d.ts +0 -27
- package/dist/node-runtime-factory.d.ts.map +0 -1
- package/dist/node-runtime-factory.js +0 -336
- package/dist/runtime-materialization.d.ts +0 -58
- package/dist/runtime-materialization.d.ts.map +0 -1
- package/dist/runtime-materialization.js +0 -187
- package/dist/runtime-supervisor.d.ts +0 -77
- package/dist/runtime-supervisor.d.ts.map +0 -1
- package/dist/runtime-supervisor.js +0 -265
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @hypequery/deployment
|
|
2
2
|
|
|
3
|
-
Provider-neutral building blocks for receiving, verifying, activating, and
|
|
3
|
+
Provider-neutral building blocks for receiving, verifying, activating, and invoking Hypequery deployment bundles.
|
|
4
4
|
|
|
5
5
|
This package is for Cloud providers and self-hosted control planes. Application teams normally use `hypequery deploy` through `@hypequery/cli` instead.
|
|
6
6
|
|
|
@@ -11,7 +11,7 @@ Every deployment is treated as immutable content. Before storage or execution, t
|
|
|
11
11
|
- the target-bound release envelope;
|
|
12
12
|
- the closed bundle manifest;
|
|
13
13
|
- declared paths and byte limits;
|
|
14
|
-
- every file hash and
|
|
14
|
+
- every declared file hash and the canonical deployment JSON;
|
|
15
15
|
- deployment, bundle, and release identities;
|
|
16
16
|
- activation revision consistency.
|
|
17
17
|
|
|
@@ -24,10 +24,8 @@ Symbolic links, undeclared files, path traversal, missing content, and identity
|
|
|
24
24
|
- a durable reference filesystem store;
|
|
25
25
|
- compare-and-swap activation and rollback;
|
|
26
26
|
- Node and Fetch control-plane adapters;
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- named-query data-plane execution;
|
|
30
|
-
- a reference single-host composition.
|
|
27
|
+
- contract-driven semantic invocation with an injected dataset executor;
|
|
28
|
+
- authorization-aware contract projection for discovery.
|
|
31
29
|
|
|
32
30
|
## Minimal intake
|
|
33
31
|
|
|
@@ -50,33 +48,9 @@ const intake = createDeploymentIntake({
|
|
|
50
48
|
|
|
51
49
|
Authentication happens before upload bytes are consumed. The store receives a fully verified temporary bundle and must persist required bytes before returning.
|
|
52
50
|
|
|
53
|
-
## Single-host reference
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
import { createFileSystemDeploymentHost } from '@hypequery/deployment';
|
|
57
|
-
|
|
58
|
-
const service = createFileSystemDeploymentHost({
|
|
59
|
-
directory: '/var/lib/hypequery/deployments',
|
|
60
|
-
targets: [{ project: 'analytics', environment: 'production' }],
|
|
61
|
-
intake: {
|
|
62
|
-
authenticator: deploymentAuthenticator,
|
|
63
|
-
authorizer: deploymentAuthorizer,
|
|
64
|
-
},
|
|
65
|
-
controlPlane: {
|
|
66
|
-
authenticator: operatorAuthenticator,
|
|
67
|
-
authorizer: operatorAuthorizer,
|
|
68
|
-
},
|
|
69
|
-
configureDataPlane,
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
await service.start();
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Distributed providers can keep the same interfaces while replacing persistence, runtime isolation, secret resolution, routing, and observability.
|
|
76
|
-
|
|
77
51
|
## Trust boundary
|
|
78
52
|
|
|
79
|
-
|
|
53
|
+
This package validates the deployment contract and gates semantic calls, but does not execute datasets or supervise application code. Providers supply the executor, credentials, tenant resolution, routing, and runtime isolation. The filesystem store assumes its configured directory is controlled by the operator.
|
|
80
54
|
|
|
81
55
|
## Specifications
|
|
82
56
|
|
package/dist/activation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activation.d.ts","sourceRoot":"","sources":["../src/activation.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,iCAAiC,EACtC,KAAK,+BAA+B,EACrC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"activation.d.ts","sourceRoot":"","sources":["../src/activation.ts"],"names":[],"mappings":"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"}
|
package/dist/activation.js
CHANGED
|
@@ -3,6 +3,7 @@ import { constants } from 'node:fs';
|
|
|
3
3
|
import { lstat, mkdir, mkdtemp, open, readdir, rename, rm, } from 'node:fs/promises';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { prepareProtocolDeploymentReleaseEnvelope, validateProtocolDeploymentReleaseTarget, } from '@hypequery/protocol';
|
|
6
|
+
import { readBoundedFile } from './utils/read-bounded-file.js';
|
|
6
7
|
const ACTIVATION_FILE = 'activation.json';
|
|
7
8
|
const CLAIMS_DIRECTORY = 'claims';
|
|
8
9
|
// Each predecessor has one filesystem slot for its successor. Renaming a
|
|
@@ -242,7 +243,7 @@ async function readRegularFile(filePath, maximumBytes) {
|
|
|
242
243
|
if (!stat.isFile() || stat.size < 1 || stat.size > maximumBytes) {
|
|
243
244
|
throw new Error(`Stored entry is not a bounded regular file: ${filePath}`);
|
|
244
245
|
}
|
|
245
|
-
return await handle
|
|
246
|
+
return await readBoundedFile(handle, maximumBytes, 1, `Stored entry is not a bounded regular file: ${filePath}`);
|
|
246
247
|
}
|
|
247
248
|
finally {
|
|
248
249
|
await handle.close();
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* execution would refuse.
|
|
14
14
|
*/
|
|
15
15
|
import type { ProtocolAccessPolicy, ProtocolDeploymentContract, ProtocolEndpointPolicy } from '@hypequery/protocol';
|
|
16
|
-
import type { DeploymentDataPlanePrincipal } from './
|
|
16
|
+
import type { DeploymentDataPlanePrincipal } from './principal.js';
|
|
17
17
|
/**
|
|
18
18
|
* Whether a principal satisfies an access policy.
|
|
19
19
|
*
|
|
@@ -27,47 +27,18 @@ export declare function isDeploymentEndpointAuthorized(endpoint: ProtocolEndpoin
|
|
|
27
27
|
export interface AuthorizedDeploymentProjection {
|
|
28
28
|
/**
|
|
29
29
|
* A valid contract narrowed to what the principal may see, including any
|
|
30
|
-
* dataset retained only to support a join
|
|
30
|
+
* dataset retained only to support a join.
|
|
31
31
|
*/
|
|
32
32
|
readonly contract: ProtocolDeploymentContract;
|
|
33
33
|
/**
|
|
34
|
-
* Datasets
|
|
34
|
+
* Datasets addressable as a `query_dataset` target, in contract order.
|
|
35
35
|
*
|
|
36
|
-
* Wider than `queryable`: a dataset the principal cannot address may still
|
|
37
|
-
* carry a metric it can, and hiding the dataset would hide that metric.
|
|
38
36
|
* Narrower than `contract.datasets`, which also holds datasets retained only
|
|
39
|
-
* to support a join.
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* dataset and disclose its dimensions and measures to a principal with no
|
|
45
|
-
* access to it.
|
|
46
|
-
*/
|
|
47
|
-
readonly advertised: readonly string[];
|
|
48
|
-
/**
|
|
49
|
-
* Datasets addressable as a `query_dataset` target. A subset of `advertised`.
|
|
50
|
-
*
|
|
51
|
-
* The two differ because a deployment authorizes a dataset and each of its
|
|
52
|
-
* metrics through separate endpoint policies. Collapsing them would either
|
|
53
|
-
* offer a target execution refuses or withhold a metric it would run.
|
|
54
|
-
*
|
|
55
|
-
* The intended composition rehydrates the whole contract, so relationship
|
|
56
|
-
* targets still resolve, and advertises the two sets separately:
|
|
57
|
-
*
|
|
58
|
-
* ```ts
|
|
59
|
-
* const { contract, advertised, queryable } =
|
|
60
|
-
* projectAuthorizedDeploymentContract(active, principal);
|
|
61
|
-
* const registry = rehydrateProtocolDatasets(contract.datasets, { onUnsupportedMetric: 'skip' });
|
|
62
|
-
* createMCPDiscoveryExecutor({
|
|
63
|
-
* datasets: Object.fromEntries(advertised.map(name => [name, registry[name]])),
|
|
64
|
-
* queryableDatasets: queryable,
|
|
65
|
-
* });
|
|
66
|
-
* ```
|
|
67
|
-
*
|
|
68
|
-
* A joined dimension such as `orders.employee.id` still resolves through the
|
|
69
|
-
* full registry, which is correct: that join is governed by the endpoint of
|
|
70
|
-
* the dataset being queried, not by the target's.
|
|
37
|
+
* to support a join. Always read this before advertising anything: catalog
|
|
38
|
+
* projection and rehydration enumerate every dataset they are given and
|
|
39
|
+
* neither consults an endpoint, so handing them the whole contract would
|
|
40
|
+
* advertise a supporting dataset and disclose its shape to a principal with
|
|
41
|
+
* no access to it.
|
|
71
42
|
*/
|
|
72
43
|
readonly queryable: readonly string[];
|
|
73
44
|
}
|
|
@@ -76,21 +47,21 @@ export interface AuthorizedDeploymentProjection {
|
|
|
76
47
|
*
|
|
77
48
|
* A dataset is *published* when the principal may address it directly, and
|
|
78
49
|
* *supporting* when something published still needs it to stay coherent — the
|
|
79
|
-
* target of a relationship
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
50
|
+
* target of a relationship. A supporting dataset loses its endpoint and keeps
|
|
51
|
+
* only what a join reaches, so a relationship can still be traversed exactly as
|
|
52
|
+
* execution would traverse it while the dataset itself is not offered as a
|
|
53
|
+
* target.
|
|
83
54
|
*
|
|
84
55
|
* Dropping a relationship target instead would be the tempting alternative and
|
|
85
|
-
* is wrong twice: it would invalidate
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* queried, not by the target's.
|
|
56
|
+
* is wrong twice: it would invalidate the relationship that names it, and it
|
|
57
|
+
* would advertise less than the data plane permits, since a one-hop join is
|
|
58
|
+
* governed by the endpoint of the dataset being queried, not by the target's.
|
|
89
59
|
*
|
|
90
|
-
* The
|
|
91
|
-
* downstream reads an endpoint.
|
|
92
|
-
* `rehydrateProtocolDatasets` enumerate whatever
|
|
93
|
-
* unpublished dataset left in the contract they see is
|
|
60
|
+
* The contract and the target list are returned separately rather than as one
|
|
61
|
+
* contract because nothing downstream reads an endpoint.
|
|
62
|
+
* `projectAgentSafeCatalog` and `rehydrateProtocolDatasets` enumerate whatever
|
|
63
|
+
* they are handed, so an unpublished dataset left in the contract they see is
|
|
64
|
+
* an advertised one.
|
|
94
65
|
*
|
|
95
66
|
* The contract is revalidated. Callers hand it to catalog projection, schema
|
|
96
67
|
* compilation, and rehydration, all of which assume a valid contract; a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorized-contract.d.ts","sourceRoot":"","sources":["../src/authorized-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,oBAAoB,
|
|
1
|
+
{"version":3,"file":"authorized-contract.d.ts","sourceRoot":"","sources":["../src/authorized-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACV,oBAAoB,EACpB,0BAA0B,EAE1B,sBAAsB,EACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAGnE;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,4BAA4B,GAAG,IAAI,GAC7C,OAAO,CAIT;AAED,mFAAmF;AACnF,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,sBAAsB,GAAG,SAAS,EAC5C,SAAS,EAAE,4BAA4B,GAAG,IAAI,GAC7C,OAAO,CAKT;AAkCD,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAC;IAC9C;;;;;;;;;OASG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,0BAA0B,EACpC,SAAS,EAAE,4BAA4B,GAAG,IAAI,GAC7C,8BAA8B,CA2ChC"}
|
|
Binary file
|
package/dist/bundle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAQA,OAAO,
|
|
1
|
+
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAQA,OAAO,EAIL,KAAK,gCAAgC,EACrC,KAAK,0BAA0B,EAChC,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,0BAA0B,gBAAgB,CAAC;AACxD,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAE5D,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAC;CAC/C;AAkID,wBAAsB,sBAAsB,CAC1C,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,wBAAwB,CAAC,CAqEnC"}
|
package/dist/bundle.js
CHANGED
|
@@ -2,6 +2,7 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { constants, lstat, open, readdir, } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS, prepareProtocolDeploymentBundleManifest, prepareProtocolDeploymentContract, } from '@hypequery/protocol';
|
|
5
|
+
import { readBoundedFile } from './utils/read-bounded-file.js';
|
|
5
6
|
export const DEPLOYMENT_BUNDLE_MANIFEST = 'bundle.json';
|
|
6
7
|
export const DEPLOYMENT_BUNDLE_CONTRACT = 'deployment.json';
|
|
7
8
|
const utf8Decoder = new TextDecoder('utf-8', { fatal: true });
|
|
@@ -35,7 +36,7 @@ async function readBoundedRegularFile(root, relativePath, maximum, allowEmpty =
|
|
|
35
36
|
if (stat.size < (allowEmpty ? 0 : 1) || stat.size > maximum) {
|
|
36
37
|
throw new Error(`Bundle entry exceeds its byte limit: ${relativePath}`);
|
|
37
38
|
}
|
|
38
|
-
return await handle
|
|
39
|
+
return await readBoundedFile(handle, maximum, allowEmpty ? 0 : 1, `Bundle entry exceeds its byte limit: ${relativePath}`);
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
|
41
42
|
if (errorCode(error) === 'ELOOP') {
|
|
@@ -58,11 +59,11 @@ function expectedDirectories(files) {
|
|
|
58
59
|
return result;
|
|
59
60
|
}
|
|
60
61
|
async function verifyExactEntries(root, manifest) {
|
|
62
|
+
const source = manifest.source;
|
|
61
63
|
const expectedFiles = new Set([
|
|
62
64
|
DEPLOYMENT_BUNDLE_MANIFEST,
|
|
63
65
|
manifest.deployment.path,
|
|
64
|
-
...
|
|
65
|
-
...(manifest.source?.files.map(file => `${manifest.source.root}/${file.path}`) ?? []),
|
|
66
|
+
...(source?.files.map(file => `${source.root}/${file.path}`) ?? []),
|
|
66
67
|
]);
|
|
67
68
|
const expectedDirectoryPaths = expectedDirectories([...expectedFiles]);
|
|
68
69
|
const seenFiles = new Set();
|
|
@@ -116,34 +117,6 @@ function verifyFile(bytes, file) {
|
|
|
116
117
|
throw new Error(`Bundle entry SHA-256 does not match the manifest: ${file.path}`);
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
function requireClosedContractArtifactSet(contract) {
|
|
120
|
-
const referenced = new Map();
|
|
121
|
-
for (const query of contract.queries) {
|
|
122
|
-
if (query.implementation.kind === 'runtime-reference') {
|
|
123
|
-
referenced.set(query.implementation.artifactSha256, query.implementation.runtime);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (referenced.size !== contract.artifacts.length) {
|
|
127
|
-
throw new Error('Deployment contract contains missing or unreferenced runtime artifacts.');
|
|
128
|
-
}
|
|
129
|
-
for (const artifact of contract.artifacts) {
|
|
130
|
-
if (referenced.get(artifact.artifactSha256) !== artifact.runtime) {
|
|
131
|
-
throw new Error(`Deployment runtime artifact ${artifact.artifactSha256} is not referenced by a named query.`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
function verifyRuntimeReferences(contract, artifacts) {
|
|
136
|
-
requireClosedContractArtifactSet(contract);
|
|
137
|
-
const declared = new Map(contract.artifacts.map(artifact => [artifact.artifactSha256, artifact.runtime]));
|
|
138
|
-
if (declared.size !== artifacts.length) {
|
|
139
|
-
throw new Error('Bundle runtime artifacts do not match the deployment contract.');
|
|
140
|
-
}
|
|
141
|
-
for (const artifact of artifacts) {
|
|
142
|
-
if (declared.get(artifact.sha256) !== artifact.runtime) {
|
|
143
|
-
throw new Error(`Bundle artifact ${artifact.sha256} does not match a deployment runtime reference.`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
120
|
export async function verifyDeploymentBundle(bundleDirectory) {
|
|
148
121
|
const root = path.resolve(bundleDirectory);
|
|
149
122
|
const rootStat = await lstat(root);
|
|
@@ -160,6 +133,9 @@ export async function verifyDeploymentBundle(bundleDirectory) {
|
|
|
160
133
|
+ (error instanceof Error ? error.message : String(error)));
|
|
161
134
|
}
|
|
162
135
|
const preparedManifest = prepareProtocolDeploymentBundleManifest(input);
|
|
136
|
+
if (preparedManifest.manifest.artifacts.length > 0) {
|
|
137
|
+
throw new Error('A deployment bundle cannot contain runtime artifacts.');
|
|
138
|
+
}
|
|
163
139
|
const expectedManifestBytes = utf8Encoder.encode(`${preparedManifest.canonical}\n`);
|
|
164
140
|
if (!Buffer.from(manifestBytes).equals(Buffer.from(expectedManifestBytes))) {
|
|
165
141
|
throw new Error('Deployment bundle manifest must contain canonical JSON followed by one newline.');
|
|
@@ -177,13 +153,12 @@ export async function verifyDeploymentBundle(bundleDirectory) {
|
|
|
177
153
|
+ (error instanceof Error ? error.message : String(error)));
|
|
178
154
|
}
|
|
179
155
|
const preparedContract = prepareProtocolDeploymentContract(contractInput);
|
|
156
|
+
if (!Buffer.from(deploymentBytes).equals(Buffer.from(`${preparedContract.canonical}\n`))) {
|
|
157
|
+
throw new Error('Deployment JSON must contain canonical JSON followed by one newline.');
|
|
158
|
+
}
|
|
180
159
|
if (preparedContract.identity !== deployment.identity) {
|
|
181
160
|
throw new Error('Deployment identity does not match the bundle manifest.');
|
|
182
161
|
}
|
|
183
|
-
for (const artifact of preparedManifest.manifest.artifacts) {
|
|
184
|
-
const bytes = await readBoundedRegularFile(root, artifact.path, DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS.maxArtifactBytes);
|
|
185
|
-
verifyFile(bytes, artifact);
|
|
186
|
-
}
|
|
187
162
|
const source = preparedManifest.manifest.source;
|
|
188
163
|
if (source) {
|
|
189
164
|
for (const file of source.files) {
|
|
@@ -192,7 +167,6 @@ export async function verifyDeploymentBundle(bundleDirectory) {
|
|
|
192
167
|
verifyFile(bytes, { ...file, path: bundlePath });
|
|
193
168
|
}
|
|
194
169
|
}
|
|
195
|
-
verifyRuntimeReferences(preparedContract.contract, preparedManifest.manifest.artifacts);
|
|
196
170
|
return Object.freeze({
|
|
197
171
|
directory: root,
|
|
198
172
|
manifest: preparedManifest.manifest,
|
|
@@ -10,7 +10,7 @@ export function resolveDeploymentControlPlaneLimits(input = {}) {
|
|
|
10
10
|
continue;
|
|
11
11
|
if (!Number.isSafeInteger(value) || value < 1
|
|
12
12
|
|| value > DEFAULT_DEPLOYMENT_CONTROL_PLANE_LIMITS[key]) {
|
|
13
|
-
throw new RangeError(`${key} must be a positive safe integer no greater than the control-plane
|
|
13
|
+
throw new RangeError(`${key} must be a positive safe integer no greater than the control-plane safety ceiling`);
|
|
14
14
|
}
|
|
15
15
|
limits[key] = value;
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filesystem-store.d.ts","sourceRoot":"","sources":["../src/filesystem-store.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,iCAAiC,EACvC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,yBAAyB,EAE1B,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"filesystem-store.d.ts","sourceRoot":"","sources":["../src/filesystem-store.ts"],"names":[],"mappings":"AAWA,OAAO,EAEL,KAAK,iCAAiC,EACvC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AAUpB,MAAM,MAAM,kCAAkC,GAC1C,mCAAmC,GACnC,wCAAwC,GACxC,mCAAmC,GACnC,wBAAwB,CAAC;AAE7B,qBAAa,8BAA+B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,EAAE,kCAAkC,CAAC;gBAGhD,IAAI,EAAE,kCAAkC,EACxC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO;CAM7C;AAED,MAAM,WAAW,0CAA0C;IACzD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,iCAAiC,CAAC;IACpD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;CAC3C;AAED,MAAM,WAAW,mCAAmC,CAAC,SAAS,CAC5D,SAAQ,yBAAyB,CAAC,SAAS,CAAC;IAC5C,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC,CAAC;CAChF;AAkaD,wBAAgB,yCAAyC,CAAC,SAAS,GAAG,OAAO,EAC3E,OAAO,EAAE,0CAA0C,GAClD,mCAAmC,CAAC,SAAS,CAAC,CAkHhD"}
|
package/dist/filesystem-store.js
CHANGED
|
@@ -3,6 +3,7 @@ import { lstat, mkdir, mkdtemp, open, readdir, rename, rm, } from 'node:fs/promi
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { prepareProtocolDeploymentReleaseEnvelope, } from '@hypequery/protocol';
|
|
5
5
|
import { DEPLOYMENT_BUNDLE_MANIFEST, verifyDeploymentBundle, } from './bundle.js';
|
|
6
|
+
import { readBoundedFile } from './utils/read-bounded-file.js';
|
|
6
7
|
const RELEASE_FILE = 'release.json';
|
|
7
8
|
const MAX_MANIFEST_BYTES = 1024 * 1024;
|
|
8
9
|
const MAX_RELEASE_BYTES = 16 * 1024;
|
|
@@ -148,16 +149,17 @@ async function copyRegularFile(sourcePath, destinationPath, maximumBytes, expect
|
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
function bundleFilePaths(bundle) {
|
|
152
|
+
const source = bundle.manifest.source;
|
|
151
153
|
return Object.freeze([
|
|
152
154
|
{ path: DEPLOYMENT_BUNDLE_MANIFEST },
|
|
153
155
|
{
|
|
154
156
|
path: bundle.manifest.deployment.path,
|
|
155
157
|
byteLength: bundle.manifest.deployment.byteLength,
|
|
156
158
|
},
|
|
157
|
-
...
|
|
158
|
-
path:
|
|
159
|
-
byteLength:
|
|
160
|
-
})),
|
|
159
|
+
...(source?.files.map(file => ({
|
|
160
|
+
path: `${source.root}/${file.path}`,
|
|
161
|
+
byteLength: file.byteLength,
|
|
162
|
+
})) ?? []),
|
|
161
163
|
]);
|
|
162
164
|
}
|
|
163
165
|
async function syncBundleDirectories(bundleRoot, files) {
|
|
@@ -205,24 +207,7 @@ async function readRegularFile(filePath, maximumBytes) {
|
|
|
205
207
|
if (!stat.isFile() || stat.size < 1 || stat.size > maximumBytes) {
|
|
206
208
|
throw new Error(`Stored entry is not a bounded regular file: ${filePath}`);
|
|
207
209
|
}
|
|
208
|
-
|
|
209
|
-
const chunks = [];
|
|
210
|
-
let total = 0;
|
|
211
|
-
while (total <= maximumBytes) {
|
|
212
|
-
const remaining = maximumBytes + 1 - total;
|
|
213
|
-
const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.byteLength, remaining), null);
|
|
214
|
-
if (bytesRead === 0)
|
|
215
|
-
break;
|
|
216
|
-
total += bytesRead;
|
|
217
|
-
if (total > maximumBytes) {
|
|
218
|
-
throw new Error(`Stored entry is not a bounded regular file: ${filePath}`);
|
|
219
|
-
}
|
|
220
|
-
chunks.push(Buffer.from(buffer.subarray(0, bytesRead)));
|
|
221
|
-
}
|
|
222
|
-
if (total < 1) {
|
|
223
|
-
throw new Error(`Stored entry is not a bounded regular file: ${filePath}`);
|
|
224
|
-
}
|
|
225
|
-
return Buffer.concat(chunks, total);
|
|
210
|
+
return await readBoundedFile(handle, maximumBytes, 1, `Stored entry is not a bounded regular file: ${filePath}`);
|
|
226
211
|
}
|
|
227
212
|
finally {
|
|
228
213
|
await handle.close();
|
package/dist/index.d.ts
CHANGED
|
@@ -15,25 +15,8 @@ export { DEFAULT_DEPLOYMENT_CONTROL_PLANE_LIMITS, resolveDeploymentControlPlaneL
|
|
|
15
15
|
export type { DeploymentControlPlaneLimits } from './control-plane-limits.js';
|
|
16
16
|
export { DEFAULT_DEPLOYMENT_INTAKE_LIMITS, resolveDeploymentIntakeLimits, } from './limits.js';
|
|
17
17
|
export type { DeploymentIntakeLimits } from './limits.js';
|
|
18
|
-
export { createNodeWorkerDeploymentRuntimeFactory, NodeDeploymentRuntimeError, } from './node-runtime-factory.js';
|
|
19
|
-
export type { NodeDeploymentRuntimeEnvironment, NodeDeploymentRuntimeEnvironmentResolver, NodeDeploymentRuntimeErrorCode, NodeDeploymentRuntimeFactoryOptions, } from './node-runtime-factory.js';
|
|
20
|
-
export { createDeploymentRuntimeMaterializer, DeploymentRuntimeMaterializationError, } from './runtime-materialization.js';
|
|
21
|
-
export type { DeploymentRuntimeArtifactSnapshot, DeploymentRuntimeMaterializationErrorCode, DeploymentRuntimeMaterializer, DeploymentRuntimeMaterializerOptions, DeploymentRuntimeQueryBinding, DeploymentRuntimeRelease, DeploymentRuntimeReleaseReader, DeploymentRuntimeSnapshot, } from './runtime-materialization.js';
|
|
22
|
-
export { createDeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorError, } from './runtime-supervisor.js';
|
|
23
|
-
export type { DeploymentRuntimeFactory, DeploymentRuntimeGeneration, DeploymentRuntimeInstance, DeploymentRuntimeInstanceInvocation, DeploymentRuntimeInvocation, DeploymentRuntimeReconcileResult, DeploymentRuntimeStatus, DeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorErrorCode, DeploymentRuntimeSupervisorOptions, } from './runtime-supervisor.js';
|
|
24
18
|
export type { DeploymentAuthenticationInput, DeploymentAuthenticator, DeploymentAuthorizationInput, DeploymentAuthorizer, DeploymentIntake, DeploymentIntakeOptions, DeploymentIntakeRequest, DeploymentIntakeResponse, DeploymentSubmissionResponse, DeploymentSubmissionStore, VerifiedDeploymentSubmission, } from './types.js';
|
|
25
|
-
export {
|
|
26
|
-
export type { DeploymentCompiledSqlExecutionInput, DeploymentDataPlane, DeploymentDataPlaneAuthenticationInput, DeploymentDataPlaneErrorCode, DeploymentDataPlaneExecutionInput, DeploymentDataPlaneJsonRequest, DeploymentDataPlaneOptions, DeploymentDataPlanePrincipal, DeploymentDataPlaneRequest, DeploymentDataPlaneResult, DeploymentDataPlaneTenantInput, DeploymentRuntimeReferenceExecutionInput, DeploymentSemanticPlanExecutionInput, } from './data-plane.js';
|
|
27
|
-
export { DEFAULT_DEPLOYMENT_DATA_PLANE_LIMITS, resolveDeploymentDataPlaneLimits, } from './data-plane-limits.js';
|
|
28
|
-
export type { DeploymentDataPlaneLimits } from './data-plane-limits.js';
|
|
29
|
-
export { createDeploymentRuntimeSupervisorExecutor } from './data-plane-runtime.js';
|
|
30
|
-
export type { DeploymentRuntimeSupervisorExecutorOptions } from './data-plane-runtime.js';
|
|
31
|
-
export { createDeploymentDataPlaneFetchHandler, createDeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
|
|
32
|
-
export type { DeploymentDataPlaneAdapterOptions, DeploymentDataPlaneAdapterRequest, DeploymentDataPlaneFetchHandler, DeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
|
|
33
|
-
export { createDeploymentHost, DeploymentHostError, } from './host.js';
|
|
34
|
-
export { createFileSystemDeploymentHost } from './filesystem-host.js';
|
|
35
|
-
export type { FileSystemDeploymentHost, FileSystemDeploymentHostOptions, } from './filesystem-host.js';
|
|
36
|
-
export type { DeploymentHost, DeploymentHostDataPlaneConfiguration, DeploymentHostDataPlaneInput, DeploymentHostErrorCode, DeploymentHostOptions, } from './host.js';
|
|
19
|
+
export type { DeploymentDataPlanePrincipal } from './principal.js';
|
|
37
20
|
export { createDeploymentSemanticDataPlane, DeploymentSemanticInvocationError, toProtocolSemanticInvocationFailure, } from './semantic-data-plane.js';
|
|
38
21
|
export type { DeploymentSemanticAuthenticationInput, DeploymentSemanticBudget, DeploymentSemanticDataPlane, DeploymentSemanticDataPlaneOptions, DeploymentSemanticExecutionInput, DeploymentSemanticInvocationRequest, DeploymentSemanticTenantInput, } from './semantic-data-plane.js';
|
|
39
22
|
export { validateSemanticOperation } from './semantic-operation-validation.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,4CAA4C,EAC5C,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,gCAAgC,EAChC,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,6CAA6C,GAC9C,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,yCAAyC,EACzC,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,kCAAkC,EAClC,mCAAmC,EACnC,0CAA0C,EAC1C,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,wCAAwC,EACxC,gCAAgC,EAChC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,uCAAuC,EACvC,mCAAmC,GACpC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4CAA4C,EAC5C,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,6BAA6B,EAC7B,+BAA+B,EAC/B,gCAAgC,EAChC,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,6CAA6C,GAC9C,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,qBAAqB,GACtB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EACL,yCAAyC,EACzC,8BAA8B,GAC/B,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,kCAAkC,EAClC,mCAAmC,EACnC,0CAA0C,EAC1C,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,wCAAwC,EACxC,uCAAuC,GACxC,MAAM,6BAA6B,CAAC;AACrC,YAAY,EACV,kCAAkC,EAClC,iCAAiC,GAClC,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,4BAA4B,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,wCAAwC,EACxC,gCAAgC,EAChC,+BAA+B,EAC/B,6BAA6B,EAC7B,6BAA6B,EAC7B,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,uCAAuC,EACvC,mCAAmC,GACpC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,YAAY,EACV,6BAA6B,EAC7B,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,gBAAgB,EAChB,uBAAuB,EACvB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAEnE,OAAO,EACL,iCAAiC,EACjC,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,qCAAqC,EACrC,wBAAwB,EACxB,2BAA2B,EAC3B,kCAAkC,EAClC,gCAAgC,EAChC,mCAAmC,EACnC,6BAA6B,GAC9B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,YAAY,EACV,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,oCAAoC,CAAC;AAI5C,OAAO,EACL,8BAA8B,EAC9B,mCAAmC,EACnC,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,16 +7,6 @@ export { createDeploymentControlPlaneFetchHandler, createDeploymentControlPlaneN
|
|
|
7
7
|
export { createDeploymentControlPlane, } from './control-plane.js';
|
|
8
8
|
export { DEFAULT_DEPLOYMENT_CONTROL_PLANE_LIMITS, resolveDeploymentControlPlaneLimits, } from './control-plane-limits.js';
|
|
9
9
|
export { DEFAULT_DEPLOYMENT_INTAKE_LIMITS, resolveDeploymentIntakeLimits, } from './limits.js';
|
|
10
|
-
export { createNodeWorkerDeploymentRuntimeFactory, NodeDeploymentRuntimeError, } from './node-runtime-factory.js';
|
|
11
|
-
export { createDeploymentRuntimeMaterializer, DeploymentRuntimeMaterializationError, } from './runtime-materialization.js';
|
|
12
|
-
export { createDeploymentRuntimeSupervisor, DeploymentRuntimeSupervisorError, } from './runtime-supervisor.js';
|
|
13
|
-
export { createDeploymentDataPlane, DeploymentDataPlaneError, } from './data-plane.js';
|
|
14
|
-
export { DEFAULT_DEPLOYMENT_DATA_PLANE_LIMITS, resolveDeploymentDataPlaneLimits, } from './data-plane-limits.js';
|
|
15
|
-
export { createDeploymentRuntimeSupervisorExecutor } from './data-plane-runtime.js';
|
|
16
|
-
export { createDeploymentDataPlaneFetchHandler, createDeploymentDataPlaneNodeHandler, } from './data-plane-adapters.js';
|
|
17
|
-
export { createDeploymentHost, DeploymentHostError, } from './host.js';
|
|
18
|
-
export { createFileSystemDeploymentHost } from './filesystem-host.js';
|
|
19
|
-
// Semantic invocation beside named-query execution (decision 0002).
|
|
20
10
|
export { createDeploymentSemanticDataPlane, DeploymentSemanticInvocationError, toProtocolSemanticInvocationFailure, } from './semantic-data-plane.js';
|
|
21
11
|
export { validateSemanticOperation } from './semantic-operation-validation.js';
|
|
22
12
|
// What one principal may see of a contract, for a gateway listing targets
|
package/dist/intake.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../src/intake.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EAIxB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../src/intake.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EACV,gBAAgB,EAChB,uBAAuB,EAIxB,MAAM,YAAY,CAAC;AAwSpB,wBAAgB,sBAAsB,CAAC,SAAS,EAC9C,OAAO,EAAE,uBAAuB,CAAC,SAAS,CAAC,GAC1C,gBAAgB,CAiIlB"}
|
package/dist/intake.js
CHANGED
|
@@ -85,10 +85,10 @@ function decodeJson(bytes, description) {
|
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
function requireReconstructablePaths(manifest) {
|
|
88
|
+
const source = manifest.manifest.source;
|
|
88
89
|
const files = [
|
|
89
90
|
manifest.manifest.deployment.path,
|
|
90
|
-
...
|
|
91
|
-
...(manifest.manifest.source?.files.map(file => `${manifest.manifest.source.root}/${file.path}`) ?? []),
|
|
91
|
+
...(source?.files.map(file => `${source.root}/${file.path}`) ?? []),
|
|
92
92
|
];
|
|
93
93
|
const fileSet = new Set(files);
|
|
94
94
|
if (fileSet.has(DEPLOYMENT_BUNDLE_MANIFEST)) {
|
|
@@ -149,6 +149,9 @@ async function readManifest(reader, maximum) {
|
|
|
149
149
|
throw error;
|
|
150
150
|
throw badRequest('The deployment bundle manifest is invalid.', error);
|
|
151
151
|
}
|
|
152
|
+
if (prepared.manifest.artifacts.length > 0) {
|
|
153
|
+
throw badRequest('A deployment bundle cannot contain runtime artifacts.');
|
|
154
|
+
}
|
|
152
155
|
const canonical = Buffer.from(`${prepared.canonical}\n`);
|
|
153
156
|
if (!part.bytes.equals(canonical)) {
|
|
154
157
|
throw badRequest('The deployment bundle manifest must use canonical JSON followed by one newline.');
|
|
@@ -282,12 +285,12 @@ export function createDeploymentIntake(options) {
|
|
|
282
285
|
const bundleRoot = path.join(temporaryRoot, 'bundle');
|
|
283
286
|
await mkdir(bundleRoot);
|
|
284
287
|
await writeFile(path.join(bundleRoot, DEPLOYMENT_BUNDLE_MANIFEST), manifest.bytes, { flag: 'wx' });
|
|
288
|
+
const source = manifest.prepared.manifest.source;
|
|
285
289
|
const files = [
|
|
286
290
|
manifest.prepared.manifest.deployment,
|
|
287
|
-
...
|
|
288
|
-
...(manifest.prepared.manifest.source?.files.map(file => ({
|
|
291
|
+
...(source?.files.map(file => ({
|
|
289
292
|
...file,
|
|
290
|
-
path: `${
|
|
293
|
+
path: `${source.root}/${file.path}`,
|
|
291
294
|
})) ?? []),
|
|
292
295
|
];
|
|
293
296
|
for (let index = 0; index < files.length; index += 1) {
|
package/dist/limits.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED,eAAO,MAAM,gCAAgC,EAAE,QAAQ,CAAC,sBAAsB,CAQ5E,CAAC;AAEH,wBAAgB,6BAA6B,CAC3C,KAAK,GAAE,OAAO,CAAC,sBAAsB,CAAM,GAC1C,QAAQ,CAAC,sBAAsB,CAAC,CAelC"}
|
package/dist/limits.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS } from '@hypequery/protocol';
|
|
2
2
|
export const DEFAULT_DEPLOYMENT_INTAKE_LIMITS = Object.freeze({
|
|
3
|
-
|
|
3
|
+
// Source and deployment bytes, plus the manifest and headers for up to 1,000 files.
|
|
4
|
+
maxRequestBytes: DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS.maxDeploymentBytes
|
|
5
|
+
+ DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS.maxSourceBytes
|
|
6
|
+
+ (10 * 1024 * 1024),
|
|
4
7
|
maxReleaseBytes: 16 * 1024,
|
|
5
8
|
maxManifestBytes: 1024 * 1024,
|
|
6
9
|
maxPartHeaderBytes: 8 * 1024,
|
|
@@ -14,7 +17,7 @@ export function resolveDeploymentIntakeLimits(input = {}) {
|
|
|
14
17
|
if (!Number.isSafeInteger(value) || value < 1
|
|
15
18
|
|| value > DEFAULT_DEPLOYMENT_INTAKE_LIMITS[key]) {
|
|
16
19
|
throw new RangeError(`${key} must be a positive safe integer no greater than `
|
|
17
|
-
+ `${DEFAULT_DEPLOYMENT_INTAKE_LIMITS[key]} (the deployment intake
|
|
20
|
+
+ `${DEFAULT_DEPLOYMENT_INTAKE_LIMITS[key]} (the deployment intake safety ceiling)`);
|
|
18
21
|
}
|
|
19
22
|
result[key] = value;
|
|
20
23
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who a deployed call is made as, after authentication and before any
|
|
3
|
+
* authorization decision. Carried by every data-plane surface.
|
|
4
|
+
*/
|
|
5
|
+
export interface DeploymentDataPlanePrincipal {
|
|
6
|
+
readonly subject?: string;
|
|
7
|
+
readonly roles?: readonly string[];
|
|
8
|
+
readonly scopes?: readonly string[];
|
|
9
|
+
readonly claims?: Readonly<Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=principal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.d.ts","sourceRoot":"","sources":["../src/principal.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,20 +1,19 @@
|
|
|
1
|
-
export { DeploymentSemanticInvocationError, toProtocolSemanticInvocationFailure } from './semantic-invocation-errors.js';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
2
|
+
* Dataset invocation against an activated deployment.
|
|
4
3
|
*
|
|
5
|
-
* Decision 0002 requires a dataset
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Decision 0002 requires a dataset call to run a fixed enforcement sequence:
|
|
5
|
+
* select the active generation, resolve the target from its validated
|
|
6
|
+
* contract, authenticate, enforce roles and scopes, resolve tenant, apply the
|
|
7
|
+
* most restrictive budget, validate input, execute, then validate and bound
|
|
8
|
+
* the output.
|
|
10
9
|
*
|
|
11
10
|
* Execution itself is injected. This module decides whether a call is allowed
|
|
12
|
-
* and what it is allowed to ask for
|
|
13
|
-
* answers it.
|
|
11
|
+
* and what it is allowed to ask for.
|
|
14
12
|
*/
|
|
15
|
-
import type {
|
|
16
|
-
import type { DeploymentDataPlanePrincipal } from './
|
|
13
|
+
import type { ProtocolDeploymentContract, ProtocolDeploymentDataset, ProtocolSemanticInvocation, ProtocolSemanticInvocationResult, ProtocolSemanticQuery } from '@hypequery/protocol';
|
|
14
|
+
import type { DeploymentDataPlanePrincipal } from './principal.js';
|
|
17
15
|
import { type SemanticOperationLimits } from './semantic-operation-validation.js';
|
|
16
|
+
export { DeploymentSemanticInvocationError, toProtocolSemanticInvocationFailure } from './semantic-invocation-errors.js';
|
|
18
17
|
/** The ceilings that survived after every source was applied. */
|
|
19
18
|
export interface DeploymentSemanticBudget {
|
|
20
19
|
readonly maxRows: number;
|
|
@@ -24,19 +23,16 @@ export interface DeploymentSemanticBudget {
|
|
|
24
23
|
export interface DeploymentSemanticAuthenticationInput {
|
|
25
24
|
readonly credentials: unknown;
|
|
26
25
|
readonly invocation: ProtocolSemanticInvocation;
|
|
27
|
-
readonly dataset:
|
|
28
|
-
readonly metric?: ProtocolDatasetMetric;
|
|
26
|
+
readonly dataset: ProtocolDeploymentDataset;
|
|
29
27
|
}
|
|
30
28
|
export interface DeploymentSemanticTenantInput {
|
|
31
29
|
readonly principal: DeploymentDataPlanePrincipal | null;
|
|
32
30
|
readonly invocation: ProtocolSemanticInvocation;
|
|
33
|
-
readonly dataset:
|
|
34
|
-
readonly metric?: ProtocolDatasetMetric;
|
|
31
|
+
readonly dataset: ProtocolDeploymentDataset;
|
|
35
32
|
}
|
|
36
33
|
export interface DeploymentSemanticExecutionInput {
|
|
37
34
|
readonly deployment: ProtocolDeploymentContract;
|
|
38
|
-
readonly dataset:
|
|
39
|
-
readonly metric?: ProtocolDatasetMetric;
|
|
35
|
+
readonly dataset: ProtocolDeploymentDataset;
|
|
40
36
|
readonly operation: ProtocolSemanticQuery;
|
|
41
37
|
readonly principal: DeploymentDataPlanePrincipal | null;
|
|
42
38
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-data-plane.d.ts","sourceRoot":"","sources":["../src/semantic-data-plane.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"semantic-data-plane.d.ts","sourceRoot":"","sources":["../src/semantic-data-plane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EAEzB,0BAA0B,EAC1B,gCAAgC,EAChC,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAO7B,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,oCAAoC,CAAC;AAM5C,OAAO,EAAE,iCAAiC,EAAE,mCAAmC,EAAE,MAAM,iCAAiC,CAAC;AAEzH,iEAAiE;AACjE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,0BAA0B,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;CAC7C;AAED,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,0BAA0B,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;CAC7C;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,UAAU,EAAE,0BAA0B,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IAC5C,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACxD;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,wBAAwB,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,mCAAmC;IAClD,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,UAAU,EAAE,0BAA0B,CAAC;IAChD,uDAAuD;IACvD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,CACtB,KAAK,EAAE,qCAAqC,KACzC,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CAAC;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,6BAA6B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpF,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAChF,0EAA0E;IAC1E,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG;QACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;KACpC,CAAC;CACH;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,CAAC,OAAO,EAAE,mCAAmC,GAAG,OAAO,CAAC,gCAAgC,CAAC,CAAC;CACjG;AAYD,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,kCAAkC,GAC1C,2BAA2B,CA8O7B"}
|