(args: Record<string, unknown>)
| 237 | writeFileSync(statePath(), JSON.stringify(state, null, 2)); |
| 238 | } |
| 239 | function readState(args: Record<string, unknown>): StackState { |
| 240 | const overrides = { |
| 241 | projectId: args.project as string | undefined, |
| 242 | region: args.region as string | undefined, |
| 243 | }; |
| 244 | let base: Partial<StackState> = {}; |
| 245 | if (existsSync(statePath())) { |
| 246 | try { |
| 247 | base = JSON.parse(readFileSync(statePath(), "utf8")) as StackState; |
| 248 | } catch { |
| 249 | // ignore a corrupt state file; flags must supply the values. |
| 250 | } |
| 251 | } |
| 252 | const merged: Partial<StackState> = { ...base, ...stripUndefined(overrides) }; |
| 253 | const missing = ( |
| 254 | ["projectId", "region", "bucketName", "serviceUrl", "workflowId"] as const |
| 255 | ).filter((k) => !merged[k]); |
| 256 | if (missing.length > 0) { |
| 257 | console.error( |
| 258 | `[cloudrun] missing stack coordinates: ${missing.join(", ")}. ` + |
| 259 | `Run \`hyperframes cloudrun deploy --project <id>\` first, or pass them as flags.`, |
| 260 | ); |
| 261 | process.exit(1); |
| 262 | } |
| 263 | return merged as StackState; |
| 264 | } |
| 265 | function stripUndefined<T extends Record<string, unknown>>(o: T): Partial<T> { |
| 266 | return Object.fromEntries(Object.entries(o).filter(([, v]) => v != null)) as Partial<T>; |
| 267 | } |
no test coverage detected