@substrat-run/control-plane-api 0.163.0 → 0.164.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/dist/api.d.ts +18 -2
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +121 -18
- package/dist/api.js.map +1 -1
- package/dist/connection-binding-options.d.ts.map +1 -1
- package/dist/connection-binding-options.js +5 -1
- package/dist/connection-binding-options.js.map +1 -1
- package/dist/connection-relay.d.ts +26 -2
- package/dist/connection-relay.d.ts.map +1 -1
- package/dist/connection-relay.js +17 -4
- package/dist/connection-relay.js.map +1 -1
- package/dist/deploy.d.ts +1 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +1 -1
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/platform-drain.d.ts +6 -0
- package/dist/platform-drain.d.ts.map +1 -1
- package/dist/platform-drain.js +9 -6
- package/dist/platform-drain.js.map +1 -1
- package/dist/platform-entry.generated.d.ts +1 -1
- package/dist/platform-entry.generated.d.ts.map +1 -1
- package/dist/platform-entry.generated.js +2 -2
- package/dist/platform-entry.generated.js.map +1 -1
- package/dist/vertical-connectors.d.ts +102 -0
- package/dist/vertical-connectors.d.ts.map +1 -0
- package/dist/vertical-connectors.js +428 -0
- package/dist/vertical-connectors.js.map +1 -0
- package/package.json +8 -8
package/dist/api.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ConnectionScopeBinding, ConnectionScopeBindingInput } from '@substrat-run/control-plane-client';
|
|
2
2
|
import { Hono } from 'hono';
|
|
3
3
|
import { type ConnectionCertificate, z, type ScopeStoreNeed, type StoreDriverRegistration } from '@substrat-run/contracts';
|
|
4
|
-
import type { Connection, ConnectionActivity, ConnectionActivitySource, ConnectionCredential, ConnectionProbe, PlatformActorId } from '@substrat-run/contracts';
|
|
4
|
+
import type { Connection, ConnectionActivity, ConnectionActivitySource, ConnectionCredential, ConnectionProbe, PlatformActorId, ScopeId, TenantId } from '@substrat-run/contracts';
|
|
5
5
|
import type { CrossVerticalOptions, HostAdmin, OpsFailureInput, ScopeHost } from '@substrat-run/kernel';
|
|
6
6
|
import type { PlatformActorAuth, BuilderAuth, Principal, TenantServiceAuth } from './auth.js';
|
|
7
7
|
import { type VerticalClient } from './vertical-client.js';
|
|
@@ -9,7 +9,7 @@ import { type CopyJobs } from './copy-job.js';
|
|
|
9
9
|
import type { PlatformScopeStores } from './platform-scope-stores.js';
|
|
10
10
|
import type { ScopeStoreEnsurerOptions, StoreCanaryTarget } from './store-script.js';
|
|
11
11
|
import { type CanaryCall, type StoreReleaseBytes } from './store-releases.js';
|
|
12
|
-
import { type ConnectionCandidatePrepare } from './connection-relay.js';
|
|
12
|
+
import { type ConnectionCandidatePrepare, type VerticalConnectorDeclarationOf } from './connection-relay.js';
|
|
13
13
|
import type { DeployVerticalFn, FetchVerticalAssetFn, FetchVerticalModulesFn } from './deploy.js';
|
|
14
14
|
import type { PatchScriptBindingsFn } from './wfp.js';
|
|
15
15
|
import { type ObservabilityReader } from './observability.js';
|
|
@@ -349,6 +349,22 @@ export interface ControlPlaneApiOptions {
|
|
|
349
349
|
* verify a Fortnox key yet" is a true statement; "your Fortnox key is fine" is not.
|
|
350
350
|
*/
|
|
351
351
|
connectionInspectors?: Record<string, ConnectionInspector>;
|
|
352
|
+
/**
|
|
353
|
+
* The inspector for a vertical-defined provider (`<namespace>.<name>`, vertical-connectors.md
|
|
354
|
+
* §6.4), which `connectionInspectors` never names: built per (tenant, vertical), since its code
|
|
355
|
+
* runs in that vertical's deployment. Asked only for a dotted provider the record lacks. Absent,
|
|
356
|
+
* such a provider answers as an unregistered one does.
|
|
357
|
+
*/
|
|
358
|
+
verticalConnectorInspector?: (provider: string, context: {
|
|
359
|
+
tenantId: TenantId;
|
|
360
|
+
vertical: string;
|
|
361
|
+
scopeId: ScopeId | null;
|
|
362
|
+
}) => ConnectionInspector | undefined;
|
|
363
|
+
/**
|
|
364
|
+
* A vertical-defined provider's serving declaration, which the tenant connection route grants
|
|
365
|
+
* from (`VerticalConnectorDeclarationOf`). Absent, that route refuses a dotted provider.
|
|
366
|
+
*/
|
|
367
|
+
verticalConnectorDeclaration?: VerticalConnectorDeclarationOf;
|
|
352
368
|
/**
|
|
353
369
|
* Where this platform's compute actually runs — the coordinates a staff surface needs
|
|
354
370
|
* to hand an operator a link INTO the provider's own console (the right script, the
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AAE9G,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAsBL,KAAK,qBAAqB,EAqF1B,CAAC,EAeD,KAAK,cAAc,EAEnB,KAAK,uBAAuB,
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -2,8 +2,9 @@ import { PREVIEW_CONNECTIONS_REFUSAL } from './connection-relay.js';
|
|
|
2
2
|
import { connectionBindingOptions } from './connection-binding-options.js';
|
|
3
3
|
import { resolveObservabilityWindow } from './observability-window.js';
|
|
4
4
|
import { Hono } from 'hono';
|
|
5
|
-
import { permissionKey, parseHostname, withLabel, RESERVED_LABEL_SEPARATOR, adminAction, lakeEventsInput, ownerTransferInput, memberInviteInput, memberRoleInput, ASSET_PART_PREFIX, assetHash, STORE_DRIVERS, STORE_RELEASE_MAX_BYTES, channelName, connectLinkId, connectionActivity, connectionActivitySource, connectionCredential, connectionCertificate, connectionFilter, connectionHealthState, connectionProvider, connectorDispatchKind, PROVISION_SIBLING_KIND, ARCHIVE_SCOPE_KIND, PROVISION_TENANT_KIND, SET_ENTITLEMENTS_KIND, MODEL_USAGE_KIND, SWEEP_RUNS_KIND, toConnectionHealthEntry, CONNECTION_EXPIRY_WARNING_DAYS, CONNECTION_STALE_DAYS, connectionProbe, createTenantInput, entitlementGrantInput, hostname as hostnameSchema, hostnameRegion, hostnameStatus, identityLink, errorCode, issueStatus, issueStatusInput, FINDINGS_LIMIT_DEFAULT, FINDINGS_LIMIT_MAX, findingCursorOf, findingKind, findingRuleInput, findingStatus, findingStatusInput, listPageQuery, matchesOutboundHost, pageOf, platformRequestFilter, principalId as principalIdSchema, impersonationStamp, promotionAcknowledgement, bindAcknowledgement, rebindAcknowledgement, provisionableJurisdiction, publishVersionInput, queryScopeInput, readScopeTableInput, entityHistoryInput, eventFacetInput, eventCauseInput, eventEffectsInput, invocationEventsInput, deadLettersInput, lifecycleFlowInput, operationSeriesCount, operationSeriesInput, delegatedReadParams, createOrgInput, roleKey as roleKeySchema, peerSwitch, verticalSlug, scopeText, systemSwitch, DEFAULT_DENIAL_LIMIT, DENIAL_LIMIT_MAX, denialGroupBy, registerVerticalInput, platformScriptCollision, platformScriptRefusal, PLATFORM_SCRIPT_NAMES, serviceDimensions, sweepRunKind, sweepRunOutcome, scopeDump, dataSubjectId as dataSubjectIdSchema, scopeId as scopeIdSchema, scopeStatus, requestRollupReading, meterDaysReading, verticalOwnersReading, utcDay, storageShape, surfaceName, tenantId as tenantIdSchema, tenantStatus, versionOrigin, z, PROBLEM_CONTENT_TYPE, toProblem, validationIssuesFrom, redrainEventsInput, importCursorMove, importCursorAcknowledgementMissing, REDRAIN_BATCH, migrationsOnTop, substratError, errorCodeOf, capabilityFilterQuery, capabilityId as capabilityIdSchema, PLATFORM_FEATURES_HEADER, PLATFORM_FEATURE_SCOPE_SWEEPER, SOCIAL_RELAY_VERTICALS, } from '@substrat-run/contracts';
|
|
5
|
+
import { permissionKey, parseHostname, withLabel, RESERVED_LABEL_SEPARATOR, adminAction, lakeEventsInput, ownerTransferInput, memberInviteInput, memberRoleInput, ASSET_PART_PREFIX, assetHash, STORE_DRIVERS, STORE_RELEASE_MAX_BYTES, channelName, connectLinkId, connectionActivity, connectionActivitySource, connectionCredential, connectionCertificate, connectionFilter, connectionHealthState, connectionProvider, connectorDispatchKind, PROVISION_SIBLING_KIND, ARCHIVE_SCOPE_KIND, PROVISION_TENANT_KIND, SET_ENTITLEMENTS_KIND, MODEL_USAGE_KIND, SWEEP_RUNS_KIND, toConnectionHealthEntry, CONNECTION_EXPIRY_WARNING_DAYS, CONNECTION_STALE_DAYS, connectionProbe, createTenantInput, entitlementGrantInput, hostname as hostnameSchema, hostnameRegion, hostnameStatus, identityLink, errorCode, issueStatus, issueStatusInput, FINDINGS_LIMIT_DEFAULT, FINDINGS_LIMIT_MAX, findingCursorOf, findingKind, findingRuleInput, findingStatus, findingStatusInput, listPageQuery, matchesOutboundHost, pageOf, platformRequestFilter, principalId as principalIdSchema, impersonationStamp, promotionAcknowledgement, bindAcknowledgement, rebindAcknowledgement, provisionableJurisdiction, publishVersionInput, queryScopeInput, readScopeTableInput, entityHistoryInput, eventFacetInput, eventCauseInput, eventEffectsInput, invocationEventsInput, deadLettersInput, lifecycleFlowInput, operationSeriesCount, operationSeriesInput, delegatedReadParams, createOrgInput, roleKey as roleKeySchema, peerSwitch, verticalSlug, scopeText, systemSwitch, DEFAULT_DENIAL_LIMIT, DENIAL_LIMIT_MAX, denialGroupBy, registerVerticalInput, platformScriptCollision, platformScriptRefusal, PLATFORM_SCRIPT_NAMES, serviceDimensions, sweepRunKind, sweepRunOutcome, scopeDump, dataSubjectId as dataSubjectIdSchema, scopeId as scopeIdSchema, scopeStatus, requestRollupReading, meterDaysReading, verticalOwnersReading, utcDay, storageShape, surfaceName, tenantId as tenantIdSchema, tenantStatus, versionOrigin, z, PROBLEM_CONTENT_TYPE, toProblem, validationIssuesFrom, redrainEventsInput, importCursorMove, importCursorAcknowledgementMissing, REDRAIN_BATCH, migrationsOnTop, substratError, errorCodeOf, capabilityFilterQuery, capabilityId as capabilityIdSchema, PLATFORM_FEATURES_HEADER, PLATFORM_FEATURE_SCOPE_SWEEPER, SOCIAL_RELAY_VERTICALS, isVerticalConnectorProvider, } from '@substrat-run/contracts';
|
|
6
6
|
import { upstreamHandleIn, upstreamReferenceOf, withUpstreamReference } from '@substrat-run/contracts';
|
|
7
|
+
import { ENGINE_ENTITLEMENT_KEYS, bareSlug, declarableEntitlementKey, entitlementNamespaceRefusal, grantableEntitlements } from '@substrat-run/contracts';
|
|
7
8
|
import { SCOPE_COPY_LEASE_MS, copyRestoreFence, publishedMigrationDigest, replayStoreErasures } from '@substrat-run/kernel';
|
|
8
9
|
import { attributeFailure } from './failure-attribution.js';
|
|
9
10
|
import { auditedChange, withAuditedOutcomes } from './audited-change.js';
|
|
@@ -28,7 +29,7 @@ import { NON_PROBLEM_REFUSAL, coded, mapError, relayed } from './errors.js';
|
|
|
28
29
|
import { maskDump, maskRecords } from './mask.js';
|
|
29
30
|
import { createPseudonymizer } from './pseudonymize.js';
|
|
30
31
|
import { openDump, sealDump } from './seal.js';
|
|
31
|
-
import { assertSandboxContract, verticalUploadBindings, migrationsDigestBindings, deployManifest, storedDeployManifest, pushedOwnerGrantProblems, pushedModuleRegistryProblems, pushedPermissionRegistry, deploymentRefFor, stableDeploymentRefFor, nextMigrationTag, upstreamStatusOf, } from './deploy.js';
|
|
32
|
+
import { assertSandboxContract, verticalUploadBindings, migrationsDigestBindings, deployManifest, storedDeployManifest, pushedOwnerGrantProblems, pushedConnectorProblems, pushedModuleRegistryProblems, pushedPermissionRegistry, deploymentRefFor, stableDeploymentRefFor, nextMigrationTag, upstreamStatusOf, } from './deploy.js';
|
|
32
33
|
/**
|
|
33
34
|
* Answer with a problem document (#113 phase 4).
|
|
34
35
|
*
|
|
@@ -113,6 +114,18 @@ class ExportBreakRefused extends ControlPlaneError {
|
|
|
113
114
|
this.breaks = breaks;
|
|
114
115
|
}
|
|
115
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* #2577: a serve whose upload carried a DO-class migration, refused its record because another serve
|
|
119
|
+
* changed the serving row's class set or tag during the upload. The runtime's migration tag is now
|
|
120
|
+
* past the record's, so a re-serve diffed from the record names an `old_tag` the runtime refuses:
|
|
121
|
+
* promoting again cannot land, and the record needs repair.
|
|
122
|
+
*/
|
|
123
|
+
class ServeRecordBehindScript extends ControlPlaneError {
|
|
124
|
+
constructor(slug) {
|
|
125
|
+
super(409, `the serving record of '${slug}' changed while this serve's upload added a Durable Object class, so the ` +
|
|
126
|
+
"record's migration tag is behind the serving script's (#2577)");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
116
129
|
/**
|
|
117
130
|
* A carry whose source store kept changing between its export and its bind (#1722, Codex #2008
|
|
118
131
|
* r12): every re-carry from a fresh export found the source changed again before it could bind.
|
|
@@ -2161,7 +2174,11 @@ export function createControlPlaneApi(options) {
|
|
|
2161
2174
|
return refuse(c, 'validation_failed', 'body tenantId disagrees with the route tenant');
|
|
2162
2175
|
}
|
|
2163
2176
|
try {
|
|
2164
|
-
return c.json(await relayConnectionUpsert(c.var.host, c.get('actor'), { ...body, tenantId }, {
|
|
2177
|
+
return c.json(await relayConnectionUpsert(c.var.host, c.get('actor'), { ...body, tenantId }, {
|
|
2178
|
+
probeCandidate,
|
|
2179
|
+
prepareCandidate,
|
|
2180
|
+
...(options.verticalConnectorDeclaration ? { declarationOf: options.verticalConnectorDeclaration } : {}),
|
|
2181
|
+
}));
|
|
2165
2182
|
}
|
|
2166
2183
|
catch (err) {
|
|
2167
2184
|
if (err instanceof ConnectionRelayError && err.status < 500) {
|
|
@@ -2271,12 +2288,20 @@ export function createControlPlaneApi(options) {
|
|
|
2271
2288
|
* exactly like an absent one — and revoked rows are excluded: a withdrawn credential
|
|
2272
2289
|
* has no secret left to probe with, so "revoked" is a 404 for these reads too.
|
|
2273
2290
|
*/
|
|
2291
|
+
/**
|
|
2292
|
+
* The inspector for `provider`: the record's entry, else, for a vertical-defined provider, the one
|
|
2293
|
+
* built for the vertical the connection belongs to (vertical-connectors.md §6.4).
|
|
2294
|
+
*/
|
|
2295
|
+
const inspectorFor = (provider, context) => options.connectionInspectors?.[provider] ??
|
|
2296
|
+
(isVerticalConnectorProvider(provider) ? options.verticalConnectorInspector?.(provider, context) : undefined);
|
|
2297
|
+
/** {@link inspectorFor} for a connection row, which names its own tenant and vertical. */
|
|
2298
|
+
const inspectorOf = (row) => inspectorFor(row.provider, { tenantId: row.tenantId, vertical: row.vertical, scopeId: null });
|
|
2274
2299
|
/**
|
|
2275
2300
|
* The connect-time gate (#605), as the relay consumes it: ask the provider about a
|
|
2276
2301
|
* candidate credential, or answer `undefined` when this platform has no probe for it —
|
|
2277
2302
|
* in which case the upsert behaves exactly as it always did, storing unverified.
|
|
2278
2303
|
*/
|
|
2279
|
-
const probeCandidate = async (provider, secret) =>
|
|
2304
|
+
const probeCandidate = async (provider, secret, context) => inspectorFor(provider, context)?.probeCandidate?.(secret);
|
|
2280
2305
|
/** #2100: the provider's own half of a credential, made before the probe sees it. */
|
|
2281
2306
|
const prepareCandidate = (provider) => options.connectionInspectors?.[provider]?.prepareCandidate;
|
|
2282
2307
|
const inspectableConnection = async (c) => {
|
|
@@ -2292,7 +2317,7 @@ export function createControlPlaneApi(options) {
|
|
|
2292
2317
|
const row = await inspectableConnection(c);
|
|
2293
2318
|
if (!row)
|
|
2294
2319
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2295
|
-
const read =
|
|
2320
|
+
const read = inspectorOf(row)?.bindings;
|
|
2296
2321
|
if (!read)
|
|
2297
2322
|
return refuseStatus(c, 501, `no scope binding registered for provider '${row.provider}'`);
|
|
2298
2323
|
const bindings = await read(c.var.host, row);
|
|
@@ -2313,7 +2338,7 @@ export function createControlPlaneApi(options) {
|
|
|
2313
2338
|
const row = await inspectableConnection(c);
|
|
2314
2339
|
if (!row)
|
|
2315
2340
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2316
|
-
const bind =
|
|
2341
|
+
const bind = inspectorOf(row)?.bindScope;
|
|
2317
2342
|
if (!bind)
|
|
2318
2343
|
return refuseStatus(c, 501, `no scope binding registered for provider '${row.provider}'`);
|
|
2319
2344
|
const scopeId = scopeIdSchema.parse(c.req.param('scopeId'));
|
|
@@ -2367,7 +2392,7 @@ export function createControlPlaneApi(options) {
|
|
|
2367
2392
|
const row = await inspectableConnection(c);
|
|
2368
2393
|
if (!row)
|
|
2369
2394
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2370
|
-
const probe =
|
|
2395
|
+
const probe = inspectorOf(row)?.probe;
|
|
2371
2396
|
if (!probe) {
|
|
2372
2397
|
return refuseStatus(c, 501, `no probe registered for provider '${row.provider}'`);
|
|
2373
2398
|
}
|
|
@@ -2389,7 +2414,7 @@ export function createControlPlaneApi(options) {
|
|
|
2389
2414
|
const row = await inspectableConnection(c);
|
|
2390
2415
|
if (!row)
|
|
2391
2416
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2392
|
-
const activity =
|
|
2417
|
+
const activity = inspectorOf(row)?.activity;
|
|
2393
2418
|
if (!activity) {
|
|
2394
2419
|
return refuseStatus(c, 501, `no activity view registered for provider '${row.provider}'`);
|
|
2395
2420
|
}
|
|
@@ -2410,7 +2435,7 @@ export function createControlPlaneApi(options) {
|
|
|
2410
2435
|
const row = await inspectableConnection(c);
|
|
2411
2436
|
if (!row)
|
|
2412
2437
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2413
|
-
const credential =
|
|
2438
|
+
const credential = inspectorOf(row)?.credential;
|
|
2414
2439
|
if (!credential) {
|
|
2415
2440
|
return refuseStatus(c, 501, `no credential view registered for provider '${row.provider}'`);
|
|
2416
2441
|
}
|
|
@@ -2425,7 +2450,7 @@ export function createControlPlaneApi(options) {
|
|
|
2425
2450
|
const row = await inspectableConnection(c);
|
|
2426
2451
|
if (!row)
|
|
2427
2452
|
return refuse(c, 'not_found', 'unknown connection');
|
|
2428
|
-
const certificate = await
|
|
2453
|
+
const certificate = await inspectorOf(row)?.certificate?.(c.var.host, row);
|
|
2429
2454
|
if (!certificate)
|
|
2430
2455
|
return refuse(c, 'not_found', 'this connection signs in with no certificate');
|
|
2431
2456
|
return c.json(connectionCertificate.parse(certificate));
|
|
@@ -5883,7 +5908,10 @@ export function createControlPlaneApi(options) {
|
|
|
5883
5908
|
});
|
|
5884
5909
|
// The write half of the governed pull (§8) — load a dump INTO an existing scope:
|
|
5885
5910
|
// restore a backup, back out to a snapshot, or land a locally-built world on a
|
|
5886
|
-
// hosted app. Staff
|
|
5911
|
+
// hosted app. Staff, and a tenant's own credential (TENANT_ROUTES, path-pinned): the
|
|
5912
|
+
// dashboard's Import sends a file a team owner or admin uploaded (#2573), the dashboard
|
|
5913
|
+
// asking that role, since this plane sees the credential, not the person. Builders are
|
|
5914
|
+
// refused (not in BUILDER_ROUTES). The dump is input, judged on load. No jurisdiction
|
|
5887
5915
|
// gate: this is ingress — the data ENTERS the scope's pinned region, it never
|
|
5888
5916
|
// leaves one. Mirrors the export's delegation shape: the canonical `restoreScope`
|
|
5889
5917
|
// writes the audit row (and the co-located bytes); when the scope's data lives in
|
|
@@ -5988,7 +6016,7 @@ export function createControlPlaneApi(options) {
|
|
|
5988
6016
|
// A restore throw is driven by the caller-supplied dump (a shape the target cannot
|
|
5989
6017
|
// load, a DDL the engine rejects), so DISCLOSE it as an actionable 422 rather than
|
|
5990
6018
|
// collapsing to the generic 500 `internal error` mapError would produce (#321,
|
|
5991
|
-
// secondary obs #2). The route is staff
|
|
6019
|
+
// secondary obs #2). The route is staff- or own-tenant-gated and the detail is about the
|
|
5992
6020
|
// dump the caller sent, not another tenant's state.
|
|
5993
6021
|
const detail = e instanceof Error ? e.message : String(e);
|
|
5994
6022
|
return refuseStatus(c, 422, 'restore failed — the backup could not be loaded', { detail });
|
|
@@ -6743,6 +6771,8 @@ export function createControlPlaneApi(options) {
|
|
|
6743
6771
|
* vertical stays owner-only, and so do the reads narrowed on purpose (migration SQL,
|
|
6744
6772
|
* the prod history).
|
|
6745
6773
|
*/
|
|
6774
|
+
/** The bare slug of every registered vertical: what a manager's SKU may not be (#2388). */
|
|
6775
|
+
const verticalSlugsOf = async (actor) => (await host.admin.listVerticals(actor)).map((v) => bareSlug(v.slug));
|
|
6746
6776
|
/**
|
|
6747
6777
|
* Whether a CONFINED principal may grant its own tenant `key` (#977): some vertical it
|
|
6748
6778
|
* can read — its own, or a listed one — declares the key, or is the vertical whose
|
|
@@ -6750,14 +6780,40 @@ export function createControlPlaneApi(options) {
|
|
|
6750
6780
|
* (`installEntitlements`), checked here so a credential cannot grant what no install
|
|
6751
6781
|
* would. Read through the configured host: a check audits nothing.
|
|
6752
6782
|
*/
|
|
6783
|
+
/**
|
|
6784
|
+
* The refusal for REGISTERING a vertical whose bare slug is a plan SKU a manager declares (#2388),
|
|
6785
|
+
* so the manager's key does not change meaning under a later registration. A manager is a row that
|
|
6786
|
+
* holds the tenant-provisioner capability or declares `provisions` (the capability is granted after
|
|
6787
|
+
* the first push). Its own slug and the engine keys are always declarable, so they reserve nothing.
|
|
6788
|
+
* Only a new slug is judged; the sentence names no other vertical.
|
|
6789
|
+
*/
|
|
6790
|
+
const slugClaimsSku = async (actor, slug) => {
|
|
6791
|
+
const all = await host.admin.listVerticals(actor);
|
|
6792
|
+
if (all.some((v) => v.slug === slug))
|
|
6793
|
+
return undefined;
|
|
6794
|
+
const name = bareSlug(slug);
|
|
6795
|
+
return all.some((v) => (v.tenantProvisioner || v.provisions?.length) &&
|
|
6796
|
+
bareSlug(v.slug) !== name &&
|
|
6797
|
+
!ENGINE_ENTITLEMENT_KEYS.includes(name) &&
|
|
6798
|
+
v.entitlements?.includes(name))
|
|
6799
|
+
? `'${bareSlug(slug)}' is not available as a vertical name`
|
|
6800
|
+
: undefined;
|
|
6801
|
+
};
|
|
6802
|
+
/** The declared keys of a registry row that an install may grant: a manager's include plan SKUs. */
|
|
6803
|
+
const grantableOf = (v, slugs) => grantableEntitlements(v.slug, v.entitlements ?? [], v.tenantProvisioner ? slugs : undefined);
|
|
6753
6804
|
const tenantGrantable = async (p, key) => {
|
|
6754
6805
|
const pin = confinedTenant(p);
|
|
6755
6806
|
if (pin === null)
|
|
6756
6807
|
return true;
|
|
6757
|
-
const
|
|
6758
|
-
|
|
6759
|
-
|
|
6760
|
-
|
|
6808
|
+
const all = await host.admin.listVerticals(p.actor);
|
|
6809
|
+
const slugs = all.map((v) => bareSlug(v.slug));
|
|
6810
|
+
const visible = all.filter((v) => v.ownerTenant === pin || v.listed);
|
|
6811
|
+
return visible.some((v) => {
|
|
6812
|
+
// The install's own derivation (`installEntitlements`): the declared keys the vertical may
|
|
6813
|
+
// declare, else its bare slug.
|
|
6814
|
+
const grantable = grantableOf(v, slugs);
|
|
6815
|
+
return (grantable.length > 0 ? grantable : declarableEntitlementKey(v.slug, bareSlug(v.slug), v.tenantProvisioner ? slugs : undefined) ? [bareSlug(v.slug)] : []).includes(key);
|
|
6816
|
+
});
|
|
6761
6817
|
};
|
|
6762
6818
|
const notReadable = async (p, slug) => {
|
|
6763
6819
|
const pin = confinedTenant(p);
|
|
@@ -6834,7 +6890,13 @@ export function createControlPlaneApi(options) {
|
|
|
6834
6890
|
? all.filter((v) => v.ownerTenant === p.tenantId)
|
|
6835
6891
|
: all.filter((v) => (ownerTenant === undefined || v.ownerTenant === ownerTenant) &&
|
|
6836
6892
|
(visibleTo === undefined || v.listed || v.ownerTenant === visibleTo));
|
|
6837
|
-
|
|
6893
|
+
// The install catalog (`visibleTo`) carries what an install may grant, not what a row declared
|
|
6894
|
+
// before the namespace rule (#2388), so the dashboard's install and the grant paths agree.
|
|
6895
|
+
const slugs = visibleTo === undefined || p.kind === 'builder' ? [] : all.map((v) => bareSlug(v.slug));
|
|
6896
|
+
const rows = visibleTo === undefined || p.kind === 'builder'
|
|
6897
|
+
? visible
|
|
6898
|
+
: visible.map((v) => (v.entitlements ? { ...v, entitlements: grantableOf(v, slugs) } : v));
|
|
6899
|
+
return c.json(pageSlice(rows, page, (v) => v.slug));
|
|
6838
6900
|
});
|
|
6839
6901
|
// -- the service→dimensions resolver (#1231's last item) -----------------------
|
|
6840
6902
|
// What a Cloudflare service ref MEANS: each owned vertical's serving script and
|
|
@@ -6939,6 +7001,15 @@ export function createControlPlaneApi(options) {
|
|
|
6939
7001
|
return refuse(c, 'forbidden', 'forbidden');
|
|
6940
7002
|
input.ownerTenant = p.tenantId;
|
|
6941
7003
|
}
|
|
7004
|
+
const claimed = await slugClaimsSku(c.get('actor'), input.slug);
|
|
7005
|
+
if (claimed)
|
|
7006
|
+
return refuseStatus(c, 422, claimed);
|
|
7007
|
+
// #2388: the same declaration rule as a push, for any principal that is not staff.
|
|
7008
|
+
if (p.kind !== 'staff') {
|
|
7009
|
+
const foreignKey = entitlementNamespaceRefusal(input.slug, input.entitlements ?? [], input.provisions?.length ? await verticalSlugsOf(c.get('actor')) : undefined);
|
|
7010
|
+
if (foreignKey)
|
|
7011
|
+
return refuseStatus(c, 422, foreignKey);
|
|
7012
|
+
}
|
|
6942
7013
|
await c.var.admin.registerVertical(c.get('actor'), input);
|
|
6943
7014
|
// Idempotent on the slug (a conflicting re-register throws below the seam), so
|
|
6944
7015
|
// read back rather than echo the request.
|
|
@@ -7009,6 +7080,9 @@ export function createControlPlaneApi(options) {
|
|
|
7009
7080
|
const ownerGrants = pushedOwnerGrantProblems(checked.data);
|
|
7010
7081
|
if (ownerGrants.length > 0)
|
|
7011
7082
|
return refuseManifest({ path: ['ownerGrants'], message: ownerGrants.join('; ') });
|
|
7083
|
+
const connectorProblems = pushedConnectorProblems(checked.data);
|
|
7084
|
+
if (connectorProblems.length > 0)
|
|
7085
|
+
return refuseManifest({ path: ['connectors'], message: connectorProblems.join('; ') });
|
|
7012
7086
|
}
|
|
7013
7087
|
await c.var.admin.publishVersion(c.get('actor'), input);
|
|
7014
7088
|
const version = await c.var.admin.getVersion(c.get('actor'), input.id, slug);
|
|
@@ -7488,6 +7562,11 @@ export function createControlPlaneApi(options) {
|
|
|
7488
7562
|
: undefined);
|
|
7489
7563
|
await recordWireUpload(admin, actor, versionId, wire);
|
|
7490
7564
|
const addedClasses = serving ? doClasses.some((cls) => !serving.doClasses.includes(cls)) : false;
|
|
7565
|
+
// #2577: `serving`'s class set and tag are what the upload's migration was diffed from, so the
|
|
7566
|
+
// record lands only while the row still holds them; a serve that moved only the ref and version
|
|
7567
|
+
// meanwhile is recorded over, as before. A refusal is not retried: the script already runs this
|
|
7568
|
+
// upload. When a migration rode it, the runtime's tag is past the record's and a retry cannot land.
|
|
7569
|
+
const migrated = !serving || addedClasses;
|
|
7491
7570
|
await admin.setVerticalServing(actor, slug, {
|
|
7492
7571
|
ref,
|
|
7493
7572
|
versionId,
|
|
@@ -7500,6 +7579,8 @@ export function createControlPlaneApi(options) {
|
|
|
7500
7579
|
? nextMigrationTag(serving.migrationTag)
|
|
7501
7580
|
: serving.migrationTag
|
|
7502
7581
|
: 'v1',
|
|
7582
|
+
}, serving).catch((e) => {
|
|
7583
|
+
throw migrated && errorCodeOf(e) === 'precondition_failed' ? new ServeRecordBehindScript(slug) : e;
|
|
7503
7584
|
});
|
|
7504
7585
|
};
|
|
7505
7586
|
/**
|
|
@@ -7811,7 +7892,11 @@ export function createControlPlaneApi(options) {
|
|
|
7811
7892
|
// The serve, the adopt and the backfill reach every install of the vertical, whoever's, so
|
|
7812
7893
|
// what failed is withheld from a confined caller (#2540), and the tenant the backstop would
|
|
7813
7894
|
// have filed it under reads only the sentence.
|
|
7814
|
-
|
|
7895
|
+
// #2577: a serve refused after its upload already runs the new code, so neither says which code runs.
|
|
7896
|
+
const sentence = (reference) => e instanceof ServeRecordBehindScript
|
|
7897
|
+
? `promoted, but the in-place serve failed — another serve changed the serving record while this one ` +
|
|
7898
|
+
`added a Durable Object class, so promoting again cannot land until the record is repaired (reference ${reference})`
|
|
7899
|
+
: `promoted, but the in-place serve failed — promote again to retry (reference ${reference})`;
|
|
7815
7900
|
const withheld = withheldFailure(c, {
|
|
7816
7901
|
operation: 'promote.serve',
|
|
7817
7902
|
stage: 'serve-in-place',
|
|
@@ -7906,6 +7991,10 @@ export function createControlPlaneApi(options) {
|
|
|
7906
7991
|
const ownerGrants = pushedOwnerGrantProblems(manifest);
|
|
7907
7992
|
if (ownerGrants.length > 0)
|
|
7908
7993
|
return refuse(c, 'validation_failed', `manifest ownerGrants: ${ownerGrants.join('; ')}`);
|
|
7994
|
+
// vertical-connectors.md §7.1: a connector's standing grant is a declared, person-held key.
|
|
7995
|
+
const connectorProblems = pushedConnectorProblems(manifest);
|
|
7996
|
+
if (connectorProblems.length > 0)
|
|
7997
|
+
return refuse(c, 'validation_failed', `manifest connectors: ${connectorProblems.join('; ')}`);
|
|
7909
7998
|
// §4 sandbox contract, before anything reaches the namespace.
|
|
7910
7999
|
assertSandboxContract(manifest, options.storeDrivers);
|
|
7911
8000
|
// #2339: a push whose migration digest is not the one its migrations give is refused here,
|
|
@@ -8050,6 +8139,17 @@ export function createControlPlaneApi(options) {
|
|
|
8050
8139
|
if (!modules.some((m) => m.name === manifest.entry)) {
|
|
8051
8140
|
return refuse(c, 'validation_failed', `entry module '${manifest.entry}' is not among the uploaded files`);
|
|
8052
8141
|
}
|
|
8142
|
+
// #2388: a new version declares only keys its vertical may (its own, the engines', and those of
|
|
8143
|
+
// the verticals it provisions). The capability is granted after a first push, so the declaration
|
|
8144
|
+
// is judged here and honoured by the grant paths only for a tenant-provisioner. Earlier versions
|
|
8145
|
+
// are not re-judged.
|
|
8146
|
+
// Declaring `provisions` marks a manager: the capability itself is granted after a first push.
|
|
8147
|
+
const foreignKey = entitlementNamespaceRefusal(slug, manifest.entitlements ?? [], manifest.provisions?.length ? await verticalSlugsOf(c.get('actor')) : undefined);
|
|
8148
|
+
if (foreignKey)
|
|
8149
|
+
return refuseStatus(c, 422, foreignKey);
|
|
8150
|
+
const claimed = await slugClaimsSku(c.get('actor'), slug);
|
|
8151
|
+
if (claimed)
|
|
8152
|
+
return refuseStatus(c, 422, claimed);
|
|
8053
8153
|
// The static-asset half of the §4 sandbox contract (self-serve-deploy.md §4.1). The
|
|
8054
8154
|
// bytes are inert — no code, no authority — so they are ACCEPTED; the content-address
|
|
8055
8155
|
// is not, so it is VERIFIED. The runtime's asset store dedups by hash across the whole
|
|
@@ -8179,6 +8279,9 @@ export function createControlPlaneApi(options) {
|
|
|
8179
8279
|
...(manifest.entitlements ? { entitlements: manifest.entitlements } : {}),
|
|
8180
8280
|
...(manifest.provides ? { provides: manifest.provides } : {}),
|
|
8181
8281
|
...(manifest.requires ? { requires: manifest.requires } : {}),
|
|
8282
|
+
// The declared vertical-defined connectors (vertical-connectors.md §7.2): what the dashboard's
|
|
8283
|
+
// door renders. The proxy never reads this copy; it reads the running version's manifest.
|
|
8284
|
+
...(manifest.connectors ? { connectors: manifest.connectors } : {}),
|
|
8182
8285
|
// The declared provisioner intent (#455) — a REQUEST the console reviews; the
|
|
8183
8286
|
// tenant-provisioner grant itself is never touched by a push. Refreshes on every
|
|
8184
8287
|
// re-push like the rest of the install spec, exactly because it grants nothing.
|