@noodleseed/one 0.137.0 → 0.138.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/commands/assistant-ops.d.ts.map +1 -1
- package/dist/commands/assistant-ops.js +30 -1
- package/dist/commands/assistant-ops.js.map +1 -1
- package/dist/commands/deploy-first-flow.d.ts +2 -0
- package/dist/commands/deploy-first-flow.d.ts.map +1 -1
- package/dist/commands/deploy-first-flow.js +46 -14
- package/dist/commands/deploy-first-flow.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +27 -1
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/deploy-preflight.d.ts +1 -0
- package/dist/commands/deploy-preflight.d.ts.map +1 -1
- package/dist/commands/deploy-preflight.js +1 -0
- package/dist/commands/deploy-preflight.js.map +1 -1
- package/dist/commands/deploy-status-ops.d.ts +1 -0
- package/dist/commands/deploy-status-ops.d.ts.map +1 -1
- package/dist/commands/deploy-status-ops.js +59 -4
- package/dist/commands/deploy-status-ops.js.map +1 -1
- package/dist/commands/deployments-ops.d.ts.map +1 -1
- package/dist/commands/deployments-ops.js +2 -0
- package/dist/commands/deployments-ops.js.map +1 -1
- package/dist/commands/diagnostics-ops.d.ts +1 -0
- package/dist/commands/diagnostics-ops.d.ts.map +1 -1
- package/dist/commands/diagnostics-ops.js +3 -0
- package/dist/commands/diagnostics-ops.js.map +1 -1
- package/dist/deploy.d.ts +3 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +4 -0
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/admission-limits/dist/envelope.js +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +3 -3
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-embedded-assistant-ref.js +6 -7
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.d.ts +6 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/assistant-store.js +5 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/model-request.js +37 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/model-runtime.js +4 -0
- package/node_modules/@noodle-borg/{service/dist/assistant-model-stream.js → assistant-gateway/dist/model-stream.js} +34 -2
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-session.d.ts +3 -0
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-session.js +2 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-turn.d.ts +4 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/public-turn.js +2 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.d.ts +6 -1
- package/node_modules/@noodle-borg/assistant-gateway/dist/surface-budget.js +11 -5
- package/node_modules/@noodle-borg/assistant-gateway/package.json +5 -1
- package/node_modules/@noodle-borg/authoring/dist/assistant.d.ts +10 -2
- package/node_modules/@noodle-borg/authoring/dist/assistant.js +4 -0
- package/node_modules/@noodle-borg/authoring/dist/index.d.ts +1 -1
- package/node_modules/@noodle-borg/authoring/dist/index.js +1 -1
- package/node_modules/@noodle-borg/authoring/dist/load-authored.js +1 -1
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-assistant.js +17 -0
- package/node_modules/@noodle-borg/cli-catalog/dist/catalog-data-hosted-deployment.js +14 -0
- package/node_modules/@noodle-borg/compiler/dist/artifact/types.d.ts +1 -7
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.d.ts +20 -8
- package/node_modules/@noodle-borg/compiler/dist/manifest/schema.js +12 -8
- package/node_modules/@noodle-borg/control-plane/dist/portable.d.ts +2 -0
- package/node_modules/@noodle-borg/control-plane/dist/portable.js +1 -0
- package/node_modules/@noodle-borg/control-plane/dist/rollback-deployment.d.ts +61 -0
- package/node_modules/@noodle-borg/{service/dist/operations → control-plane/dist}/rollback-deployment.js +3 -2
- package/node_modules/@noodle-borg/control-plane/dist/rollback-result.d.ts +19 -0
- package/node_modules/@noodle-borg/control-plane/package.json +3 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/contracts.js +4 -0
- package/node_modules/@noodle-borg/developer-mcp/dist/widgets/app-overview.js +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/widgets/deployment-detail.js +1 -1
- package/node_modules/@noodle-borg/module/dist/contract.d.ts +1 -0
- package/node_modules/@noodle-borg/module/dist/deployment-automation.d.ts +1 -1
- package/node_modules/@noodle-borg/module/dist/endpoint-url.d.ts +11 -0
- package/node_modules/@noodle-borg/module/dist/endpoint-url.js +20 -0
- package/node_modules/@noodle-borg/module/dist/index.d.ts +1 -0
- package/node_modules/@noodle-borg/module/dist/index.js +1 -0
- package/node_modules/@noodle-borg/observability/dist/assistant-usage.js +217 -0
- package/node_modules/@noodle-borg/observability/dist/index.js +2 -0
- package/node_modules/@noodle-borg/{service → observability}/dist/request-event-metrics.js +5 -2
- package/node_modules/@noodle-borg/observability/dist/request-events-postgres.js +6 -0
- package/node_modules/@noodle-borg/observability/dist/request-events.js +2 -0
- package/node_modules/@noodle-borg/service/dist/assistant-bindings.js +3 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/control-plane-adapter.js +3 -3
- package/node_modules/@noodle-borg/service/dist/developer-mcp/inspection.js +2 -1
- package/node_modules/@noodle-borg/service/dist/registry-access.js +73 -24
- package/node_modules/@noodle-borg/service/dist/registry-deploy-transaction.js +5 -2
- package/node_modules/@noodle-borg/service/dist/registry-helpers.d.ts +5 -9
- package/node_modules/@noodle-borg/service/dist/registry-helpers.js +4 -18
- package/node_modules/@noodle-borg/service/dist/registry-rollback.js +3 -1
- package/node_modules/@noodle-borg/service/dist/registry-status.js +4 -1
- package/node_modules/@noodle-borg/service/dist/registry-targets.js +4 -4
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +11 -16
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +8 -5
- package/node_modules/@noodle-borg/service/dist/registry.js +8 -5
- package/node_modules/@noodle-borg/service/dist/routes/access.js +19 -1
- package/node_modules/@noodle-borg/service/dist/routes/analytics-dispatch.js +17 -1
- package/node_modules/@noodle-borg/service/dist/routes/analytics.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-agent.js +73 -59
- package/node_modules/@noodle-borg/service/dist/routes/assistant-doctor.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/assistant-model-binding.js +28 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-session.js +18 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-public-turn.js +6 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant-usage.js +42 -0
- package/node_modules/@noodle-borg/service/dist/routes/assistant.js +20 -3
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.js +1 -2
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +49 -4
- package/node_modules/@noodle-borg/service/dist/routes/deploy-preflight.js +11 -1
- package/node_modules/@noodle-borg/service/dist/routes/endpoint-enrichment.js +2 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.js +4 -0
- package/node_modules/@noodle-borg/service/dist/routes/rollback.js +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +6 -0
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +2 -5
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js +9 -21
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +2 -5
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +8 -20
- package/node_modules/@noodle-borg/service/dist/store/records.js +39 -0
- package/node_modules/@noodle-borg/service/dist/store.d.ts +21 -10
- package/node_modules/@noodle-borg/service/package.json +5 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/control-plane.d.ts +120 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/control-plane.js +123 -1
- package/node_modules/@noodle-borg/wire-contracts/dist/index.d.ts +4 -0
- package/node_modules/@noodle-borg/wire-contracts/dist/index.js +15 -1
- package/node_modules/@noodleseed/assistant/package.json +1 -1
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@ import { deployPreflightRequestSchema, formatWireError } from '@noodle-borg/wire
|
|
|
3
3
|
import { readDeployBody, sendJson } from '../http-util.js';
|
|
4
4
|
import { manifestUsesUserRoot } from '../registry-access.js';
|
|
5
5
|
import { isIdentityAccessMode } from './access-mode.js';
|
|
6
|
-
import { authorizeTenantControl, developerGrantRouteAccess } from './control-plane.js';
|
|
6
|
+
import { authorizeDeploymentOwnerSelection, authorizeTenantControl, developerGrantRouteAccess, } from './control-plane.js';
|
|
7
7
|
/**
|
|
8
8
|
* Read-only first-deploy readiness. It intentionally does not verify uploaded asset bytes:
|
|
9
9
|
* the CLI calls this before it requests upload targets or sends any bytes.
|
|
@@ -49,6 +49,9 @@ export async function handleDeployPreflight(req, res, registry, options, maxBody
|
|
|
49
49
|
error: `${accessMode} deployments require an authenticated deployer`,
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
const ownerSelection = await authorizeDeploymentOwnerSelection(res, controlPlane, tenant.org, accessMode, identity, parsed.ownerSubject);
|
|
53
|
+
if (!ownerSelection.ok)
|
|
54
|
+
return;
|
|
52
55
|
if (accessMode === 'public' && manifestUsesUserRoot(parsed.manifest)) {
|
|
53
56
|
return sendJson(res, 400, {
|
|
54
57
|
code: 'public_user_context_conflict',
|
|
@@ -71,6 +74,7 @@ export async function handleDeployPreflight(req, res, registry, options, maxBody
|
|
|
71
74
|
...(parsed.connectors !== undefined ? { connectors: parsed.connectors } : {}),
|
|
72
75
|
actor: identity,
|
|
73
76
|
accessMode,
|
|
77
|
+
ownerSubject: ownerSelection.ownerSubject,
|
|
74
78
|
...(parsed.orgMembershipSources !== undefined
|
|
75
79
|
? { orgMembershipSources: parsed.orgMembershipSources }
|
|
76
80
|
: {}),
|
|
@@ -99,6 +103,9 @@ export async function handleDeployPreflight(req, res, registry, options, maxBody
|
|
|
99
103
|
ready,
|
|
100
104
|
appState,
|
|
101
105
|
environmentState,
|
|
106
|
+
...(ownerSelection.ownerSubject !== undefined
|
|
107
|
+
? { ownerSubject: ownerSelection.ownerSubject }
|
|
108
|
+
: {}),
|
|
102
109
|
errorCount: errors.length,
|
|
103
110
|
codes,
|
|
104
111
|
missingSecretCount: missingSecrets.length,
|
|
@@ -108,6 +115,9 @@ export async function handleDeployPreflight(req, res, registry, options, maxBody
|
|
|
108
115
|
return sendJson(res, 200, {
|
|
109
116
|
ok: true,
|
|
110
117
|
ready,
|
|
118
|
+
...(ownerSelection.ownerSubject !== undefined
|
|
119
|
+
? { ownerSubject: ownerSelection.ownerSubject }
|
|
120
|
+
: {}),
|
|
111
121
|
target: {
|
|
112
122
|
...tenant,
|
|
113
123
|
appState,
|
|
@@ -204,6 +204,10 @@ export function parseTenantSessionPath(pathname) {
|
|
|
204
204
|
sessionId: decodeSegment(match, 4),
|
|
205
205
|
}));
|
|
206
206
|
}
|
|
207
|
+
/** `GET .../assistant/usage` — scalar-only embedded assistant engagement and model usage. */
|
|
208
|
+
export function parseTenantAssistantUsagePath(pathname) {
|
|
209
|
+
return matchPath(pathname, /^\/v1\/orgs\/([^/]+)\/apps\/([^/]+)\/envs\/([^/]+)\/assistant\/usage$/, tenantRef);
|
|
210
|
+
}
|
|
207
211
|
/** Match `/v1/orgs/{org}/apps/{app}/github/connection` (GHD-1 repository connection, GET/POST/DELETE). */
|
|
208
212
|
export function parseGithubConnectionPath(pathname) {
|
|
209
213
|
return matchPath(pathname, /^\/v1\/orgs\/([^/]+)\/apps\/([^/]+)\/github\/connection$/, appRef);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { rollbackDeploymentOperation } from '@noodle-borg/control-plane/portable';
|
|
1
2
|
import { baseFromRequest, readJsonBody, sendForbidden, sendJson } from '../http-util.js';
|
|
2
3
|
import { endpointUrlOptionsForOrg } from '../mcp-public-routing.js';
|
|
3
|
-
import { rollbackDeploymentOperation } from '../operations/rollback-deployment.js';
|
|
4
4
|
import { authorizeTenantControl, developerGrantRouteAccess } from './control-plane.js';
|
|
5
5
|
export async function handleRollback(req, res, registry, gate, controlPlane, audit, maxBody, tenant, options) {
|
|
6
6
|
const identity = await authorizeTenantControl(req, res, gate, controlPlane, tenant.org, developerGrantRouteAccess(options.developerGrantStore, 'deployments:rollback'));
|
|
@@ -253,6 +253,12 @@ export function createServiceHandler(registry, options = {}) {
|
|
|
253
253
|
...(options.assistantModelFetch !== undefined
|
|
254
254
|
? { modelFetch: options.assistantModelFetch }
|
|
255
255
|
: {}),
|
|
256
|
+
...(options.managedAssistantModelResolver !== undefined
|
|
257
|
+
? { managedModelResolver: options.managedAssistantModelResolver }
|
|
258
|
+
: {}),
|
|
259
|
+
...(options.captureRequestEvent !== undefined
|
|
260
|
+
? { captureRequestEvent: options.captureRequestEvent }
|
|
261
|
+
: {}),
|
|
256
262
|
...(options.clock !== undefined ? { clock: options.clock } : {}),
|
|
257
263
|
logger,
|
|
258
264
|
applySecurityHeaders,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AccessMode } from '@noodle-borg/transport-http';
|
|
2
|
-
import type { AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationResult, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
2
|
+
import type { ActiveAccessUpdateInput, AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationResult, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
3
3
|
/** In-memory store: keeps records in a Map. Used by tests and as an explicit, non-persistent option. */
|
|
4
4
|
export declare class InMemoryArtifactStore implements ArtifactStore {
|
|
5
5
|
#private;
|
|
@@ -16,10 +16,7 @@ export declare class InMemoryArtifactStore implements ArtifactStore {
|
|
|
16
16
|
}, _options?: {
|
|
17
17
|
readonly automationId?: string;
|
|
18
18
|
}): Promise<DeploymentActivationResult | undefined>;
|
|
19
|
-
updateActiveAccess(ref: TenantRef, deploymentId: string,
|
|
20
|
-
readonly expectedAccessMode: AccessMode | undefined;
|
|
21
|
-
readonly serverAuth?: TenantAuthConfig;
|
|
22
|
-
}): Promise<DeployRecord | undefined>;
|
|
19
|
+
updateActiveAccess(ref: TenantRef, deploymentId: string, input: ActiveAccessUpdateInput): Promise<DeployRecord | undefined>;
|
|
23
20
|
listDeployments(filter: DeploymentListFilter): Promise<readonly DeploymentSummary[]>;
|
|
24
21
|
getAppArchivedAt(org: string, app: string): Promise<string | undefined>;
|
|
25
22
|
archiveApp(org: string, app: string, at: string): Promise<AppArchiveResult | undefined>;
|
|
@@ -3,7 +3,7 @@ import { assertSameAppPackageSnapshot, sanitizeDeployRecordAppPackageSnapshot, }
|
|
|
3
3
|
import { assertCustomerAuthRestorePrecondition, assertUniqueActiveCustomerAuthAudienceBindings, findActiveCustomerAuthAudienceConflict, } from '../customer-auth-audience-binding.js';
|
|
4
4
|
import { assertDeploymentActivationUnlocked, assertDeploymentAppendUnlocked, } from '../deployment-lock.js';
|
|
5
5
|
import { defaultActiveRecord, sameDeploymentScope, sameTenantRecord, } from '../deployment-versioning.js';
|
|
6
|
-
import { appArchivedAt, deploymentSummary, matchesDeploymentFilter, paginateAppSummaries, planAppArchive, planAppRestore, resolveProductionEnvironment, summarizeApps, summarizeEnvs, validateDeploymentListFilter, withoutArchiveStamp, } from './records.js';
|
|
6
|
+
import { appArchivedAt, deploymentSummary, matchesDeploymentFilter, paginateAppSummaries, planAppArchive, planAppRestore, preserveDeploymentOwnerState, resolveActiveAccessUpdate, resolveProductionEnvironment, summarizeApps, summarizeEnvs, validateDeploymentListFilter, withoutArchiveStamp, } from './records.js';
|
|
7
7
|
import { validateSlug, validateTenantRef } from './validate.js';
|
|
8
8
|
/** In-memory store: keeps records in a Map. Used by tests and as an explicit, non-persistent option. */
|
|
9
9
|
export class InMemoryArtifactStore {
|
|
@@ -14,6 +14,8 @@ export class InMemoryArtifactStore {
|
|
|
14
14
|
if (existing !== undefined)
|
|
15
15
|
assertSameAppPackageSnapshot(existing, record);
|
|
16
16
|
record = sanitizeDeployRecordAppPackageSnapshot(record);
|
|
17
|
+
if (existing !== undefined)
|
|
18
|
+
record = preserveDeploymentOwnerState(existing, record);
|
|
17
19
|
validateTenantRef({ org: record.orgSlug, app: record.appSlug, env: record.environment });
|
|
18
20
|
if (!assertDeploymentAppendUnlocked([...this.#records.values()], record))
|
|
19
21
|
return;
|
|
@@ -117,29 +119,15 @@ export class InMemoryArtifactStore {
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
|
-
async updateActiveAccess(ref, deploymentId,
|
|
122
|
+
async updateActiveAccess(ref, deploymentId, input) {
|
|
121
123
|
const safe = validateTenantRef(ref);
|
|
122
124
|
const record = this.#records.get(deploymentId);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
record.accessMode !== precondition.expectedAccessMode) {
|
|
128
|
-
return Promise.resolve(undefined);
|
|
129
|
-
}
|
|
130
|
-
if ((record.accessMode ?? 'owner-only') === accessMode && accessMode !== 'customers') {
|
|
131
|
-
return Promise.resolve(record);
|
|
132
|
-
}
|
|
133
|
-
const updated = {
|
|
134
|
-
...record,
|
|
135
|
-
accessMode,
|
|
136
|
-
...(accessMode === 'customers' && precondition.serverAuth !== undefined
|
|
137
|
-
? { serverAuth: precondition.serverAuth }
|
|
138
|
-
: {}),
|
|
139
|
-
};
|
|
140
|
-
const proposed = new Map(this.#records).set(record.deploymentId, updated);
|
|
125
|
+
const updated = resolveActiveAccessUpdate(record, safe, input);
|
|
126
|
+
if (updated === undefined || updated === record)
|
|
127
|
+
return Promise.resolve(updated);
|
|
128
|
+
const proposed = new Map(this.#records).set(updated.deploymentId, updated);
|
|
141
129
|
assertUniqueActiveCustomerAuthAudienceBindings([...proposed.values()]);
|
|
142
|
-
this.#records.set(
|
|
130
|
+
this.#records.set(updated.deploymentId, updated);
|
|
143
131
|
return Promise.resolve(updated);
|
|
144
132
|
}
|
|
145
133
|
listDeployments(filter) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AccessMode } from '@noodle-borg/transport-http';
|
|
2
|
-
import type { AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationResult, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
2
|
+
import type { ActiveAccessUpdateInput, AppArchiveResult, AppRestorePrecondition, AppRestoreResult, AppSummary, ArtifactStore, DeploymentActivationResult, DeploymentListFilter, DeploymentLock, DeploymentLockUpdateResult, DeploymentSummary, DeployRecord, EnvSummary, ProductionEnvironmentChange, TenantAuthConfig, TenantRef } from '../store.js';
|
|
3
3
|
/**
|
|
4
4
|
* JSON-file store: one file per deployment at `<dataDir>/deployments/<deploymentId>.json`, written atomically
|
|
5
5
|
* (write a temp file, then `rename` over the target — no partial file is ever read). `deploymentId` is a
|
|
@@ -15,10 +15,7 @@ export declare class JsonFileArtifactStore implements ArtifactStore {
|
|
|
15
15
|
getActiveByTenantVersion(ref: TenantRef, serverVersion: string): Promise<DeployRecord | undefined>;
|
|
16
16
|
setDeploymentLock(ref: TenantRef, serverVersion: string, expectedDeploymentId: string, deploymentLock: DeploymentLock | undefined): Promise<DeploymentLockUpdateResult>;
|
|
17
17
|
findActiveCustomerAuthAudienceConflict(ref: TenantRef, auth: TenantAuthConfig): Promise<TenantRef | undefined>;
|
|
18
|
-
updateActiveAccess(ref: TenantRef, deploymentId: string,
|
|
19
|
-
readonly expectedAccessMode: AccessMode | undefined;
|
|
20
|
-
readonly serverAuth?: TenantAuthConfig;
|
|
21
|
-
}): Promise<DeployRecord | undefined>;
|
|
18
|
+
updateActiveAccess(ref: TenantRef, deploymentId: string, input: ActiveAccessUpdateInput): Promise<DeployRecord | undefined>;
|
|
22
19
|
activateDeployment(ref: TenantRef, deploymentId: string, precondition?: {
|
|
23
20
|
readonly expectedAccessMode: AccessMode | undefined;
|
|
24
21
|
readonly serverAuth?: TenantAuthConfig;
|
|
@@ -6,7 +6,7 @@ import { assertSameAppPackageSnapshot, sanitizeDeployRecordAppPackageSnapshot, }
|
|
|
6
6
|
import { assertCustomerAuthRestorePrecondition, assertUniqueActiveCustomerAuthAudienceBindings, findActiveCustomerAuthAudienceConflict, } from '../customer-auth-audience-binding.js';
|
|
7
7
|
import { assertDeploymentActivationUnlocked, assertDeploymentAppendUnlocked, } from '../deployment-lock.js';
|
|
8
8
|
import { defaultActiveRecord, sameDeploymentScope, sameTenantRecord, } from '../deployment-versioning.js';
|
|
9
|
-
import { appArchivedAt, deploymentSummary, matchesDeploymentFilter, paginateAppSummaries, planAppArchive, planAppRestore, resolveProductionEnvironment, summarizeApps, summarizeEnvs, validateDeploymentListFilter, withoutArchiveStamp, } from './records.js';
|
|
9
|
+
import { appArchivedAt, deploymentSummary, matchesDeploymentFilter, paginateAppSummaries, planAppArchive, planAppRestore, preserveDeploymentOwnerState, resolveActiveAccessUpdate, resolveProductionEnvironment, summarizeApps, summarizeEnvs, validateDeploymentListFilter, withoutArchiveStamp, } from './records.js';
|
|
10
10
|
import { DEPLOYMENT_ID_PATTERN, validateSlug, validateTenantRef } from './validate.js';
|
|
11
11
|
/**
|
|
12
12
|
* JSON-file store: one file per deployment at `<dataDir>/deployments/<deploymentId>.json`, written atomically
|
|
@@ -38,6 +38,8 @@ export class JsonFileArtifactStore {
|
|
|
38
38
|
if (existing !== undefined)
|
|
39
39
|
assertSameAppPackageSnapshot(existing, record);
|
|
40
40
|
record = sanitizeDeployRecordAppPackageSnapshot(record);
|
|
41
|
+
if (existing !== undefined)
|
|
42
|
+
record = preserveDeploymentOwnerState(existing, record);
|
|
41
43
|
if (!assertDeploymentAppendUnlocked(records, record))
|
|
42
44
|
return;
|
|
43
45
|
const proposed = new Map(records.map((item) => [item.deploymentId, item]));
|
|
@@ -104,28 +106,14 @@ export class JsonFileArtifactStore {
|
|
|
104
106
|
async findActiveCustomerAuthAudienceConflict(ref, auth) {
|
|
105
107
|
return findActiveCustomerAuthAudienceConflict(await this.loadAll(), validateTenantRef(ref), auth);
|
|
106
108
|
}
|
|
107
|
-
async updateActiveAccess(ref, deploymentId,
|
|
109
|
+
async updateActiveAccess(ref, deploymentId, input) {
|
|
108
110
|
const safe = validateTenantRef(ref);
|
|
109
111
|
return this.#serializeLifecycle(async () => {
|
|
110
112
|
const record = await this.get(deploymentId);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
record.accessMode !== precondition.expectedAccessMode) {
|
|
116
|
-
return undefined;
|
|
117
|
-
}
|
|
118
|
-
if ((record.accessMode ?? 'owner-only') === accessMode && accessMode !== 'customers') {
|
|
119
|
-
return record;
|
|
120
|
-
}
|
|
121
|
-
const updated = {
|
|
122
|
-
...record,
|
|
123
|
-
accessMode,
|
|
124
|
-
...(accessMode === 'customers' && precondition.serverAuth !== undefined
|
|
125
|
-
? { serverAuth: precondition.serverAuth }
|
|
126
|
-
: {}),
|
|
127
|
-
};
|
|
128
|
-
const proposed = new Map((await this.loadAll()).map((item) => [item.deploymentId, item])).set(record.deploymentId, updated);
|
|
113
|
+
const updated = resolveActiveAccessUpdate(record, safe, input);
|
|
114
|
+
if (updated === undefined || updated === record)
|
|
115
|
+
return updated;
|
|
116
|
+
const proposed = new Map((await this.loadAll()).map((item) => [item.deploymentId, item])).set(updated.deploymentId, updated);
|
|
129
117
|
assertUniqueActiveCustomerAuthAudienceBindings([...proposed.values()]);
|
|
130
118
|
await this.#writeRecord(updated);
|
|
131
119
|
return updated;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure record-level helpers shared by every {@link ArtifactStore} backend: the canonical
|
|
3
|
+
* deployment-summary mapping, list filtering, app archive/restore planning (ADR 0117), and the
|
|
4
|
+
* `apps` resource aggregation (`summarizeApps`). No I/O here — backends apply the plans to their
|
|
5
|
+
* own persistence and feed their own raw records/anchors through these pure functions so every
|
|
6
|
+
* backend groups, ranks, and sorts identically.
|
|
7
|
+
*/
|
|
8
|
+
import { sameTenantRecord } from '../deployment-versioning.js';
|
|
9
|
+
import { deploymentOwnerSubject } from '../registry-helpers.js';
|
|
1
10
|
import { validateSlug } from './validate.js';
|
|
2
11
|
/** The canonical, secret-free list projection of a {@link DeployRecord}. */
|
|
3
12
|
export function deploymentSummary(record) {
|
|
13
|
+
const ownerSubject = deploymentOwnerSubject(record);
|
|
4
14
|
return {
|
|
5
15
|
deploymentId: record.deploymentId,
|
|
6
16
|
orgSlug: record.orgSlug,
|
|
@@ -11,6 +21,7 @@ export function deploymentSummary(record) {
|
|
|
11
21
|
serverName: record.serverName,
|
|
12
22
|
createdAt: record.createdAt,
|
|
13
23
|
...(record.createdByEmail !== undefined ? { createdByEmail: record.createdByEmail } : {}),
|
|
24
|
+
...(ownerSubject !== undefined ? { ownerSubject } : {}),
|
|
14
25
|
...(record.deploymentSource !== undefined ? { deploymentSource: record.deploymentSource } : {}),
|
|
15
26
|
accessMode: record.accessMode ?? 'owner-only',
|
|
16
27
|
...(record.deploymentLock !== undefined
|
|
@@ -95,6 +106,34 @@ export function withoutArchiveStamp(record) {
|
|
|
95
106
|
const { archivedAt: _cleared, ...rest } = record;
|
|
96
107
|
return rest;
|
|
97
108
|
}
|
|
109
|
+
export function preserveDeploymentOwnerState(existing, candidate) {
|
|
110
|
+
const { ownerSubject: _candidateOwnerSubject, ...deployFields } = candidate;
|
|
111
|
+
return {
|
|
112
|
+
...deployFields,
|
|
113
|
+
...(existing.ownerSubject !== undefined ? { ownerSubject: existing.ownerSubject } : {}),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export function resolveActiveAccessUpdate(record, ref, input) {
|
|
117
|
+
if (record === undefined ||
|
|
118
|
+
!record.active ||
|
|
119
|
+
record.archivedAt !== undefined ||
|
|
120
|
+
!sameTenantRecord(record, ref) ||
|
|
121
|
+
record.accessMode !== input.expectedAccessMode ||
|
|
122
|
+
deploymentOwnerSubject(record) !== input.expectedOwnerSubject)
|
|
123
|
+
return undefined;
|
|
124
|
+
if ((record.accessMode ?? 'owner-only') === input.accessMode &&
|
|
125
|
+
(input.ownerSubject === undefined || deploymentOwnerSubject(record) === input.ownerSubject) &&
|
|
126
|
+
input.accessMode !== 'customers')
|
|
127
|
+
return record;
|
|
128
|
+
return {
|
|
129
|
+
...record,
|
|
130
|
+
accessMode: input.accessMode,
|
|
131
|
+
...(input.ownerSubject !== undefined ? { ownerSubject: input.ownerSubject } : {}),
|
|
132
|
+
...(input.accessMode === 'customers' && input.serverAuth !== undefined
|
|
133
|
+
? { serverAuth: input.serverAuth }
|
|
134
|
+
: {}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
98
137
|
const ENVIRONMENT_RANK = { prod: 0, staging: 1, dev: 2 };
|
|
99
138
|
function environmentRank(environment) {
|
|
100
139
|
return ENVIRONMENT_RANK[environment] ?? 3;
|
|
@@ -47,6 +47,8 @@ export interface DeployRecord {
|
|
|
47
47
|
readonly createdAt: string;
|
|
48
48
|
readonly createdBySubject?: string;
|
|
49
49
|
readonly createdByEmail?: string;
|
|
50
|
+
/** OAuth subject authorized by owner-only access; absent legacy records fall back to the creator. */
|
|
51
|
+
readonly ownerSubject?: string;
|
|
50
52
|
/** Informational deploy origin. Absent on records written before source tracking. */
|
|
51
53
|
readonly deploymentSource?: DeploymentSource;
|
|
52
54
|
/**
|
|
@@ -142,6 +144,7 @@ export interface DeploymentSummary {
|
|
|
142
144
|
readonly serverName: string;
|
|
143
145
|
readonly createdAt: string;
|
|
144
146
|
readonly createdByEmail?: string;
|
|
147
|
+
readonly ownerSubject?: string;
|
|
145
148
|
readonly deploymentSource?: DeploymentSource;
|
|
146
149
|
readonly accessMode: AccessMode;
|
|
147
150
|
readonly deploymentLock?: DeploymentLockMetadata;
|
|
@@ -236,6 +239,7 @@ export interface DeploymentStatus {
|
|
|
236
239
|
readonly serverName: string;
|
|
237
240
|
readonly createdAt: string;
|
|
238
241
|
readonly createdByEmail?: string;
|
|
242
|
+
readonly ownerSubject?: string;
|
|
239
243
|
readonly accessMode: AccessMode;
|
|
240
244
|
readonly deploymentLock?: DeploymentLockMetadata;
|
|
241
245
|
};
|
|
@@ -252,6 +256,16 @@ export interface DeploymentActivationResult {
|
|
|
252
256
|
readonly previousActive?: DeployRecord;
|
|
253
257
|
readonly alreadyActive: boolean;
|
|
254
258
|
}
|
|
259
|
+
/** One atomic access/owner compare-and-set over the active deployment's observed state. */
|
|
260
|
+
export interface ActiveAccessUpdateInput {
|
|
261
|
+
readonly accessMode: AccessMode;
|
|
262
|
+
/** Desired owner mutation. Omission preserves the current effective owner; clearing is unsupported. */
|
|
263
|
+
readonly ownerSubject?: string;
|
|
264
|
+
readonly expectedAccessMode: AccessMode | undefined;
|
|
265
|
+
readonly expectedOwnerSubject: string | undefined;
|
|
266
|
+
/** Compiler-authoritative projection persisted atomically when enabling customer access. */
|
|
267
|
+
readonly serverAuth?: TenantAuthConfig;
|
|
268
|
+
}
|
|
255
269
|
export type DeploymentLockUpdateResult = {
|
|
256
270
|
readonly ok: true;
|
|
257
271
|
readonly record: DeployRecord;
|
|
@@ -263,9 +277,10 @@ export type DeploymentLockUpdateResult = {
|
|
|
263
277
|
export interface ControlPlaneStore extends OrganizationStore {
|
|
264
278
|
}
|
|
265
279
|
/**
|
|
266
|
-
* Durable storage for deployed-server records. `append` writes (or replaces) one server's
|
|
267
|
-
*
|
|
268
|
-
*
|
|
280
|
+
* Durable storage for deployed-server records. `append` writes (or replaces) one server's immutable deploy
|
|
281
|
+
* inputs while preserving owner state changed through {@link updateActiveAccess}; `loadAll` returns every
|
|
282
|
+
* current record for restart recovery. Historical records are retained so a tenant environment can reactivate
|
|
283
|
+
* an earlier deployment without changing the tenant-facing URL.
|
|
269
284
|
*/
|
|
270
285
|
export interface ArtifactStore {
|
|
271
286
|
append(record: DeployRecord): Promise<void>;
|
|
@@ -294,14 +309,10 @@ export interface ArtifactStore {
|
|
|
294
309
|
readonly automationId?: string;
|
|
295
310
|
}): Promise<DeploymentActivationResult | undefined>;
|
|
296
311
|
/**
|
|
297
|
-
* Compare and set the active record's access mode. The precondition is the raw
|
|
298
|
-
*
|
|
312
|
+
* Compare and set the active record's access mode and effective owner. The access precondition is the raw
|
|
313
|
+
* persisted value; the owner precondition resolves legacy records through creator provenance.
|
|
299
314
|
*/
|
|
300
|
-
updateActiveAccess(ref: TenantRef, deploymentId: string,
|
|
301
|
-
readonly expectedAccessMode: AccessMode | undefined;
|
|
302
|
-
/** Compiler-authoritative projection persisted atomically when enabling customer access. */
|
|
303
|
-
readonly serverAuth?: TenantAuthConfig;
|
|
304
|
-
}): Promise<DeployRecord | undefined>;
|
|
315
|
+
updateActiveAccess(ref: TenantRef, deploymentId: string, input: ActiveAccessUpdateInput): Promise<DeployRecord | undefined>;
|
|
305
316
|
listDeployments(filter: DeploymentListFilter): Promise<readonly DeploymentSummary[]>;
|
|
306
317
|
/**
|
|
307
318
|
* App soft delete (ADR 0117). `getAppArchivedAt` reports the app's archived stamp (defined iff the
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"./main": {
|
|
21
21
|
"types": "./dist/main.d.ts",
|
|
22
22
|
"import": "./dist/main.js"
|
|
23
|
+
},
|
|
24
|
+
"./oauth-google": {
|
|
25
|
+
"types": "./dist/oauth/google.d.ts",
|
|
26
|
+
"import": "./dist/oauth/google.js"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"bin": {
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
"dependencies": {
|
|
36
40
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
37
41
|
"@noodle-borg/admission-limits": "0.0.0",
|
|
38
|
-
"@noodle-borg/agent-kit": "0.
|
|
42
|
+
"@noodle-borg/agent-kit": "0.82.0",
|
|
39
43
|
"@noodle-borg/app-package": "0.0.0",
|
|
40
44
|
"@noodle-borg/assistant-gateway": "0.0.0",
|
|
41
45
|
"@noodle-borg/auth": "0.0.0",
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** Strict service-output contracts for control-plane reads and mutations (ADR 0128). */
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
/** Exact OAuth subject bound by an operator to an owner-only deployment. */
|
|
4
|
+
export declare const deploymentOwnerSubjectSchema: z.ZodString;
|
|
3
5
|
export declare const accessUpdateRequestSchema: z.ZodObject<{
|
|
4
6
|
accessMode: z.ZodEnum<{
|
|
5
7
|
"owner-only": "owner-only";
|
|
@@ -9,8 +11,118 @@ export declare const accessUpdateRequestSchema: z.ZodObject<{
|
|
|
9
11
|
mixed: "mixed";
|
|
10
12
|
customers: "customers";
|
|
11
13
|
}>;
|
|
14
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
12
15
|
serverVersion: z.ZodOptional<z.ZodString>;
|
|
13
16
|
}, z.core.$strict>;
|
|
17
|
+
export declare const accessUpdateResponseSchema: z.ZodObject<{
|
|
18
|
+
ok: z.ZodLiteral<true>;
|
|
19
|
+
target: z.ZodObject<{
|
|
20
|
+
org: z.ZodString;
|
|
21
|
+
app: z.ZodString;
|
|
22
|
+
env: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
deployment: z.ZodObject<{
|
|
25
|
+
deploymentId: z.ZodString;
|
|
26
|
+
serverVersion: z.ZodOptional<z.ZodString>;
|
|
27
|
+
accessMode: z.ZodEnum<{
|
|
28
|
+
"owner-only": "owner-only";
|
|
29
|
+
"org-members": "org-members";
|
|
30
|
+
authenticated: "authenticated";
|
|
31
|
+
public: "public";
|
|
32
|
+
mixed: "mixed";
|
|
33
|
+
customers: "customers";
|
|
34
|
+
}>;
|
|
35
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strict>;
|
|
37
|
+
previousAccessMode: z.ZodEnum<{
|
|
38
|
+
"owner-only": "owner-only";
|
|
39
|
+
"org-members": "org-members";
|
|
40
|
+
authenticated: "authenticated";
|
|
41
|
+
public: "public";
|
|
42
|
+
mixed: "mixed";
|
|
43
|
+
customers: "customers";
|
|
44
|
+
}>;
|
|
45
|
+
previousOwnerSubject: z.ZodOptional<z.ZodString>;
|
|
46
|
+
accessChanged: z.ZodBoolean;
|
|
47
|
+
ownerChanged: z.ZodBoolean;
|
|
48
|
+
changed: z.ZodBoolean;
|
|
49
|
+
}, z.core.$strict>;
|
|
50
|
+
export type AccessUpdateResponse = z.output<typeof accessUpdateResponseSchema>;
|
|
51
|
+
/**
|
|
52
|
+
* Additive client reader for the access mutation response. Older services emitted only the aggregate
|
|
53
|
+
* `changed` bit, so the mode component is derived from the authoritative previous/current modes while an
|
|
54
|
+
* unobservable owner component remains omitted. Modern component bits retain the strict cross-field check.
|
|
55
|
+
*/
|
|
56
|
+
export declare const accessUpdateClientResponseSchema: z.ZodPipe<z.ZodObject<{
|
|
57
|
+
ok: z.ZodLiteral<true>;
|
|
58
|
+
target: z.ZodObject<{
|
|
59
|
+
org: z.ZodString;
|
|
60
|
+
app: z.ZodString;
|
|
61
|
+
env: z.ZodString;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
deployment: z.ZodObject<{
|
|
64
|
+
deploymentId: z.ZodString;
|
|
65
|
+
serverVersion: z.ZodOptional<z.ZodString>;
|
|
66
|
+
accessMode: z.ZodEnum<{
|
|
67
|
+
"owner-only": "owner-only";
|
|
68
|
+
"org-members": "org-members";
|
|
69
|
+
authenticated: "authenticated";
|
|
70
|
+
public: "public";
|
|
71
|
+
mixed: "mixed";
|
|
72
|
+
customers: "customers";
|
|
73
|
+
}>;
|
|
74
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
75
|
+
}, z.core.$strip>;
|
|
76
|
+
previousAccessMode: z.ZodEnum<{
|
|
77
|
+
"owner-only": "owner-only";
|
|
78
|
+
"org-members": "org-members";
|
|
79
|
+
authenticated: "authenticated";
|
|
80
|
+
public: "public";
|
|
81
|
+
mixed: "mixed";
|
|
82
|
+
customers: "customers";
|
|
83
|
+
}>;
|
|
84
|
+
previousOwnerSubject: z.ZodOptional<z.ZodString>;
|
|
85
|
+
accessChanged: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
ownerChanged: z.ZodOptional<z.ZodBoolean>;
|
|
87
|
+
changed: z.ZodBoolean;
|
|
88
|
+
}, z.core.$strip>, z.ZodTransform<{
|
|
89
|
+
accessChanged: boolean;
|
|
90
|
+
ok: true;
|
|
91
|
+
target: {
|
|
92
|
+
org: string;
|
|
93
|
+
app: string;
|
|
94
|
+
env: string;
|
|
95
|
+
};
|
|
96
|
+
deployment: {
|
|
97
|
+
deploymentId: string;
|
|
98
|
+
accessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
99
|
+
serverVersion?: string | undefined;
|
|
100
|
+
ownerSubject?: string | undefined;
|
|
101
|
+
};
|
|
102
|
+
previousAccessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
103
|
+
changed: boolean;
|
|
104
|
+
previousOwnerSubject?: string | undefined;
|
|
105
|
+
ownerChanged?: boolean | undefined;
|
|
106
|
+
}, {
|
|
107
|
+
ok: true;
|
|
108
|
+
target: {
|
|
109
|
+
org: string;
|
|
110
|
+
app: string;
|
|
111
|
+
env: string;
|
|
112
|
+
};
|
|
113
|
+
deployment: {
|
|
114
|
+
deploymentId: string;
|
|
115
|
+
accessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
116
|
+
serverVersion?: string | undefined;
|
|
117
|
+
ownerSubject?: string | undefined;
|
|
118
|
+
};
|
|
119
|
+
previousAccessMode: "owner-only" | "org-members" | "authenticated" | "public" | "mixed" | "customers";
|
|
120
|
+
changed: boolean;
|
|
121
|
+
previousOwnerSubject?: string | undefined;
|
|
122
|
+
accessChanged?: boolean | undefined;
|
|
123
|
+
ownerChanged?: boolean | undefined;
|
|
124
|
+
}>>;
|
|
125
|
+
export type AccessUpdateClientResponse = z.output<typeof accessUpdateClientResponseSchema>;
|
|
14
126
|
export declare const deploymentLockRequestSchema: z.ZodObject<{
|
|
15
127
|
serverVersion: z.ZodString;
|
|
16
128
|
expectedDeploymentId: z.ZodString;
|
|
@@ -27,6 +139,7 @@ export declare const DeploymentSummarySchema: z.ZodObject<{
|
|
|
27
139
|
serverName: z.ZodString;
|
|
28
140
|
createdAt: z.ZodString;
|
|
29
141
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
142
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
30
143
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
31
144
|
accessMode: z.ZodEnum<{
|
|
32
145
|
"owner-only": "owner-only";
|
|
@@ -66,6 +179,7 @@ export declare const AppSummarySchema: z.ZodObject<{
|
|
|
66
179
|
serverName: z.ZodString;
|
|
67
180
|
createdAt: z.ZodString;
|
|
68
181
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
182
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
69
183
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
70
184
|
accessMode: z.ZodEnum<{
|
|
71
185
|
"owner-only": "owner-only";
|
|
@@ -107,6 +221,7 @@ export declare const AppsListResponseSchema: z.ZodObject<{
|
|
|
107
221
|
serverName: z.ZodString;
|
|
108
222
|
createdAt: z.ZodString;
|
|
109
223
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
224
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
110
225
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
111
226
|
accessMode: z.ZodEnum<{
|
|
112
227
|
"owner-only": "owner-only";
|
|
@@ -150,6 +265,7 @@ export declare const AppResponseSchema: z.ZodObject<{
|
|
|
150
265
|
serverName: z.ZodString;
|
|
151
266
|
createdAt: z.ZodString;
|
|
152
267
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
268
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
153
269
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
154
270
|
accessMode: z.ZodEnum<{
|
|
155
271
|
"owner-only": "owner-only";
|
|
@@ -190,6 +306,7 @@ export declare const EnvSummarySchema: z.ZodObject<{
|
|
|
190
306
|
serverName: z.ZodString;
|
|
191
307
|
createdAt: z.ZodString;
|
|
192
308
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
309
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
193
310
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
194
311
|
accessMode: z.ZodEnum<{
|
|
195
312
|
"owner-only": "owner-only";
|
|
@@ -233,6 +350,7 @@ export declare const EnvsListResponseSchema: z.ZodObject<{
|
|
|
233
350
|
serverName: z.ZodString;
|
|
234
351
|
createdAt: z.ZodString;
|
|
235
352
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
353
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
236
354
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
237
355
|
accessMode: z.ZodEnum<{
|
|
238
356
|
"owner-only": "owner-only";
|
|
@@ -277,6 +395,7 @@ export declare const EnvResponseSchema: z.ZodObject<{
|
|
|
277
395
|
serverName: z.ZodString;
|
|
278
396
|
createdAt: z.ZodString;
|
|
279
397
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
398
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
280
399
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
281
400
|
accessMode: z.ZodEnum<{
|
|
282
401
|
"owner-only": "owner-only";
|
|
@@ -358,6 +477,7 @@ export declare const DeploymentResponseSchema: z.ZodObject<{
|
|
|
358
477
|
serverName: z.ZodString;
|
|
359
478
|
createdAt: z.ZodString;
|
|
360
479
|
createdByEmail: z.ZodOptional<z.ZodString>;
|
|
480
|
+
ownerSubject: z.ZodOptional<z.ZodString>;
|
|
361
481
|
deploymentSource: z.ZodOptional<z.ZodString>;
|
|
362
482
|
accessMode: z.ZodEnum<{
|
|
363
483
|
"owner-only": "owner-only";
|