@varde-flyt/vfac 0.6.0 → 0.7.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/vfac.mjs +77 -0
- package/package.json +1 -1
package/dist/vfac.mjs
CHANGED
|
@@ -13403,6 +13403,16 @@ var ProductOutputSchema = external_exports.object({
|
|
|
13403
13403
|
*/
|
|
13404
13404
|
secret: external_exports.boolean().optional()
|
|
13405
13405
|
}).strict();
|
|
13406
|
+
var ProductConditionSchema = external_exports.object({
|
|
13407
|
+
key: external_exports.string().regex(/^[a-z][a-zA-Z0-9]{1,47}$/, "Condition keys are camelCase.").describe("Stable key. A running instance reports its state under this key."),
|
|
13408
|
+
displayName: external_exports.string().min(2).max(60),
|
|
13409
|
+
/**
|
|
13410
|
+
* What the customer must understand, and — when it is ACTION_REQUIRED —
|
|
13411
|
+
* enough to act on. The platform never writes this sentence: it does not
|
|
13412
|
+
* know what the condition is about.
|
|
13413
|
+
*/
|
|
13414
|
+
description: external_exports.string().min(10).max(300)
|
|
13415
|
+
}).strict();
|
|
13406
13416
|
var ProductDependencySchema = external_exports.object({
|
|
13407
13417
|
/**
|
|
13408
13418
|
* OPTIONAL ONLY WHEN `interface` IS PRESENT, enforced below.
|
|
@@ -13631,6 +13641,16 @@ var ProductDefinitionObjectSchema = external_exports.object({
|
|
|
13631
13641
|
// --- Results, relationships, operations -------------------------------
|
|
13632
13642
|
outputs: external_exports.array(ProductOutputSchema).min(1).max(MAX_PRODUCT_OUTPUTS),
|
|
13633
13643
|
dependencies: external_exports.array(ProductDependencySchema).max(8),
|
|
13644
|
+
/**
|
|
13645
|
+
* Operational conditions a running instance of this Product may report.
|
|
13646
|
+
*
|
|
13647
|
+
* `.optional()`, NEVER `.default([])`. A default materialises the key,
|
|
13648
|
+
* `contractDigest` digests the parsed object, and a republish of unchanged
|
|
13649
|
+
* bytes would then be refused as `RELEASED_CONTRACT_MUTATED`. Absent means
|
|
13650
|
+
* this Product reports none, which is what every Definition published
|
|
13651
|
+
* before this field already means.
|
|
13652
|
+
*/
|
|
13653
|
+
conditions: external_exports.array(ProductConditionSchema).min(1).max(8).optional(),
|
|
13634
13654
|
/**
|
|
13635
13655
|
* The service interfaces this Product provides to other Products.
|
|
13636
13656
|
*
|
|
@@ -13697,6 +13717,15 @@ var ProductDefinitionSchema = ProductDefinitionObjectSchema.superRefine((definit
|
|
|
13697
13717
|
});
|
|
13698
13718
|
}
|
|
13699
13719
|
});
|
|
13720
|
+
const conditionKeys = (definition.conditions ?? []).map((condition) => condition.key);
|
|
13721
|
+
const duplicateConditions = conditionKeys.filter((key, i) => conditionKeys.indexOf(key) !== i);
|
|
13722
|
+
if (duplicateConditions.length > 0) {
|
|
13723
|
+
ctx.addIssue({
|
|
13724
|
+
code: external_exports.ZodIssueCode.custom,
|
|
13725
|
+
path: ["conditions"],
|
|
13726
|
+
message: `Duplicate condition keys: ${[...new Set(duplicateConditions)].join(", ")}.`
|
|
13727
|
+
});
|
|
13728
|
+
}
|
|
13700
13729
|
const dependencyIds = definition.dependencies.map((dependency) => dependency.productId).filter((id) => id !== void 0);
|
|
13701
13730
|
const duplicateDependencies = dependencyIds.filter((id, i) => dependencyIds.indexOf(id) !== i);
|
|
13702
13731
|
if (duplicateDependencies.length > 0) {
|
|
@@ -14880,6 +14909,33 @@ var DeploymentBlueprintObjectSchema = external_exports.object({
|
|
|
14880
14909
|
serviceExports: external_exports.array(ServiceExportSchema).max(MAX_SERVICE_EXPORTS).optional(),
|
|
14881
14910
|
/** Service interfaces this Product consumes. Absent means none. */
|
|
14882
14911
|
serviceBindings: external_exports.array(ServiceBindingSchema).max(MAX_SERVICE_BINDINGS).optional(),
|
|
14912
|
+
/**
|
|
14913
|
+
* Which of your own components may report an operational condition.
|
|
14914
|
+
*
|
|
14915
|
+
* NOT DECORATION, and the same policy `dynamicResources[].consumers` is. The
|
|
14916
|
+
* Control Plane mints the condition-reporting credential only for a named
|
|
14917
|
+
* component, so a Blueprint that names none has declared conditions in its
|
|
14918
|
+
* Definition that nothing can reach. Delivery is the enforcement.
|
|
14919
|
+
*
|
|
14920
|
+
* `.optional()`, NEVER `.default([])` — `contractDigest` digests the parsed
|
|
14921
|
+
* object, and a default would materialise the key on every Blueprint
|
|
14922
|
+
* published before this field existed.
|
|
14923
|
+
*
|
|
14924
|
+
* EXACTLY ONE, and that is a property of what a condition IS rather than a
|
|
14925
|
+
* limit somebody will want raised. A condition is keyed per INSTANCE, not
|
|
14926
|
+
* per component: two components reporting `sso` write the same row and
|
|
14927
|
+
* decide it between them by whichever clock is ahead, which is a race with
|
|
14928
|
+
* a customer-visible answer. And "is this Product usable" is a statement
|
|
14929
|
+
* about the instance — CLAUDE.md's "One Product Instance is ONE runtime
|
|
14930
|
+
* unit" — so a second voice is a second opinion, not more coverage.
|
|
14931
|
+
*
|
|
14932
|
+
* It also keeps the platform's withdrawal honest. The watermark that stops
|
|
14933
|
+
* a superseded runtime's answer being served is per instance, because what
|
|
14934
|
+
* replaced the container is an instance-level event; with two reporters,
|
|
14935
|
+
* redeploying one would withdraw the other's still-correct answer and it
|
|
14936
|
+
* would never speak again.
|
|
14937
|
+
*/
|
|
14938
|
+
conditionReporters: external_exports.array(ComponentIdSchema).min(1).max(1).optional(),
|
|
14883
14939
|
secrets: external_exports.array(SecretWiringSchema).max(20),
|
|
14884
14940
|
dataStores: external_exports.array(DataStoreSchema).max(8),
|
|
14885
14941
|
egress: external_exports.array(EgressRuleSchema).max(24),
|
|
@@ -16624,6 +16680,27 @@ async function runGet(parsed) {
|
|
|
16624
16680
|
const declaredNames = declared.map((entry) => entry["key"]).filter((key2) => typeof key2 === "string");
|
|
16625
16681
|
const names = [.../* @__PURE__ */ new Set([...Object.keys(outputs), ...declaredNames])].sort();
|
|
16626
16682
|
const isSecret2 = (name) => declared.find((entry) => entry["key"] === name)?.["secret"] === true;
|
|
16683
|
+
const conditions = Array.isArray(resource["conditions"]) ? resource["conditions"] : [];
|
|
16684
|
+
if (conditions.length > 0) {
|
|
16685
|
+
lines.push("", " Operational");
|
|
16686
|
+
const width = Math.max(
|
|
16687
|
+
...conditions.map((one) => String(one["displayName"] ?? one["key"] ?? "").length)
|
|
16688
|
+
);
|
|
16689
|
+
for (const one of conditions) {
|
|
16690
|
+
const label = String(one["displayName"] ?? one["key"] ?? "");
|
|
16691
|
+
const state = String(one["state"] ?? "UNKNOWN");
|
|
16692
|
+
const reason = one["reason"];
|
|
16693
|
+
lines.push(
|
|
16694
|
+
` ${label.padEnd(width)} ${state}${typeof reason === "string" && reason !== "" ? ` (${reason})` : ""}`
|
|
16695
|
+
);
|
|
16696
|
+
const description = one["description"];
|
|
16697
|
+
if (typeof description === "string") {
|
|
16698
|
+
for (const line of wrapOutput(description, 68)) {
|
|
16699
|
+
lines.push(` ${" ".repeat(width)} ${line}`);
|
|
16700
|
+
}
|
|
16701
|
+
}
|
|
16702
|
+
}
|
|
16703
|
+
}
|
|
16627
16704
|
if (names.length > 0) {
|
|
16628
16705
|
lines.push("", " Outputs");
|
|
16629
16706
|
const width = Math.max(...names.map((name) => name.length));
|