| 97 | // failure as "<source>: <message>" before throwing — the same all-at-once style as |
| 98 | // assertDeployable. Narrows to DeployComponent once the shape is proven. |
| 99 | export function parseDeployComponents(raw: { source: string; data: unknown }[]): DeployComponent[] { |
| 100 | const errors: string[] = []; |
| 101 | for (const { source, data } of raw) { |
| 102 | for (const message of validateComponent(data)) errors.push(`${source}: ${message}`); |
| 103 | } |
| 104 | if (errors.length > 0) { |
| 105 | throw new Error(`invalid custom component(s):\n - ${errors.join("\n - ")}`); |
| 106 | } |
| 107 | return raw.map((r) => r.data as DeployComponent); |
| 108 | } |
| 109 | |
| 110 | // One line of a <name>.env.example: a KEY=value assignment, or anything else |
| 111 | // (comment, blank) passed through verbatim so the generated file keeps its shape. |