(req: DeployRequirements, p: Partial<DeployConfig>)
| 172 | process.exit(1); |
| 173 | } |
| 174 | throw err; |
| 175 | } |
| 176 | let parsed: unknown; |
| 177 | try { |
| 178 | parsed = JSON.parse(raw); |
| 179 | } catch (err) { |
| 180 | process.stderr.write(`Invalid JSON in values file: ${err instanceof Error ? err.message : String(err)}\n`); |
| 181 | process.exit(1); |
| 182 | } |
| 183 | if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) { |
| 184 | process.stderr.write("Values file must be a JSON object (a partial deploy config).\n"); |
| 185 | process.exit(1); |
| 186 | } |
| 187 | const checked = valuesFileSchema.safeParse(parsed); |
| 188 | if (!checked.success) { |
| 189 | process.stderr.write("Invalid values file (not a partial deploy config):\n"); |
| 190 | for (const issue of checked.error.issues) { |
| 191 | const at = issue.path.length > 0 ? issue.path.join(".") : "(top level)"; |
| 192 | process.stderr.write(` - ${at}: ${issue.message}\n`); |
| 193 | } |
| 194 | process.exit(1); |
| 195 | } |
| 196 | return checked.data; |
| 197 | } |
| 198 | |
| 199 | // Required values that have no default and can only come from the operator, |
| 200 | // plus consistency problems (address conflicts, family-mismatched fields) — |
| 201 | // used to fail fast (exit 1) when there is no terminal to prompt on. |
| 202 | export function missingRequired(req: DeployRequirements, p: Partial<DeployConfig>): string[] { |
| 203 | const missing: string[] = []; |
| 204 | for (const ch of hardwareBindings(req)) { |
no test coverage detected