@serve.zone/interfaces 11.2.0 → 11.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +22 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/deployment.d.ts +6 -0
- package/dist_ts/data/deploymentpreflight.d.ts +142 -0
- package/dist_ts/data/deploymentpreflight.js +93 -0
- package/dist_ts/data/image.d.ts +4 -2
- package/dist_ts/data/immutableimage.d.ts +145 -0
- package/dist_ts/data/immutableimage.js +146 -0
- package/dist_ts/data/index.d.ts +2 -0
- package/dist_ts/data/index.js +3 -1
- package/dist_ts/data/registry.d.ts +22 -0
- package/dist_ts/data/service.d.ts +9 -0
- package/dist_ts/data/user.d.ts +11 -0
- package/dist_ts/requests/deployment.d.ts +3 -0
- package/dist_ts/requests/service.d.ts +54 -2
- package/package.json +1 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/deployment.ts +8 -0
- package/ts/data/deploymentpreflight.ts +297 -0
- package/ts/data/image.ts +4 -2
- package/ts/data/immutableimage.ts +373 -0
- package/ts/data/index.ts +2 -0
- package/ts/data/registry.ts +27 -0
- package/ts/data/service.ts +16 -0
- package/ts/data/user.ts +17 -0
- package/ts/requests/deployment.ts +3 -0
- package/ts/requests/service.ts +77 -2
package/changelog.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-07-19 - 11.4.0
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- define least-privilege greenfield deployment preflight contracts (deployment)
|
|
8
|
+
- Add server-persisted, service-scoped machine capabilities without broad cluster authority.
|
|
9
|
+
- Define sanitized GO/NO-GO inventory for OCI indexes, runtime digests, Corestore bindings, and namespace collisions.
|
|
10
|
+
- Bind release evidence and future durable operations to source, version, image, configuration, and namespace digests.
|
|
11
|
+
|
|
12
|
+
### Maintenance
|
|
13
|
+
|
|
14
|
+
- replace the broken pnpm 11.13.0 executable pin with pnpm 11.15.0.
|
|
15
|
+
|
|
16
|
+
## 2026-07-18 - 11.3.0
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
- define fail-closed immutable image deployment and runtime evidence contracts (deployment)
|
|
21
|
+
- Separate observed registry releases, accepted digest rollouts, and exact-digest rollback plans.
|
|
22
|
+
- Require task-derived Docker runtime evidence and complete healthy replica reports before rollout success.
|
|
23
|
+
- Add idempotent promotion, compare-and-swap rollback, capability, ordering, and mismatch contracts.
|
|
24
|
+
|
|
3
25
|
## 2026-07-15 - 11.2.0
|
|
4
26
|
|
|
5
27
|
### Features
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/interfaces',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.4.0',
|
|
7
7
|
description: 'Shared TypeScript interfaces and TypedRequest contracts for the serve.zone ecosystem.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHVGQUF1RjtDQUNyRyxDQUFBIn0=
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IRuntimeImageEvidence } from './immutableimage.js';
|
|
1
2
|
/**
|
|
2
3
|
* a deployment happens when a service is deployed
|
|
3
4
|
* tracks the status of a deployment
|
|
@@ -28,6 +29,11 @@ export interface IDeployment {
|
|
|
28
29
|
slot?: number;
|
|
29
30
|
/** Docker desired state for this task/deployment. */
|
|
30
31
|
desiredState?: string;
|
|
32
|
+
/** Immutable rollout generation represented by this task, when applicable. */
|
|
33
|
+
rolloutId?: string;
|
|
34
|
+
rolloutGeneration?: number;
|
|
35
|
+
/** Evidence derived from Docker runtime state rather than service intent metadata. */
|
|
36
|
+
runtimeImageEvidence?: IRuntimeImageEvidence;
|
|
31
37
|
/**
|
|
32
38
|
* Image used for this deployment
|
|
33
39
|
*/
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import type { TOciManifestMediaType, TSha256Digest } from './immutableimage.js';
|
|
2
|
+
import type { TServiceDeploymentCapability } from './user.js';
|
|
3
|
+
export type TDeploymentPreflightDecision = 'GO' | 'NO-GO';
|
|
4
|
+
export type TDeploymentPreflightBlockerCode = 'INVALID_REQUEST' | 'AUTHORIZATION_MISSING' | 'SOURCE_REVISION_INVALID' | 'VERSION_NOT_RESERVED' | 'VERSION_COLLISION' | 'NAMESPACE_NOT_RESERVED' | 'NAMESPACE_COLLISION' | 'NAMESPACE_NOT_PROVEN_BLANK' | 'CONFIGURATION_DIGEST_INVALID' | 'CURRENT_REFERENCE_MUTABLE' | 'CURRENT_RUNTIME_DIGEST_MISSING' | 'OCI_INDEX_DIGEST_REQUIRED' | 'OCI_INDEX_NOT_FOUND' | 'OCI_INDEX_MEDIA_TYPE_REQUIRED' | 'OCI_PLATFORM_MISSING' | 'OCI_PLATFORM_MANIFEST_MISSING' | 'IMMUTABLE_RELEASE_TAG_REQUIRED' | 'IMMUTABLE_RELEASE_TAG_NOT_RESERVED' | 'RELEASE_EVIDENCE_MISSING' | 'RELEASE_EVIDENCE_INVALID' | 'RELEASE_NOT_AUTHORIZED' | 'GREENFIELD_EXECUTION_UNAVAILABLE' | 'ROUTE_PROMOTION_FENCE_UNAVAILABLE' | 'POST_DEPLOYMENT_VERIFICATION_UNAVAILABLE' | 'WOULD_REPLACE_EXISTING_STATE' | 'CORESTORE_INVENTORY_UNAVAILABLE' | 'RUNTIME_ATTESTATION_MISMATCH';
|
|
5
|
+
export interface IDeploymentPreflightBlocker {
|
|
6
|
+
code: TDeploymentPreflightBlockerCode;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
export interface IDeploymentPreflightAuthorizationCheck {
|
|
10
|
+
capability: TServiceDeploymentCapability;
|
|
11
|
+
granted: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface IOciPlatformDescriptorSummary {
|
|
14
|
+
os: string;
|
|
15
|
+
architecture: string;
|
|
16
|
+
digest?: TSha256Digest;
|
|
17
|
+
mediaType?: string;
|
|
18
|
+
runnable: boolean;
|
|
19
|
+
manifestPresent: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface IDeploymentPreflightRuntimeTask {
|
|
22
|
+
deploymentId: string;
|
|
23
|
+
nodeName?: string;
|
|
24
|
+
status: string;
|
|
25
|
+
healthStatus?: string;
|
|
26
|
+
imageReference?: string;
|
|
27
|
+
reportedDigest?: TSha256Digest;
|
|
28
|
+
verificationStatus?: 'not-required' | 'pending' | 'verified' | 'missing' | 'mismatched';
|
|
29
|
+
}
|
|
30
|
+
export interface IDeploymentPreflightPlatformBinding {
|
|
31
|
+
capability: 'database' | 'objectstorage';
|
|
32
|
+
desiredState: 'enabled' | 'disabled';
|
|
33
|
+
status: 'requested' | 'provisioning' | 'ready' | 'degraded' | 'failed' | 'disabled';
|
|
34
|
+
}
|
|
35
|
+
export interface IDeploymentPreflightCorestoreResource {
|
|
36
|
+
capability: 'database' | 'objectstorage';
|
|
37
|
+
provider: string;
|
|
38
|
+
resourceName: string;
|
|
39
|
+
}
|
|
40
|
+
export interface IDeploymentReleaseEvidenceReference {
|
|
41
|
+
kind: 'provenance' | 'sbom' | 'signature' | 'vulnerability-policy' | 'release-authorization';
|
|
42
|
+
statementDigest: TSha256Digest;
|
|
43
|
+
subjectDigest: TSha256Digest;
|
|
44
|
+
verifier: string;
|
|
45
|
+
verifiedAt: number;
|
|
46
|
+
}
|
|
47
|
+
/** Evidence is descriptive input until a trusted Cloudly verifier validates it. */
|
|
48
|
+
export interface IDeploymentReleaseEvidence {
|
|
49
|
+
sourceRevision: string;
|
|
50
|
+
version: string;
|
|
51
|
+
configurationDigest: TSha256Digest;
|
|
52
|
+
ociIndexDigest: TSha256Digest;
|
|
53
|
+
releaseAuthorized: boolean;
|
|
54
|
+
attestations: IDeploymentReleaseEvidenceReference[];
|
|
55
|
+
}
|
|
56
|
+
export interface IDeploymentPreflightRequestData {
|
|
57
|
+
requestId: string;
|
|
58
|
+
serviceId: string;
|
|
59
|
+
sourceRevision: string;
|
|
60
|
+
version: string;
|
|
61
|
+
configurationDigest: string;
|
|
62
|
+
proposedNamespace: string;
|
|
63
|
+
ociIndexDigest?: string;
|
|
64
|
+
releaseTag?: string;
|
|
65
|
+
releaseEvidence?: IDeploymentReleaseEvidence;
|
|
66
|
+
greenfield: true;
|
|
67
|
+
}
|
|
68
|
+
export interface IDeploymentPreflightReport {
|
|
69
|
+
schemaVersion: 1;
|
|
70
|
+
decision: TDeploymentPreflightDecision;
|
|
71
|
+
mutationPerformed: false;
|
|
72
|
+
generatedAt: number;
|
|
73
|
+
service: {
|
|
74
|
+
serviceId: string;
|
|
75
|
+
serviceName: string;
|
|
76
|
+
workspaceIdentity: string;
|
|
77
|
+
registryRepository: string;
|
|
78
|
+
deployOnPush: boolean;
|
|
79
|
+
};
|
|
80
|
+
source: {
|
|
81
|
+
revision: string;
|
|
82
|
+
version: string;
|
|
83
|
+
configurationDigest?: TSha256Digest;
|
|
84
|
+
};
|
|
85
|
+
currentImage: {
|
|
86
|
+
tag?: string;
|
|
87
|
+
digest?: TSha256Digest;
|
|
88
|
+
imageReference?: string;
|
|
89
|
+
mutableReference: boolean;
|
|
90
|
+
mediaType?: TOciManifestMediaType;
|
|
91
|
+
platforms: IOciPlatformDescriptorSummary[];
|
|
92
|
+
};
|
|
93
|
+
requestedImage: {
|
|
94
|
+
digest?: TSha256Digest;
|
|
95
|
+
releaseTag?: string;
|
|
96
|
+
tagReserved: boolean;
|
|
97
|
+
mediaType?: TOciManifestMediaType;
|
|
98
|
+
platforms: IOciPlatformDescriptorSummary[];
|
|
99
|
+
};
|
|
100
|
+
runtimeTasks: IDeploymentPreflightRuntimeTask[];
|
|
101
|
+
platformBindings: IDeploymentPreflightPlatformBinding[];
|
|
102
|
+
corestoreResources: IDeploymentPreflightCorestoreResource[];
|
|
103
|
+
proposed: {
|
|
104
|
+
namespace: string;
|
|
105
|
+
namespaceReserved: boolean;
|
|
106
|
+
namespaceBlank: boolean;
|
|
107
|
+
versionReserved: boolean;
|
|
108
|
+
wouldReplaceExistingState: boolean;
|
|
109
|
+
};
|
|
110
|
+
authorizationChecks: IDeploymentPreflightAuthorizationCheck[];
|
|
111
|
+
compatibilityBlockers: IDeploymentPreflightBlocker[];
|
|
112
|
+
}
|
|
113
|
+
export interface IGreenfieldDeploymentFence {
|
|
114
|
+
sourceServiceId: string;
|
|
115
|
+
sourceRevision: string;
|
|
116
|
+
version: string;
|
|
117
|
+
ociIndexDigest: TSha256Digest;
|
|
118
|
+
configurationDigest: TSha256Digest;
|
|
119
|
+
targetNamespace: string;
|
|
120
|
+
}
|
|
121
|
+
export interface IGreenfieldDeploymentOperation {
|
|
122
|
+
id: string;
|
|
123
|
+
data: {
|
|
124
|
+
idempotencyKey: string;
|
|
125
|
+
requestDigest: TSha256Digest;
|
|
126
|
+
fence: IGreenfieldDeploymentFence;
|
|
127
|
+
candidateServiceId?: string;
|
|
128
|
+
state: 'reserved' | 'provisioning' | 'deploying' | 'verifying' | 'ready-for-promotion' | 'promoting' | 'promoted' | 'rolling-back' | 'rolled-back' | 'failed';
|
|
129
|
+
routeGeneration?: number;
|
|
130
|
+
createdAt: number;
|
|
131
|
+
updatedAt: number;
|
|
132
|
+
failureCode?: string;
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
export declare const validateDeploymentPreflightRequest: (requestArg: unknown) => IDeploymentPreflightBlocker[];
|
|
136
|
+
export declare const validateDeploymentReleaseEvidence: (argsArg: {
|
|
137
|
+
evidence: unknown;
|
|
138
|
+
sourceRevision: string;
|
|
139
|
+
version: string;
|
|
140
|
+
configurationDigest: TSha256Digest;
|
|
141
|
+
ociIndexDigest: TSha256Digest;
|
|
142
|
+
}) => IDeploymentPreflightBlocker[];
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { normalizeSha256Digest } from './immutableimage.js';
|
|
2
|
+
const fullGitRevisionRegex = /^[a-f0-9]{40}$/;
|
|
3
|
+
const namespaceRegex = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
4
|
+
const requiredEvidenceKinds = new Set([
|
|
5
|
+
'provenance',
|
|
6
|
+
'sbom',
|
|
7
|
+
'signature',
|
|
8
|
+
'vulnerability-policy',
|
|
9
|
+
'release-authorization',
|
|
10
|
+
]);
|
|
11
|
+
const isRecord = (valueArg) => Boolean(valueArg) && typeof valueArg === 'object' && !Array.isArray(valueArg);
|
|
12
|
+
export const validateDeploymentPreflightRequest = (requestArg) => {
|
|
13
|
+
const blockers = [];
|
|
14
|
+
if (!isRecord(requestArg)) {
|
|
15
|
+
return [{ code: 'INVALID_REQUEST', message: 'Deployment preflight request must be an object.' }];
|
|
16
|
+
}
|
|
17
|
+
if (typeof requestArg.requestId !== 'string' || !requestArg.requestId.trim() || requestArg.requestId.length > 200) {
|
|
18
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'A bounded request identifier is required.' });
|
|
19
|
+
}
|
|
20
|
+
if (typeof requestArg.serviceId !== 'string' || !requestArg.serviceId.trim() || requestArg.serviceId.length > 200) {
|
|
21
|
+
blockers.push({ code: 'INVALID_REQUEST', message: 'A bounded service identifier is required.' });
|
|
22
|
+
}
|
|
23
|
+
if (typeof requestArg.sourceRevision !== 'string' || !fullGitRevisionRegex.test(requestArg.sourceRevision)) {
|
|
24
|
+
blockers.push({ code: 'SOURCE_REVISION_INVALID', message: 'Source revision must be a full lower-case Git commit SHA.' });
|
|
25
|
+
}
|
|
26
|
+
if (typeof requestArg.version !== 'string' || !requestArg.version.trim() || requestArg.version.length > 100) {
|
|
27
|
+
blockers.push({ code: 'VERSION_NOT_RESERVED', message: 'A bounded release version is required.' });
|
|
28
|
+
}
|
|
29
|
+
if (typeof requestArg.proposedNamespace !== 'string' || !namespaceRegex.test(requestArg.proposedNamespace)) {
|
|
30
|
+
blockers.push({ code: 'NAMESPACE_NOT_RESERVED', message: 'The proposed namespace is missing or malformed.' });
|
|
31
|
+
}
|
|
32
|
+
if (typeof requestArg.configurationDigest !== 'string' || !normalizeSha256Digest(requestArg.configurationDigest)) {
|
|
33
|
+
blockers.push({ code: 'CONFIGURATION_DIGEST_INVALID', message: 'Configuration digest must be a canonical sha256 digest.' });
|
|
34
|
+
}
|
|
35
|
+
if (requestArg.ociIndexDigest !== undefined
|
|
36
|
+
&& (typeof requestArg.ociIndexDigest !== 'string' || !normalizeSha256Digest(requestArg.ociIndexDigest))) {
|
|
37
|
+
blockers.push({ code: 'OCI_INDEX_DIGEST_REQUIRED', message: 'OCI index digest must be a canonical sha256 digest.' });
|
|
38
|
+
}
|
|
39
|
+
if (requestArg.greenfield !== true) {
|
|
40
|
+
blockers.push({ code: 'WOULD_REPLACE_EXISTING_STATE', message: 'Only greenfield deployment preflight is supported.' });
|
|
41
|
+
}
|
|
42
|
+
return blockers;
|
|
43
|
+
};
|
|
44
|
+
export const validateDeploymentReleaseEvidence = (argsArg) => {
|
|
45
|
+
const blockers = [];
|
|
46
|
+
if (!isRecord(argsArg.evidence)) {
|
|
47
|
+
return [{ code: 'RELEASE_EVIDENCE_INVALID', message: 'Release evidence must be an object.' }];
|
|
48
|
+
}
|
|
49
|
+
const evidence = argsArg.evidence;
|
|
50
|
+
if (evidence.releaseAuthorized !== true) {
|
|
51
|
+
blockers.push({ code: 'RELEASE_NOT_AUTHORIZED', message: 'Release authorization evidence is explicitly false.' });
|
|
52
|
+
}
|
|
53
|
+
if (evidence.sourceRevision !== argsArg.sourceRevision
|
|
54
|
+
|| evidence.version !== argsArg.version
|
|
55
|
+
|| evidence.configurationDigest !== argsArg.configurationDigest
|
|
56
|
+
|| evidence.ociIndexDigest !== argsArg.ociIndexDigest) {
|
|
57
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_INVALID', message: 'Release evidence is not bound to the requested deployment fence.' });
|
|
58
|
+
}
|
|
59
|
+
const seenKinds = new Set();
|
|
60
|
+
const attestations = Array.isArray(evidence.attestations) ? evidence.attestations : [];
|
|
61
|
+
if (!Array.isArray(evidence.attestations)) {
|
|
62
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_INVALID', message: 'Release attestations must be an array.' });
|
|
63
|
+
}
|
|
64
|
+
for (const attestation of attestations) {
|
|
65
|
+
if (!isRecord(attestation)) {
|
|
66
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_INVALID', message: 'Release attestation must be an object.' });
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const kind = attestation.kind;
|
|
70
|
+
if (typeof kind !== 'string' || !requiredEvidenceKinds.has(kind)) {
|
|
71
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_INVALID', message: 'Release attestation kind is invalid.' });
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
seenKinds.add(kind);
|
|
75
|
+
if (attestation.subjectDigest !== argsArg.ociIndexDigest
|
|
76
|
+
|| typeof attestation.statementDigest !== 'string'
|
|
77
|
+
|| !normalizeSha256Digest(attestation.statementDigest)
|
|
78
|
+
|| typeof attestation.verifier !== 'string'
|
|
79
|
+
|| !attestation.verifier.trim()
|
|
80
|
+
|| typeof attestation.verifiedAt !== 'number'
|
|
81
|
+
|| !Number.isSafeInteger(attestation.verifiedAt)
|
|
82
|
+
|| attestation.verifiedAt < 1) {
|
|
83
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_INVALID', message: `Invalid ${kind} evidence.` });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const requiredKind of requiredEvidenceKinds) {
|
|
87
|
+
if (!seenKinds.has(requiredKind)) {
|
|
88
|
+
blockers.push({ code: 'RELEASE_EVIDENCE_MISSING', message: `Missing ${requiredKind} evidence.` });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return blockers;
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95bWVudHByZWZsaWdodC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2RhdGEvZGVwbG95bWVudHByZWZsaWdodC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQTBMNUQsTUFBTSxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQztBQUM5QyxNQUFNLGNBQWMsR0FBRyx3Q0FBd0MsQ0FBQztBQUNoRSxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxDQUE4QztJQUNqRixZQUFZO0lBQ1osTUFBTTtJQUNOLFdBQVc7SUFDWCxzQkFBc0I7SUFDdEIsdUJBQXVCO0NBQ3hCLENBQUMsQ0FBQztBQUVILE1BQU0sUUFBUSxHQUFHLENBQUMsUUFBaUIsRUFBdUMsRUFBRSxDQUMxRSxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVoRixNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxDQUNoRCxVQUFtQixFQUNZLEVBQUU7SUFDakMsTUFBTSxRQUFRLEdBQWtDLEVBQUUsQ0FBQztJQUNuRCxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFDMUIsT0FBTyxDQUFDLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sRUFBRSxpREFBaUQsRUFBRSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUNELElBQUksT0FBTyxVQUFVLENBQUMsU0FBUyxLQUFLLFFBQVEsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksVUFBVSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDbEgsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxP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
|
package/dist_ts/data/image.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IRegistryPushEvent } from './registry.js';
|
|
1
|
+
import type { IImmutableRegistryPushEvent, IRegistryPushEvent } from './registry.js';
|
|
2
2
|
export interface IImage {
|
|
3
3
|
id: string;
|
|
4
4
|
data: {
|
|
@@ -13,6 +13,8 @@ export interface IImage {
|
|
|
13
13
|
versions: Array<{
|
|
14
14
|
versionString: string;
|
|
15
15
|
digest?: string;
|
|
16
|
+
releaseId?: string;
|
|
17
|
+
manifestMediaType?: string;
|
|
16
18
|
registryRepository?: string;
|
|
17
19
|
registryTag?: string;
|
|
18
20
|
source?: 'upload' | 'registry';
|
|
@@ -20,6 +22,6 @@ export interface IImage {
|
|
|
20
22
|
size: number;
|
|
21
23
|
createdAt: number;
|
|
22
24
|
}>;
|
|
23
|
-
lastPushEvent?: IRegistryPushEvent;
|
|
25
|
+
lastPushEvent?: IRegistryPushEvent | IImmutableRegistryPushEvent;
|
|
24
26
|
};
|
|
25
27
|
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/** Canonical lower-case OCI sha256 digest. */
|
|
2
|
+
export type TSha256Digest = `sha256:${string}`;
|
|
3
|
+
export type TImageDeploymentPolicy = 'legacy-tag' | 'immutable-digest';
|
|
4
|
+
export type TOciManifestMediaType = 'application/vnd.oci.image.index.v1+json' | 'application/vnd.oci.image.manifest.v1+json' | 'application/vnd.docker.distribution.manifest.list.v2+json' | 'application/vnd.docker.distribution.manifest.v2+json';
|
|
5
|
+
export type TImmutableImageRolloutMode = 'promotion' | 'automatic' | 'rollback';
|
|
6
|
+
export type TImmutableImageMismatchReason = 'immutable-plan-missing' | 'requested-digest-missing' | 'requested-digest-malformed' | 'registry-digest-inconsistent' | 'runtime-capability-missing' | 'pull-failed' | 'pulled-digest-missing' | 'pulled-digest-mismatch' | 'service-image-not-digest-pinned' | 'service-image-digest-mismatch' | 'task-image-not-digest-pinned' | 'task-image-digest-mismatch' | 'container-inspection-unavailable' | 'container-image-id-missing' | 'container-repodigest-missing' | 'container-repodigest-mismatch' | 'runtime-attestation-missing' | 'required-replica-missing' | 'replica-unhealthy' | 'replica-failed' | 'stale-rollout-report' | 'rollback-target-not-accepted';
|
|
7
|
+
export type TRuntimeImageVerificationStatus = 'not-required' | 'pending' | 'verified' | 'missing' | 'mismatched';
|
|
8
|
+
export type TImmutableImageRolloutStatus = 'pending' | 'deploying' | 'verifying' | 'succeeded' | 'failed' | 'mismatched' | 'rolling-back' | 'rolled-back';
|
|
9
|
+
export interface ICoreflowRuntimeCapabilities {
|
|
10
|
+
immutableImageDeploymentVersion: 1;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* A registry manifest observed by Cloudly. Observation alone does not make the
|
|
14
|
+
* release deployable: acceptedAt is set only by an explicit promotion or a
|
|
15
|
+
* configured automatic promotion.
|
|
16
|
+
*/
|
|
17
|
+
export interface IImageRelease {
|
|
18
|
+
id: string;
|
|
19
|
+
data: {
|
|
20
|
+
serviceId: string;
|
|
21
|
+
imageId: string;
|
|
22
|
+
registryHost: string;
|
|
23
|
+
repository: string;
|
|
24
|
+
/** Digest of the registry root descriptor, preserving an index/list when submitted. */
|
|
25
|
+
registryRootDigest: TSha256Digest;
|
|
26
|
+
digestPinnedImageReference: string;
|
|
27
|
+
manifestMediaType: TOciManifestMediaType;
|
|
28
|
+
observedTags: string[];
|
|
29
|
+
firstObservedAt: number;
|
|
30
|
+
lastObservedAt: number;
|
|
31
|
+
observationCount: number;
|
|
32
|
+
acceptedAt?: number;
|
|
33
|
+
lastPromotedAt?: number;
|
|
34
|
+
promotionCount?: number;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export interface IImmutableImageTargetScope {
|
|
38
|
+
targetClusterIds: string[];
|
|
39
|
+
targetNodeNames: string[];
|
|
40
|
+
replicasPerNode: number;
|
|
41
|
+
requiredReplicaCount: number;
|
|
42
|
+
}
|
|
43
|
+
/** Immutable desired state issued by Cloudly and consumed by Coreflow. */
|
|
44
|
+
export interface IImmutableImageDeploymentPlan {
|
|
45
|
+
policy: 'immutable-digest';
|
|
46
|
+
rolloutId: string;
|
|
47
|
+
rolloutGeneration: number;
|
|
48
|
+
releaseId: string;
|
|
49
|
+
registryHost: string;
|
|
50
|
+
repository: string;
|
|
51
|
+
requestedDigest: TSha256Digest;
|
|
52
|
+
digestPinnedImageReference: string;
|
|
53
|
+
manifestMediaType: TOciManifestMediaType;
|
|
54
|
+
createdAt: number;
|
|
55
|
+
mode: TImmutableImageRolloutMode;
|
|
56
|
+
rollbackOfRolloutId?: string;
|
|
57
|
+
targetScope: IImmutableImageTargetScope;
|
|
58
|
+
}
|
|
59
|
+
/** Runtime evidence collected from Docker service, task, container and image state. */
|
|
60
|
+
interface IRuntimeImageEvidenceBase {
|
|
61
|
+
rolloutId?: string;
|
|
62
|
+
rolloutGeneration?: number;
|
|
63
|
+
expectedDigest?: TSha256Digest;
|
|
64
|
+
serviceImageReference?: string;
|
|
65
|
+
taskImageReference?: string;
|
|
66
|
+
taskReportedDigest?: TSha256Digest;
|
|
67
|
+
containerImageId?: string;
|
|
68
|
+
containerConfigImageReference?: string;
|
|
69
|
+
resolvedDigest?: TSha256Digest;
|
|
70
|
+
platformManifestDigest?: TSha256Digest;
|
|
71
|
+
repoDigests?: string[];
|
|
72
|
+
evidenceSource?: 'task-spec' | 'local-container-inspect';
|
|
73
|
+
observedAt: number;
|
|
74
|
+
}
|
|
75
|
+
export interface IVerifiedRuntimeImageEvidence extends IRuntimeImageEvidenceBase {
|
|
76
|
+
verificationStatus: 'verified';
|
|
77
|
+
rolloutId: string;
|
|
78
|
+
rolloutGeneration: number;
|
|
79
|
+
expectedDigest: TSha256Digest;
|
|
80
|
+
serviceImageReference: string;
|
|
81
|
+
taskImageReference: string;
|
|
82
|
+
taskReportedDigest: TSha256Digest;
|
|
83
|
+
containerImageId: string;
|
|
84
|
+
containerConfigImageReference: string;
|
|
85
|
+
resolvedDigest: TSha256Digest;
|
|
86
|
+
repoDigests: string[];
|
|
87
|
+
evidenceSource: 'local-container-inspect';
|
|
88
|
+
mismatchReason?: never;
|
|
89
|
+
}
|
|
90
|
+
export interface IUnverifiedRuntimeImageEvidence extends IRuntimeImageEvidenceBase {
|
|
91
|
+
verificationStatus: 'missing' | 'mismatched';
|
|
92
|
+
mismatchReason: TImmutableImageMismatchReason;
|
|
93
|
+
}
|
|
94
|
+
export interface IPendingRuntimeImageEvidence extends IRuntimeImageEvidenceBase {
|
|
95
|
+
verificationStatus: 'pending' | 'not-required';
|
|
96
|
+
mismatchReason?: never;
|
|
97
|
+
}
|
|
98
|
+
export type IRuntimeImageEvidence = IVerifiedRuntimeImageEvidence | IUnverifiedRuntimeImageEvidence | IPendingRuntimeImageEvidence;
|
|
99
|
+
/** Mandatory security envelope when reporting an immutable rollout. */
|
|
100
|
+
export interface IImmutableRolloutReportEnvelope {
|
|
101
|
+
rolloutId: string;
|
|
102
|
+
rolloutGeneration: number;
|
|
103
|
+
reporterSessionId: string;
|
|
104
|
+
reportSequence: number;
|
|
105
|
+
reporterCapabilities: ICoreflowRuntimeCapabilities;
|
|
106
|
+
reporterNodeIds: string[];
|
|
107
|
+
reporterNodeNames: string[];
|
|
108
|
+
}
|
|
109
|
+
export interface IImageRolloutReporterStatus {
|
|
110
|
+
reporterId: string;
|
|
111
|
+
reporterSessionId: string;
|
|
112
|
+
clusterId: string;
|
|
113
|
+
reporterNodeNames: string[];
|
|
114
|
+
rolloutId: string;
|
|
115
|
+
rolloutGeneration: number;
|
|
116
|
+
reportSequence: number;
|
|
117
|
+
reportedAt: number;
|
|
118
|
+
requiredReplicaCount: number;
|
|
119
|
+
observedReplicaCount: number;
|
|
120
|
+
healthyReplicaCount: number;
|
|
121
|
+
verifiedReplicaCount: number;
|
|
122
|
+
failedReplicaCount: number;
|
|
123
|
+
mismatchReason?: TImmutableImageMismatchReason;
|
|
124
|
+
}
|
|
125
|
+
export interface IImageRolloutStatus {
|
|
126
|
+
rolloutId: string;
|
|
127
|
+
rolloutGeneration: number;
|
|
128
|
+
expectedDigest: TSha256Digest;
|
|
129
|
+
status: TImmutableImageRolloutStatus;
|
|
130
|
+
requiredReplicaCount: number;
|
|
131
|
+
observedReplicaCount: number;
|
|
132
|
+
healthyReplicaCount: number;
|
|
133
|
+
verifiedReplicaCount: number;
|
|
134
|
+
failedReplicaCount: number;
|
|
135
|
+
mismatchReason?: TImmutableImageMismatchReason;
|
|
136
|
+
updatedAt: number;
|
|
137
|
+
reporters: IImageRolloutReporterStatus[];
|
|
138
|
+
}
|
|
139
|
+
export declare const normalizeSha256Digest: (digest: string) => TSha256Digest | undefined;
|
|
140
|
+
export declare const isSha256Digest: (digest: string) => digest is TSha256Digest;
|
|
141
|
+
export declare const buildDigestPinnedImageReference: (registryHost: string, repository: string, digest: TSha256Digest) => string;
|
|
142
|
+
export declare const getDigestFromPinnedImageReference: (imageReference: string) => TSha256Digest | undefined;
|
|
143
|
+
export declare const validateImmutableImageDeploymentPlan: (planArg: IImmutableImageDeploymentPlan) => string[];
|
|
144
|
+
export declare const validateImageRolloutStatus: (statusArg: IImageRolloutStatus) => string[];
|
|
145
|
+
export {};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const sha256DigestRegex = /^sha256:[a-f0-9]{64}$/;
|
|
2
|
+
export const normalizeSha256Digest = (digest) => {
|
|
3
|
+
const normalizedDigest = digest.trim().toLowerCase();
|
|
4
|
+
return sha256DigestRegex.test(normalizedDigest)
|
|
5
|
+
? normalizedDigest
|
|
6
|
+
: undefined;
|
|
7
|
+
};
|
|
8
|
+
export const isSha256Digest = (digest) => sha256DigestRegex.test(digest);
|
|
9
|
+
const registryHostRegex = /^(?:localhost|[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?)(?::[1-9][0-9]{0,4})?$/;
|
|
10
|
+
const repositoryRegex = /^[a-z0-9]+(?:[._-][a-z0-9]+)*(?:\/[a-z0-9]+(?:[._-][a-z0-9]+)*)*$/;
|
|
11
|
+
export const buildDigestPinnedImageReference = (registryHost, repository, digest) => {
|
|
12
|
+
if (!registryHostRegex.test(registryHost) || !repositoryRegex.test(repository)) {
|
|
13
|
+
throw new Error('registry host and repository must be canonical OCI names');
|
|
14
|
+
}
|
|
15
|
+
if (!isSha256Digest(digest)) {
|
|
16
|
+
throw new Error('digest must be a canonical sha256 digest');
|
|
17
|
+
}
|
|
18
|
+
return `${registryHost}/${repository}@${digest}`;
|
|
19
|
+
};
|
|
20
|
+
export const getDigestFromPinnedImageReference = (imageReference) => {
|
|
21
|
+
const separatorIndex = imageReference.lastIndexOf('@');
|
|
22
|
+
if (separatorIndex < 0) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return normalizeSha256Digest(imageReference.slice(separatorIndex + 1));
|
|
26
|
+
};
|
|
27
|
+
export const validateImmutableImageDeploymentPlan = (planArg) => {
|
|
28
|
+
const errors = [];
|
|
29
|
+
if (!Number.isSafeInteger(planArg.rolloutGeneration) || planArg.rolloutGeneration < 1) {
|
|
30
|
+
errors.push('rolloutGeneration must be a positive safe integer');
|
|
31
|
+
}
|
|
32
|
+
if (!Number.isSafeInteger(planArg.createdAt) || planArg.createdAt < 1) {
|
|
33
|
+
errors.push('createdAt must be a positive safe integer');
|
|
34
|
+
}
|
|
35
|
+
let expectedReference;
|
|
36
|
+
try {
|
|
37
|
+
expectedReference = buildDigestPinnedImageReference(planArg.registryHost, planArg.repository, planArg.requestedDigest);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
errors.push(error.message);
|
|
41
|
+
}
|
|
42
|
+
if (expectedReference && planArg.digestPinnedImageReference !== expectedReference) {
|
|
43
|
+
errors.push('digestPinnedImageReference does not match registry, repository and digest');
|
|
44
|
+
}
|
|
45
|
+
const scope = planArg.targetScope;
|
|
46
|
+
if (!Number.isSafeInteger(scope.replicasPerNode) || scope.replicasPerNode < 1) {
|
|
47
|
+
errors.push('replicasPerNode must be a positive safe integer');
|
|
48
|
+
}
|
|
49
|
+
if (scope.targetClusterIds.length < 1 || scope.targetNodeNames.length < 1) {
|
|
50
|
+
errors.push('immutable rollout target scope must contain clusters and nodes');
|
|
51
|
+
}
|
|
52
|
+
if (new Set(scope.targetClusterIds).size !== scope.targetClusterIds.length
|
|
53
|
+
|| new Set(scope.targetNodeNames).size !== scope.targetNodeNames.length) {
|
|
54
|
+
errors.push('immutable rollout target scope must not contain duplicates');
|
|
55
|
+
}
|
|
56
|
+
if (scope.requiredReplicaCount !== scope.targetNodeNames.length * scope.replicasPerNode) {
|
|
57
|
+
errors.push('requiredReplicaCount does not match target nodes and replicasPerNode');
|
|
58
|
+
}
|
|
59
|
+
if (planArg.mode === 'rollback' && !planArg.rollbackOfRolloutId) {
|
|
60
|
+
errors.push('rollback rollout must identify the rollout it replaces');
|
|
61
|
+
}
|
|
62
|
+
if (planArg.mode !== 'rollback' && planArg.rollbackOfRolloutId) {
|
|
63
|
+
errors.push('only rollback rollouts may set rollbackOfRolloutId');
|
|
64
|
+
}
|
|
65
|
+
return errors;
|
|
66
|
+
};
|
|
67
|
+
export const validateImageRolloutStatus = (statusArg) => {
|
|
68
|
+
const errors = [];
|
|
69
|
+
const counts = [
|
|
70
|
+
statusArg.requiredReplicaCount,
|
|
71
|
+
statusArg.observedReplicaCount,
|
|
72
|
+
statusArg.healthyReplicaCount,
|
|
73
|
+
statusArg.verifiedReplicaCount,
|
|
74
|
+
statusArg.failedReplicaCount,
|
|
75
|
+
];
|
|
76
|
+
if (counts.some((countArg) => !Number.isSafeInteger(countArg) || countArg < 0)) {
|
|
77
|
+
errors.push('rollout replica counts must be non-negative safe integers');
|
|
78
|
+
}
|
|
79
|
+
const reporterIds = statusArg.reporters.map((reporterArg) => reporterArg.reporterId);
|
|
80
|
+
const reporterSessionIds = statusArg.reporters.map((reporterArg) => reporterArg.reporterSessionId);
|
|
81
|
+
const reporterNodeNames = statusArg.reporters.flatMap((reporterArg) => reporterArg.reporterNodeNames);
|
|
82
|
+
if (new Set(reporterIds).size !== reporterIds.length
|
|
83
|
+
|| new Set(reporterSessionIds).size !== reporterSessionIds.length) {
|
|
84
|
+
errors.push('rollout status must contain one latest report per reporter and session');
|
|
85
|
+
}
|
|
86
|
+
for (const reporter of statusArg.reporters) {
|
|
87
|
+
const reporterCounts = [
|
|
88
|
+
reporter.requiredReplicaCount,
|
|
89
|
+
reporter.observedReplicaCount,
|
|
90
|
+
reporter.healthyReplicaCount,
|
|
91
|
+
reporter.verifiedReplicaCount,
|
|
92
|
+
reporter.failedReplicaCount,
|
|
93
|
+
];
|
|
94
|
+
if (reporterCounts.some((countArg) => !Number.isSafeInteger(countArg) || countArg < 0)) {
|
|
95
|
+
errors.push('reporter replica counts must be non-negative safe integers');
|
|
96
|
+
}
|
|
97
|
+
if (reporter.rolloutId !== statusArg.rolloutId
|
|
98
|
+
|| reporter.rolloutGeneration !== statusArg.rolloutGeneration) {
|
|
99
|
+
errors.push('reporter rollout identity does not match aggregate rollout identity');
|
|
100
|
+
}
|
|
101
|
+
if (reporter.observedReplicaCount > reporter.requiredReplicaCount
|
|
102
|
+
|| reporter.healthyReplicaCount > reporter.observedReplicaCount
|
|
103
|
+
|| reporter.verifiedReplicaCount > reporter.observedReplicaCount) {
|
|
104
|
+
errors.push('reporter replica counts are contradictory');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (statusArg.status === 'succeeded' || statusArg.status === 'rolled-back') {
|
|
108
|
+
if (statusArg.requiredReplicaCount < 1
|
|
109
|
+
|| statusArg.observedReplicaCount !== statusArg.requiredReplicaCount
|
|
110
|
+
|| statusArg.healthyReplicaCount !== statusArg.requiredReplicaCount
|
|
111
|
+
|| statusArg.verifiedReplicaCount !== statusArg.requiredReplicaCount
|
|
112
|
+
|| statusArg.failedReplicaCount !== 0) {
|
|
113
|
+
errors.push('successful rollout status requires every replica to be observed, healthy and verified');
|
|
114
|
+
}
|
|
115
|
+
if (statusArg.mismatchReason || statusArg.reporters.length < 1) {
|
|
116
|
+
errors.push('successful rollout status requires reporters without mismatch reasons');
|
|
117
|
+
}
|
|
118
|
+
if (new Set(reporterNodeNames).size !== reporterNodeNames.length) {
|
|
119
|
+
errors.push('successful rollout status must not count a node in multiple reporters');
|
|
120
|
+
}
|
|
121
|
+
if (statusArg.reporters.some((reporterArg) => (reporterArg.requiredReplicaCount < 1
|
|
122
|
+
|| reporterArg.observedReplicaCount !== reporterArg.requiredReplicaCount
|
|
123
|
+
|| reporterArg.healthyReplicaCount !== reporterArg.requiredReplicaCount
|
|
124
|
+
|| reporterArg.verifiedReplicaCount !== reporterArg.requiredReplicaCount
|
|
125
|
+
|| reporterArg.failedReplicaCount !== 0
|
|
126
|
+
|| Boolean(reporterArg.mismatchReason)))) {
|
|
127
|
+
errors.push('successful rollout requires every reporter replica to be healthy and verified');
|
|
128
|
+
}
|
|
129
|
+
const reporterTotals = statusArg.reporters.reduce((totalsArg, reporterArg) => ({
|
|
130
|
+
required: totalsArg.required + reporterArg.requiredReplicaCount,
|
|
131
|
+
observed: totalsArg.observed + reporterArg.observedReplicaCount,
|
|
132
|
+
healthy: totalsArg.healthy + reporterArg.healthyReplicaCount,
|
|
133
|
+
verified: totalsArg.verified + reporterArg.verifiedReplicaCount,
|
|
134
|
+
failed: totalsArg.failed + reporterArg.failedReplicaCount,
|
|
135
|
+
}), { required: 0, observed: 0, healthy: 0, verified: 0, failed: 0 });
|
|
136
|
+
if (reporterTotals.required !== statusArg.requiredReplicaCount
|
|
137
|
+
|| reporterTotals.observed !== statusArg.observedReplicaCount
|
|
138
|
+
|| reporterTotals.healthy !== statusArg.healthyReplicaCount
|
|
139
|
+
|| reporterTotals.verified !== statusArg.verifiedReplicaCount
|
|
140
|
+
|| reporterTotals.failed !== statusArg.failedReplicaCount) {
|
|
141
|
+
errors.push('successful rollout aggregate must exactly match successful reporter evidence');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return errors;
|
|
145
|
+
};
|
|
146
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1tdXRhYmxlaW1hZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9kYXRhL2ltbXV0YWJsZWltYWdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXVNQSxNQUFNLGlCQUFpQixHQUFHLHVCQUF1QixDQUFDO0FBRWxELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsTUFBYyxFQUE2QixFQUFFO0lBQ2pGLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBQ3JELE9BQU8saUJBQWlCLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzdDLENBQUMsQ0FBRSxnQkFBa0M7UUFDckMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNoQixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxNQUFjLEVBQTJCLEVBQUUsQ0FDeEUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBRWpDLE1BQU0saUJBQWlCLEdBQUcsdUVBQXVFLENBQUM7QUFDbEcsTUFBTSxlQUFlLEdBQUcsbUVBQW1FLENBQUM7QUFFNUYsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsQ0FDN0MsWUFBb0IsRUFDcEIsVUFBa0IsRUFDbEIsTUFBcUIsRUFDYixFQUFFO0lBQ1YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUMvRSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxDQUFDLENBQUM7SUFDOUUsQ0FBQztJQUNELElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUM1QixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDOUQsQ0FBQztJQUNELE9BQU8sR0FBRyxZQUFZLElB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
|
package/dist_ts/data/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from './cloudlyconfig.js';
|
|
|
2
2
|
export * from './cluster.js';
|
|
3
3
|
export * from './config.js';
|
|
4
4
|
export * from './deployment.js';
|
|
5
|
+
export * from './deploymentpreflight.js';
|
|
5
6
|
export * from './migration.js';
|
|
6
7
|
export * from './dns.js';
|
|
7
8
|
export * from './docker.js';
|
|
@@ -11,6 +12,7 @@ export * from './externalregistry.js';
|
|
|
11
12
|
export * from './gateway.js';
|
|
12
13
|
export * from './hostedapp.js';
|
|
13
14
|
export * from './image.js';
|
|
15
|
+
export * from './immutableimage.js';
|
|
14
16
|
export * from './isolatedrestore.js';
|
|
15
17
|
export * from './isolatedrestore.golden.js';
|
|
16
18
|
export * from './mail.js';
|