@superblocksteam/shared 0.9603.3 → 0.9604.1
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/database-lifecycle/capacityPolicy.d.ts +51 -0
- package/dist/database-lifecycle/capacityPolicy.d.ts.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.js +159 -0
- package/dist/database-lifecycle/capacityPolicy.js.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.test.d.ts +2 -0
- package/dist/database-lifecycle/capacityPolicy.test.d.ts.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.test.js +159 -0
- package/dist/database-lifecycle/capacityPolicy.test.js.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.d.ts +18 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.d.ts.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.js +32 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.js.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.d.ts +2 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.d.ts.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.js +91 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.js.map +1 -0
- package/dist/database-lifecycle/index.d.ts +50 -27
- package/dist/database-lifecycle/index.d.ts.map +1 -1
- package/dist/database-lifecycle/index.js +78 -54
- package/dist/database-lifecycle/index.js.map +1 -1
- package/dist/database-lifecycle/index.test.js +120 -77
- package/dist/database-lifecycle/index.test.js.map +1 -1
- package/dist/database-lifecycle/physicalPoolIdentity.d.ts +29 -0
- package/dist/database-lifecycle/physicalPoolIdentity.d.ts.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.js +64 -0
- package/dist/database-lifecycle/physicalPoolIdentity.js.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.d.ts +2 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.d.ts.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.js +51 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/audit/ocsf.d.ts +60 -6
- package/dist/types/audit/ocsf.d.ts.map +1 -1
- package/dist/types/audit/ocsf.js +12 -1
- package/dist/types/audit/ocsf.js.map +1 -1
- package/dist/types/deployment/deployQueueStatus.d.ts +13 -0
- package/dist/types/deployment/deployQueueStatus.d.ts.map +1 -1
- package/dist/types/deployment/index.d.ts +1 -1
- package/dist/types/deployment/index.d.ts.map +1 -1
- package/dist/types/deployment/index.js.map +1 -1
- package/dist/types/policyGate/index.d.ts +5 -0
- package/dist/types/policyGate/index.d.ts.map +1 -1
- package/dist/types/policyGate/index.js +5 -1
- package/dist/types/policyGate/index.js.map +1 -1
- package/dist/types/publishPipeline/plan.js +1 -1
- package/dist/types/publishPipeline/plan.js.map +1 -1
- package/dist/types/publishPipeline/plan.test.js +3 -3
- package/dist/types/publishPipeline/plan.test.js.map +1 -1
- package/dist/types/rbac/index.d.ts +2 -0
- package/dist/types/rbac/index.d.ts.map +1 -1
- package/dist/types/rbac/index.js +3 -1
- package/dist/types/rbac/index.js.map +1 -1
- package/dist/types/reviewPolicy/index.d.ts +35 -4
- package/dist/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist/types/reviewPolicy/index.js +15 -1
- package/dist/types/reviewPolicy/index.js.map +1 -1
- package/dist/types/reviewPolicy/index.test.d.ts +2 -0
- package/dist/types/reviewPolicy/index.test.d.ts.map +1 -0
- package/dist/types/reviewPolicy/index.test.js +17 -0
- package/dist/types/reviewPolicy/index.test.js.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.d.ts +51 -0
- package/dist-esm/database-lifecycle/capacityPolicy.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.js +150 -0
- package/dist-esm/database-lifecycle/capacityPolicy.js.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.js +157 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.js.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.d.ts +18 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.js +29 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.js.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.js +89 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.js.map +1 -0
- package/dist-esm/database-lifecycle/index.d.ts +50 -27
- package/dist-esm/database-lifecycle/index.d.ts.map +1 -1
- package/dist-esm/database-lifecycle/index.js +62 -51
- package/dist-esm/database-lifecycle/index.js.map +1 -1
- package/dist-esm/database-lifecycle/index.test.js +90 -47
- package/dist-esm/database-lifecycle/index.test.js.map +1 -1
- package/dist-esm/database-lifecycle/physicalPoolIdentity.d.ts +29 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.js +59 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.js.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.js +49 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.js.map +1 -0
- package/dist-esm/index.d.ts +1 -0
- package/dist-esm/index.d.ts.map +1 -1
- package/dist-esm/index.js +1 -0
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/types/audit/ocsf.d.ts +60 -6
- package/dist-esm/types/audit/ocsf.d.ts.map +1 -1
- package/dist-esm/types/audit/ocsf.js +12 -1
- package/dist-esm/types/audit/ocsf.js.map +1 -1
- package/dist-esm/types/deployment/deployQueueStatus.d.ts +13 -0
- package/dist-esm/types/deployment/deployQueueStatus.d.ts.map +1 -1
- package/dist-esm/types/deployment/index.d.ts +1 -1
- package/dist-esm/types/deployment/index.d.ts.map +1 -1
- package/dist-esm/types/deployment/index.js.map +1 -1
- package/dist-esm/types/policyGate/index.d.ts +5 -0
- package/dist-esm/types/policyGate/index.d.ts.map +1 -1
- package/dist-esm/types/policyGate/index.js +5 -1
- package/dist-esm/types/policyGate/index.js.map +1 -1
- package/dist-esm/types/publishPipeline/plan.js +1 -1
- package/dist-esm/types/publishPipeline/plan.js.map +1 -1
- package/dist-esm/types/publishPipeline/plan.test.js +3 -3
- package/dist-esm/types/publishPipeline/plan.test.js.map +1 -1
- package/dist-esm/types/rbac/index.d.ts +2 -0
- package/dist-esm/types/rbac/index.d.ts.map +1 -1
- package/dist-esm/types/rbac/index.js +3 -1
- package/dist-esm/types/rbac/index.js.map +1 -1
- package/dist-esm/types/reviewPolicy/index.d.ts +35 -4
- package/dist-esm/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist-esm/types/reviewPolicy/index.js +13 -0
- package/dist-esm/types/reviewPolicy/index.js.map +1 -1
- package/dist-esm/types/reviewPolicy/index.test.d.ts +2 -0
- package/dist-esm/types/reviewPolicy/index.test.d.ts.map +1 -0
- package/dist-esm/types/reviewPolicy/index.test.js +15 -0
- package/dist-esm/types/reviewPolicy/index.test.js.map +1 -0
- package/package.json +1 -1
- package/src/database-lifecycle/capacityPolicy.test.ts +209 -0
- package/src/database-lifecycle/capacityPolicy.ts +197 -0
- package/src/database-lifecycle/edit-lifecycle-capability.test.ts +116 -0
- package/src/database-lifecycle/edit-lifecycle-capability.ts +34 -0
- package/src/database-lifecycle/index.test.ts +105 -48
- package/src/database-lifecycle/index.ts +157 -90
- package/src/database-lifecycle/physicalPoolIdentity.test.ts +64 -0
- package/src/database-lifecycle/physicalPoolIdentity.ts +75 -0
- package/src/index.ts +1 -0
- package/src/types/audit/ocsf.ts +73 -7
- package/src/types/deployment/deployQueueStatus.ts +14 -0
- package/src/types/deployment/index.ts +2 -1
- package/src/types/policyGate/index.ts +5 -1
- package/src/types/publishPipeline/plan.test.ts +3 -3
- package/src/types/publishPipeline/plan.ts +1 -1
- package/src/types/rbac/index.ts +3 -1
- package/src/types/reviewPolicy/index.test.ts +17 -0
- package/src/types/reviewPolicy/index.ts +52 -5
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tag key for proactive physical-instance capacity thresholds.
|
|
3
|
+
* Each value encodes one pool policy (see {@link encodeCapacityPolicyTag} /
|
|
4
|
+
* {@link parseCapacityPolicyTags}).
|
|
5
|
+
*
|
|
6
|
+
* Versioned wire format (pipe-delimited, one tag value per pool):
|
|
7
|
+
* `v2|{encodedAgentName}|{engine}|{thresholdType}|{thresholdValue}`
|
|
8
|
+
*
|
|
9
|
+
* Example:
|
|
10
|
+
* `v2|customer-opa|postgres|minAvailableCapacityPercent|20`
|
|
11
|
+
*/
|
|
12
|
+
export declare const DATABASE_LIFECYCLE_TAG_CAPACITY_POLICIES = "databaseLifecycle:capacityPolicies";
|
|
13
|
+
export declare const DATABASE_ENGINES: readonly ["postgres", "snowflake", "snowflake_postgres", "lakebase"];
|
|
14
|
+
export type DatabaseEngine = (typeof DATABASE_ENGINES)[number];
|
|
15
|
+
export declare const PHYSICAL_DATABASE_CAPACITY_THRESHOLD_TYPES: readonly ["minAvailableCapacityPercent"];
|
|
16
|
+
export type PhysicalDatabaseCapacityThresholdType = (typeof PHYSICAL_DATABASE_CAPACITY_THRESHOLD_TYPES)[number];
|
|
17
|
+
export type PhysicalDatabaseCapacityPolicy = {
|
|
18
|
+
agentName: string;
|
|
19
|
+
engine: DatabaseEngine;
|
|
20
|
+
thresholdType: 'minAvailableCapacityPercent';
|
|
21
|
+
thresholdValue: number;
|
|
22
|
+
};
|
|
23
|
+
export type PhysicalDatabasePoolKey = {
|
|
24
|
+
organizationId: string;
|
|
25
|
+
agentName: string;
|
|
26
|
+
engine: DatabaseEngine;
|
|
27
|
+
};
|
|
28
|
+
export declare class CapacityPolicyValidationError extends Error {
|
|
29
|
+
readonly details: string[];
|
|
30
|
+
readonly code = "capacity_policy_invalid";
|
|
31
|
+
constructor(message: string, details?: string[]);
|
|
32
|
+
}
|
|
33
|
+
/** Stable idempotency and identity key for an organization physical pool. */
|
|
34
|
+
export declare function computePhysicalDatabasePoolKey(pool: PhysicalDatabasePoolKey): string;
|
|
35
|
+
export declare function encodeCapacityPolicyTag(policy: PhysicalDatabaseCapacityPolicy): string;
|
|
36
|
+
/**
|
|
37
|
+
* Parse and validate capacity-policy tags. Fail closed: any malformed value
|
|
38
|
+
* throws {@link CapacityPolicyValidationError}. Missing tag key ⇒ empty list
|
|
39
|
+
* (no proactive provisioning for that agent).
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseCapacityPolicyTags(published: string[] | undefined): PhysicalDatabaseCapacityPolicy[];
|
|
42
|
+
/**
|
|
43
|
+
* Detect threshold disagreements for the same physical pool.
|
|
44
|
+
* Profile tags are routing metadata and do not participate in identity.
|
|
45
|
+
*
|
|
46
|
+
* Registration callers soft-skip peer conflicts (rolling threshold updates);
|
|
47
|
+
* the registering agent's own invalid tags still fail closed.
|
|
48
|
+
*/
|
|
49
|
+
export declare function validateCapacityPolicyCompatibility(candidatePolicies: readonly PhysicalDatabaseCapacityPolicy[], existingPolicies: readonly PhysicalDatabaseCapacityPolicy[]): void;
|
|
50
|
+
export declare function parseCapacityPolicyTag(raw: string): PhysicalDatabaseCapacityPolicy;
|
|
51
|
+
//# sourceMappingURL=capacityPolicy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacityPolicy.d.ts","sourceRoot":"","sources":["../../src/database-lifecycle/capacityPolicy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wCAAwC,uCAAuC,CAAC;AAE7F,eAAO,MAAM,gBAAgB,sEAAuE,CAAC;AACrG,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,eAAO,MAAM,0CAA0C,0CAA2C,CAAC;AACnG,MAAM,MAAM,qCAAqC,GAAG,CAAC,OAAO,0CAA0C,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhH,MAAM,MAAM,8BAA8B,GAAG;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,6BAA6B,CAAC;IAC7C,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;CACxB,CAAC;AAEF,qBAAa,6BAA8B,SAAQ,KAAK;IAKpD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE;IAJ5B,QAAQ,CAAC,IAAI,6BAA6B;gBAGxC,OAAO,EAAE,MAAM,EACN,OAAO,GAAE,MAAM,EAAO;CAKlC;AAED,6EAA6E;AAC7E,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAGpF;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,8BAA8B,GAAG,MAAM,CAGtF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,GAAG,8BAA8B,EAAE,CAuCzG;AAED;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CACjD,iBAAiB,EAAE,SAAS,8BAA8B,EAAE,EAC5D,gBAAgB,EAAE,SAAS,8BAA8B,EAAE,GAC1D,IAAI,CAsBN;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,8BAA8B,CAgDlF"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Agent tag key for proactive physical-instance capacity thresholds.
|
|
4
|
+
* Each value encodes one pool policy (see {@link encodeCapacityPolicyTag} /
|
|
5
|
+
* {@link parseCapacityPolicyTags}).
|
|
6
|
+
*
|
|
7
|
+
* Versioned wire format (pipe-delimited, one tag value per pool):
|
|
8
|
+
* `v2|{encodedAgentName}|{engine}|{thresholdType}|{thresholdValue}`
|
|
9
|
+
*
|
|
10
|
+
* Example:
|
|
11
|
+
* `v2|customer-opa|postgres|minAvailableCapacityPercent|20`
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.CapacityPolicyValidationError = exports.PHYSICAL_DATABASE_CAPACITY_THRESHOLD_TYPES = exports.DATABASE_ENGINES = exports.DATABASE_LIFECYCLE_TAG_CAPACITY_POLICIES = void 0;
|
|
15
|
+
exports.computePhysicalDatabasePoolKey = computePhysicalDatabasePoolKey;
|
|
16
|
+
exports.encodeCapacityPolicyTag = encodeCapacityPolicyTag;
|
|
17
|
+
exports.parseCapacityPolicyTags = parseCapacityPolicyTags;
|
|
18
|
+
exports.validateCapacityPolicyCompatibility = validateCapacityPolicyCompatibility;
|
|
19
|
+
exports.parseCapacityPolicyTag = parseCapacityPolicyTag;
|
|
20
|
+
exports.DATABASE_LIFECYCLE_TAG_CAPACITY_POLICIES = 'databaseLifecycle:capacityPolicies';
|
|
21
|
+
exports.DATABASE_ENGINES = ['postgres', 'snowflake', 'snowflake_postgres', 'lakebase'];
|
|
22
|
+
exports.PHYSICAL_DATABASE_CAPACITY_THRESHOLD_TYPES = ['minAvailableCapacityPercent'];
|
|
23
|
+
class CapacityPolicyValidationError extends Error {
|
|
24
|
+
details;
|
|
25
|
+
code = 'capacity_policy_invalid';
|
|
26
|
+
constructor(message, details = []) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.details = details;
|
|
29
|
+
this.name = 'CapacityPolicyValidationError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.CapacityPolicyValidationError = CapacityPolicyValidationError;
|
|
33
|
+
/** Stable idempotency and identity key for an organization physical pool. */
|
|
34
|
+
function computePhysicalDatabasePoolKey(pool) {
|
|
35
|
+
const agentName = normalizeCapacityPolicyAgentName(pool.agentName);
|
|
36
|
+
return ['provision_physical_database', encodeURIComponent(pool.organizationId), encodeURIComponent(agentName), pool.engine].join(':');
|
|
37
|
+
}
|
|
38
|
+
function encodeCapacityPolicyTag(policy) {
|
|
39
|
+
const agentName = normalizeCapacityPolicyAgentName(policy.agentName);
|
|
40
|
+
return ['v2', encodeURIComponent(agentName), policy.engine, policy.thresholdType, String(policy.thresholdValue)].join('|');
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse and validate capacity-policy tags. Fail closed: any malformed value
|
|
44
|
+
* throws {@link CapacityPolicyValidationError}. Missing tag key ⇒ empty list
|
|
45
|
+
* (no proactive provisioning for that agent).
|
|
46
|
+
*/
|
|
47
|
+
function parseCapacityPolicyTags(published) {
|
|
48
|
+
if (published === undefined) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
if (!Array.isArray(published)) {
|
|
52
|
+
throw new CapacityPolicyValidationError('databaseLifecycle:capacityPolicies must be an array of policy strings.');
|
|
53
|
+
}
|
|
54
|
+
const policies = [];
|
|
55
|
+
const errors = [];
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
for (const raw of published) {
|
|
58
|
+
if (typeof raw !== 'string' || raw.trim() === '') {
|
|
59
|
+
errors.push('capacity policy value must be a non-empty string');
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const policy = parseCapacityPolicyTag(raw);
|
|
64
|
+
const identity = JSON.stringify([policy.agentName, policy.engine]);
|
|
65
|
+
if (seen.has(identity)) {
|
|
66
|
+
errors.push(`duplicate capacity policy for pool ${identity}`);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
seen.add(identity);
|
|
70
|
+
policies.push(policy);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
errors.push(error instanceof Error ? error.message : String(error));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (errors.length > 0) {
|
|
77
|
+
throw new CapacityPolicyValidationError(`Invalid databaseLifecycle:capacityPolicies (${errors.length} error${errors.length === 1 ? '' : 's'}).`, errors);
|
|
78
|
+
}
|
|
79
|
+
return policies;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Detect threshold disagreements for the same physical pool.
|
|
83
|
+
* Profile tags are routing metadata and do not participate in identity.
|
|
84
|
+
*
|
|
85
|
+
* Registration callers soft-skip peer conflicts (rolling threshold updates);
|
|
86
|
+
* the registering agent's own invalid tags still fail closed.
|
|
87
|
+
*/
|
|
88
|
+
function validateCapacityPolicyCompatibility(candidatePolicies, existingPolicies) {
|
|
89
|
+
const errors = [];
|
|
90
|
+
for (const candidate of candidatePolicies) {
|
|
91
|
+
const candidateAgentName = normalizeCapacityPolicyAgentName(candidate.agentName);
|
|
92
|
+
for (const existing of existingPolicies) {
|
|
93
|
+
const existingAgentName = normalizeCapacityPolicyAgentName(existing.agentName);
|
|
94
|
+
if (candidate.engine !== existing.engine || candidateAgentName !== existingAgentName) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (candidate.thresholdValue !== existing.thresholdValue) {
|
|
98
|
+
errors.push(`different thresholds for pool ${JSON.stringify([candidateAgentName, candidate.engine])}: ${candidate.thresholdValue} and ${existing.thresholdValue}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (errors.length > 0) {
|
|
103
|
+
throw new CapacityPolicyValidationError(`Conflicting databaseLifecycle:capacityPolicies (${errors.length} conflict${errors.length === 1 ? '' : 's'}): ${errors.join('; ')}`, errors);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function parseCapacityPolicyTag(raw) {
|
|
107
|
+
const parts = raw.split('|');
|
|
108
|
+
if (parts.length !== 5) {
|
|
109
|
+
throw new Error(`expected 5 pipe-delimited fields (version|agentName|engine|thresholdType|value), got ${parts.length} in ${JSON.stringify(raw)}`);
|
|
110
|
+
}
|
|
111
|
+
const [version, agentNameEncoded, engineRaw, thresholdTypeRaw, thresholdValueRaw] = parts;
|
|
112
|
+
if (version !== 'v2') {
|
|
113
|
+
throw new Error(`unsupported version ${JSON.stringify(version)}`);
|
|
114
|
+
}
|
|
115
|
+
if (!isKnownValue(engineRaw, exports.DATABASE_ENGINES)) {
|
|
116
|
+
throw new Error(`unknown engine ${JSON.stringify(engineRaw)}`);
|
|
117
|
+
}
|
|
118
|
+
if (!isKnownValue(thresholdTypeRaw, exports.PHYSICAL_DATABASE_CAPACITY_THRESHOLD_TYPES)) {
|
|
119
|
+
throw new Error(`unknown thresholdType ${JSON.stringify(thresholdTypeRaw)}`);
|
|
120
|
+
}
|
|
121
|
+
let decodedAgentName;
|
|
122
|
+
try {
|
|
123
|
+
decodedAgentName = decodeURIComponent(agentNameEncoded);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
throw new Error(`agentName is not valid URI encoding: ${JSON.stringify(agentNameEncoded)}`);
|
|
127
|
+
}
|
|
128
|
+
const agentName = normalizeCapacityPolicyAgentName(decodedAgentName);
|
|
129
|
+
if (thresholdValueRaw.trim() === '' || !/^-?\d+$/.test(thresholdValueRaw)) {
|
|
130
|
+
throw new Error('thresholdValue must be a non-empty integer');
|
|
131
|
+
}
|
|
132
|
+
const thresholdValue = Number(thresholdValueRaw);
|
|
133
|
+
if (!Number.isSafeInteger(thresholdValue)) {
|
|
134
|
+
throw new Error(`thresholdValue must be an integer, got ${JSON.stringify(thresholdValueRaw)}`);
|
|
135
|
+
}
|
|
136
|
+
if (thresholdValue < 0) {
|
|
137
|
+
throw new Error(`thresholdValue must be >= 0, got ${thresholdValue}`);
|
|
138
|
+
}
|
|
139
|
+
if (thresholdValue > 100) {
|
|
140
|
+
throw new Error(`minAvailableCapacityPercent must be <= 100, got ${thresholdValue}`);
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
agentName,
|
|
144
|
+
engine: engineRaw,
|
|
145
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
146
|
+
thresholdValue
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function isKnownValue(value, known) {
|
|
150
|
+
return known.some((candidate) => candidate === value);
|
|
151
|
+
}
|
|
152
|
+
function normalizeCapacityPolicyAgentName(agentName) {
|
|
153
|
+
const normalized = agentName.trim();
|
|
154
|
+
if (normalized.length === 0) {
|
|
155
|
+
throw new CapacityPolicyValidationError('agentName must be non-empty after trimming.');
|
|
156
|
+
}
|
|
157
|
+
return normalized;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=capacityPolicy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacityPolicy.js","sourceRoot":"","sources":["../../src/database-lifecycle/capacityPolicy.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAoCH,wEAGC;AAED,0DAGC;AAOD,0DAuCC;AASD,kFAyBC;AAED,wDAgDC;AA5KY,QAAA,wCAAwC,GAAG,oCAAoC,CAAC;AAEhF,QAAA,gBAAgB,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,CAAU,CAAC;AAGxF,QAAA,0CAA0C,GAAG,CAAC,6BAA6B,CAAU,CAAC;AAgBnG,MAAa,6BAA8B,SAAQ,KAAK;IAK3C;IAJF,IAAI,GAAG,yBAAyB,CAAC;IAE1C,YACE,OAAe,EACN,UAAoB,EAAE;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAFN,YAAO,GAAP,OAAO,CAAe;QAG/B,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAVD,sEAUC;AAED,6EAA6E;AAC7E,SAAgB,8BAA8B,CAAC,IAA6B;IAC1E,MAAM,SAAS,GAAG,gCAAgC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnE,OAAO,CAAC,6BAA6B,EAAE,kBAAkB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACxI,CAAC;AAED,SAAgB,uBAAuB,CAAC,MAAsC;IAC5E,MAAM,SAAS,GAAG,gCAAgC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACrE,OAAO,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7H,CAAC;AAED;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,SAA+B;IACrE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,6BAA6B,CAAC,wEAAwE,CAAC,CAAC;IACpH,CAAC;IAED,MAAM,QAAQ,GAAqC,EAAE,CAAC;IACtD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAE/B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YACjD,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;YAChE,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACnE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;gBAC9D,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACnB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,6BAA6B,CACrC,+CAA+C,MAAM,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,EACvG,MAAM,CACP,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,mCAAmC,CACjD,iBAA4D,EAC5D,gBAA2D;IAE3D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,SAAS,IAAI,iBAAiB,EAAE,CAAC;QAC1C,MAAM,kBAAkB,GAAG,gCAAgC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACjF,KAAK,MAAM,QAAQ,IAAI,gBAAgB,EAAE,CAAC;YACxC,MAAM,iBAAiB,GAAG,gCAAgC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC/E,IAAI,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,kBAAkB,KAAK,iBAAiB,EAAE,CAAC;gBACrF,SAAS;YACX,CAAC;YACD,IAAI,SAAS,CAAC,cAAc,KAAK,QAAQ,CAAC,cAAc,EAAE,CAAC;gBACzD,MAAM,CAAC,IAAI,CACT,iCAAiC,IAAI,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,cAAc,QAAQ,QAAQ,CAAC,cAAc,EAAE,CACtJ,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,6BAA6B,CACrC,mDAAmD,MAAM,CAAC,MAAM,YAAY,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EACnI,MAAM,CACP,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,sBAAsB,CAAC,GAAW;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,wFAAwF,KAAK,CAAC,MAAM,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CACjI,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,GAAG,KAAK,CAAC;IAE1F,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,wBAAgB,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE,kDAA0C,CAAC,EAAE,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,IAAI,gBAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,gBAAgB,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAC9F,CAAC;IACD,MAAM,SAAS,GAAG,gCAAgC,CAAC,gBAAgB,CAAC,CAAC;IAErE,IAAI,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,0CAA0C,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;IACD,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,oCAAoC,cAAc,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,cAAc,GAAG,GAAG,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,mDAAmD,cAAc,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO;QACL,SAAS;QACT,MAAM,EAAE,SAAS;QACjB,aAAa,EAAE,6BAA6B;QAC5C,cAAc;KACf,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAmB,KAAa,EAAE,KAAmB;IACxE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,gCAAgC,CAAC,SAAiB;IACzD,MAAM,UAAU,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC;IACpC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,6BAA6B,CAAC,6CAA6C,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacityPolicy.test.d.ts","sourceRoot":"","sources":["../../src/database-lifecycle/capacityPolicy.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const capacityPolicy_js_1 = require("./capacityPolicy.js");
|
|
5
|
+
(0, vitest_1.describe)('capacity policy tags', () => {
|
|
6
|
+
(0, vitest_1.test)('round-trips percentage policies with trimmed case-sensitive agent names', () => {
|
|
7
|
+
const shared = {
|
|
8
|
+
agentName: 'Customer OPA',
|
|
9
|
+
engine: 'postgres',
|
|
10
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
11
|
+
thresholdValue: 20
|
|
12
|
+
};
|
|
13
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.parseCapacityPolicyTag)((0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
14
|
+
...shared,
|
|
15
|
+
agentName: ' Customer OPA '
|
|
16
|
+
}))).toEqual(shared);
|
|
17
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.encodeCapacityPolicyTag)(shared)).toBe('v2|Customer%20OPA|postgres|minAvailableCapacityPercent|20');
|
|
18
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.encodeCapacityPolicyTag)({ ...shared, agentName: 'customer opa' })).not.toBe((0, capacityPolicy_js_1.encodeCapacityPolicyTag)(shared));
|
|
19
|
+
});
|
|
20
|
+
(0, vitest_1.test)('parseCapacityPolicyTags returns empty when the tag is omitted', () => {
|
|
21
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.parseCapacityPolicyTags)(undefined)).toEqual([]);
|
|
22
|
+
});
|
|
23
|
+
(0, vitest_1.test)('rejects unsupported versions, empty agent names, blank values, and out-of-range thresholds', () => {
|
|
24
|
+
const agentName = encodeURIComponent('customer-opa');
|
|
25
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v1|${agentName}|postgres|minAvailableCapacityPercent|20`)).toThrow(/unsupported version/);
|
|
26
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v2|%20%20|postgres|minAvailableCapacityPercent|20`)).toThrow(/agentName must be non-empty/);
|
|
27
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v2|${agentName}|postgres|minAvailableCapacityPercent|`)).toThrow(/thresholdValue must be a non-empty integer/);
|
|
28
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v2|${agentName}|postgres|minAvailableCapacityPercent|101`)).toThrow(/<= 100/);
|
|
29
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v2|${agentName}|postgres|minAvailableCapacityPercent|-1`)).toThrow(/>= 0/);
|
|
30
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTag)(`v2|${agentName}|postgres|minEmptyPhysicalInstances|1`)).toThrow(/unknown thresholdType/);
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.test)('parseCapacityPolicyTags fails closed on any invalid value', () => {
|
|
33
|
+
const valid = (0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
34
|
+
agentName: 'customer-opa',
|
|
35
|
+
engine: 'postgres',
|
|
36
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
37
|
+
thresholdValue: 20
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.parseCapacityPolicyTags)([valid, 'not-a-policy'])).toThrow(capacityPolicy_js_1.CapacityPolicyValidationError);
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.test)('rejects duplicate policies for the same agent name and engine', () => {
|
|
42
|
+
const first = (0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
43
|
+
agentName: 'Customer OPA',
|
|
44
|
+
engine: 'postgres',
|
|
45
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
46
|
+
thresholdValue: 20
|
|
47
|
+
});
|
|
48
|
+
const duplicate = (0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
49
|
+
agentName: ' Customer OPA ',
|
|
50
|
+
engine: 'postgres',
|
|
51
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
52
|
+
thresholdValue: 10
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
(0, capacityPolicy_js_1.parseCapacityPolicyTags)([first, duplicate]);
|
|
56
|
+
vitest_1.expect.fail('Expected duplicate capacity policy validation to fail');
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
(0, vitest_1.expect)(error).toBeInstanceOf(capacityPolicy_js_1.CapacityPolicyValidationError);
|
|
60
|
+
if (!(error instanceof capacityPolicy_js_1.CapacityPolicyValidationError)) {
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
63
|
+
(0, vitest_1.expect)(error.details).toEqual([vitest_1.expect.stringContaining('duplicate capacity policy')]);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
(0, vitest_1.test)('allows distinct agent names for the same engine', () => {
|
|
67
|
+
const first = (0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
68
|
+
agentName: 'customer-opa-a',
|
|
69
|
+
engine: 'postgres',
|
|
70
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
71
|
+
thresholdValue: 20
|
|
72
|
+
});
|
|
73
|
+
const second = (0, capacityPolicy_js_1.encodeCapacityPolicyTag)({
|
|
74
|
+
agentName: 'customer-opa-b',
|
|
75
|
+
engine: 'postgres',
|
|
76
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
77
|
+
thresholdValue: 10
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.parseCapacityPolicyTags)([first, second])).toHaveLength(2);
|
|
80
|
+
});
|
|
81
|
+
(0, vitest_1.test)('computePhysicalDatabasePoolKey is trimmed, case-sensitive, and delimiter-safe', () => {
|
|
82
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
83
|
+
organizationId: 'org:1',
|
|
84
|
+
agentName: ' customer:opa ',
|
|
85
|
+
engine: 'postgres'
|
|
86
|
+
})).toBe((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
87
|
+
organizationId: 'org:1',
|
|
88
|
+
agentName: 'customer:opa',
|
|
89
|
+
engine: 'postgres'
|
|
90
|
+
}));
|
|
91
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
92
|
+
organizationId: 'org:1',
|
|
93
|
+
agentName: 'customer:opa',
|
|
94
|
+
engine: 'postgres'
|
|
95
|
+
})).not.toBe((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
96
|
+
organizationId: 'org',
|
|
97
|
+
agentName: '1:customer:opa',
|
|
98
|
+
engine: 'postgres'
|
|
99
|
+
}));
|
|
100
|
+
(0, vitest_1.expect)((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
101
|
+
organizationId: 'org:1',
|
|
102
|
+
agentName: 'Customer:OPA',
|
|
103
|
+
engine: 'postgres'
|
|
104
|
+
})).not.toBe((0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
105
|
+
organizationId: 'org:1',
|
|
106
|
+
agentName: 'customer:opa',
|
|
107
|
+
engine: 'postgres'
|
|
108
|
+
}));
|
|
109
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.computePhysicalDatabasePoolKey)({
|
|
110
|
+
organizationId: 'org:1',
|
|
111
|
+
agentName: ' ',
|
|
112
|
+
engine: 'postgres'
|
|
113
|
+
})).toThrow(/agentName must be non-empty/);
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.test)('allows replicas to publish the same pool and threshold', () => {
|
|
116
|
+
const policy = {
|
|
117
|
+
agentName: 'customer-opa',
|
|
118
|
+
engine: 'postgres',
|
|
119
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
120
|
+
thresholdValue: 20
|
|
121
|
+
};
|
|
122
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.validateCapacityPolicyCompatibility)([policy], [{ ...policy }])).not.toThrow();
|
|
123
|
+
});
|
|
124
|
+
(0, vitest_1.test)('rejects different thresholds for the same pool', () => {
|
|
125
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.validateCapacityPolicyCompatibility)([
|
|
126
|
+
{
|
|
127
|
+
agentName: 'customer-opa',
|
|
128
|
+
engine: 'postgres',
|
|
129
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
130
|
+
thresholdValue: 20
|
|
131
|
+
}
|
|
132
|
+
], [
|
|
133
|
+
{
|
|
134
|
+
agentName: 'customer-opa',
|
|
135
|
+
engine: 'postgres',
|
|
136
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
137
|
+
thresholdValue: 10
|
|
138
|
+
}
|
|
139
|
+
])).toThrow(/different thresholds/);
|
|
140
|
+
});
|
|
141
|
+
(0, vitest_1.test)('allows different agent names and case-distinct agent names for the same engine', () => {
|
|
142
|
+
(0, vitest_1.expect)(() => (0, capacityPolicy_js_1.validateCapacityPolicyCompatibility)([
|
|
143
|
+
{
|
|
144
|
+
agentName: 'Customer OPA',
|
|
145
|
+
engine: 'postgres',
|
|
146
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
147
|
+
thresholdValue: 20
|
|
148
|
+
}
|
|
149
|
+
], [
|
|
150
|
+
{
|
|
151
|
+
agentName: 'customer opa',
|
|
152
|
+
engine: 'postgres',
|
|
153
|
+
thresholdType: 'minAvailableCapacityPercent',
|
|
154
|
+
thresholdValue: 10
|
|
155
|
+
}
|
|
156
|
+
])).not.toThrow();
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=capacityPolicy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capacityPolicy.test.js","sourceRoot":"","sources":["../../src/database-lifecycle/capacityPolicy.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AgentStatus, type AgentTags } from '../types/organization/agent.js';
|
|
2
|
+
export type AgentLifecycleTagSource = {
|
|
3
|
+
status?: AgentStatus | string;
|
|
4
|
+
tags?: AgentTags;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Whether an agent list shows Native DB opted in for provisioning.
|
|
8
|
+
*
|
|
9
|
+
* Coarse registration check for product advertising (Clark tools/prompts,
|
|
10
|
+
* UI Databases entry): an active agent must publish `ensure_database` and
|
|
11
|
+
* serve at least one profile. Profile-key resolution, engine support, and
|
|
12
|
+
* managed-IAM admission stay on the server at ensure/dispatch time — this
|
|
13
|
+
* helper does not re-encode that surface.
|
|
14
|
+
*
|
|
15
|
+
* Agents without a confirmed active status are excluded (fail closed).
|
|
16
|
+
*/
|
|
17
|
+
export declare function hasEditLifecycleCapability(agents: readonly AgentLifecycleTagSource[] | undefined): boolean;
|
|
18
|
+
//# sourceMappingURL=edit-lifecycle-capability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-lifecycle-capability.d.ts","sourceRoot":"","sources":["../../src/database-lifecycle/edit-lifecycle-capability.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAG7E,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,uBAAuB,EAAE,GAAG,SAAS,GAAG,OAAO,CAc1G"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hasEditLifecycleCapability = hasEditLifecycleCapability;
|
|
4
|
+
const agent_js_1 = require("../types/organization/agent.js");
|
|
5
|
+
const index_js_1 = require("./index.js");
|
|
6
|
+
/**
|
|
7
|
+
* Whether an agent list shows Native DB opted in for provisioning.
|
|
8
|
+
*
|
|
9
|
+
* Coarse registration check for product advertising (Clark tools/prompts,
|
|
10
|
+
* UI Databases entry): an active agent must publish `ensure_database` and
|
|
11
|
+
* serve at least one profile. Profile-key resolution, engine support, and
|
|
12
|
+
* managed-IAM admission stay on the server at ensure/dispatch time — this
|
|
13
|
+
* helper does not re-encode that surface.
|
|
14
|
+
*
|
|
15
|
+
* Agents without a confirmed active status are excluded (fail closed).
|
|
16
|
+
*/
|
|
17
|
+
function hasEditLifecycleCapability(agents) {
|
|
18
|
+
if (!agents || agents.length === 0) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return agents.some((agent) => {
|
|
22
|
+
if (agent.status === undefined || (agent.status !== agent_js_1.AgentStatus.ACTIVE && agent.status !== 'Active')) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
const operations = agent.tags?.[index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS] ?? [];
|
|
26
|
+
if (!operations.includes('ensure_database')) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return (agent.tags?.profile ?? []).length > 0;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=edit-lifecycle-capability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-lifecycle-capability.js","sourceRoot":"","sources":["../../src/database-lifecycle/edit-lifecycle-capability.ts"],"names":[],"mappings":";;AAmBA,gEAcC;AAjCD,6DAA6E;AAC7E,yCAA+D;AAO/D;;;;;;;;;;GAUG;AACH,SAAgB,0BAA0B,CAAC,MAAsD;IAC/F,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,sBAAW,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,EAAE,CAAC;YACrG,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,4CAAiC,CAAC,IAAI,EAAE,CAAC;QACzE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-lifecycle-capability.test.d.ts","sourceRoot":"","sources":["../../src/database-lifecycle/edit-lifecycle-capability.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const agent_js_1 = require("../types/organization/agent.js");
|
|
5
|
+
const edit_lifecycle_capability_js_1 = require("./edit-lifecycle-capability.js");
|
|
6
|
+
const index_js_1 = require("./index.js");
|
|
7
|
+
(0, vitest_1.describe)('hasEditLifecycleCapability', () => {
|
|
8
|
+
(0, vitest_1.it)('is false when no agents are present', () => {
|
|
9
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)(undefined)).toBe(false);
|
|
10
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([])).toBe(false);
|
|
11
|
+
});
|
|
12
|
+
(0, vitest_1.it)('is false when agents lack databaseLifecycle operations', () => {
|
|
13
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
14
|
+
{
|
|
15
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
16
|
+
tags: { profile: ['dev'] }
|
|
17
|
+
}
|
|
18
|
+
])).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
(0, vitest_1.it)('is false when the agent registers other operations but not ensure_database', () => {
|
|
21
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
22
|
+
{
|
|
23
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
24
|
+
tags: {
|
|
25
|
+
[index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['migrate_schema', 'retire_database'],
|
|
26
|
+
profile: ['dev']
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
])).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)('is false when ensure_database is registered but the agent serves no profile', () => {
|
|
32
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
33
|
+
{
|
|
34
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
35
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database', 'migrate_schema'] }
|
|
36
|
+
}
|
|
37
|
+
])).toBe(false);
|
|
38
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
39
|
+
{
|
|
40
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
41
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database'], profile: [] }
|
|
42
|
+
}
|
|
43
|
+
])).toBe(false);
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)('is false when a disconnected agent has lifecycle tags', () => {
|
|
46
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
47
|
+
{
|
|
48
|
+
status: agent_js_1.AgentStatus.DISCONNECTED,
|
|
49
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database'], profile: ['dev'] }
|
|
50
|
+
}
|
|
51
|
+
])).toBe(false);
|
|
52
|
+
});
|
|
53
|
+
(0, vitest_1.it)('is false when agent status is missing even if tags would otherwise qualify', () => {
|
|
54
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
55
|
+
{
|
|
56
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database'], profile: ['dev'] }
|
|
57
|
+
}
|
|
58
|
+
])).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
(0, vitest_1.it)('is true when an active agent registered ensure_database for any profile', () => {
|
|
61
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
62
|
+
{
|
|
63
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
64
|
+
tags: {
|
|
65
|
+
[index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database', 'migrate_schema'],
|
|
66
|
+
profile: ['staging', 'production']
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
])).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
// A production-only lifecycle agent still advertises Native DB. Editing is no
|
|
72
|
+
// longer a separate lifecycle axis, so there is no `edit:` pair to require —
|
|
73
|
+
// profile-key resolution stays on the server at ensure/dispatch time.
|
|
74
|
+
(0, vitest_1.it)('is true for an agent serving only production', () => {
|
|
75
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
76
|
+
{
|
|
77
|
+
status: agent_js_1.AgentStatus.ACTIVE,
|
|
78
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database'], profile: ['production'] }
|
|
79
|
+
}
|
|
80
|
+
])).toBe(true);
|
|
81
|
+
});
|
|
82
|
+
(0, vitest_1.it)('is true when status is the string Active (CLI wire form)', () => {
|
|
83
|
+
(0, vitest_1.expect)((0, edit_lifecycle_capability_js_1.hasEditLifecycleCapability)([
|
|
84
|
+
{
|
|
85
|
+
status: 'Active',
|
|
86
|
+
tags: { [index_js_1.DATABASE_LIFECYCLE_TAG_OPERATIONS]: ['ensure_database'], profile: ['dev'] }
|
|
87
|
+
}
|
|
88
|
+
])).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=edit-lifecycle-capability.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit-lifecycle-capability.test.js","sourceRoot":"","sources":["../../src/database-lifecycle/edit-lifecycle-capability.test.ts"],"names":[],"mappings":"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"}
|