( auth: ResolvedAuth, timeoutMs: number = DEFAULT_TIMEOUT_MS, )
| 207 | ); |
| 208 | |
| 209 | export const makeCliService = ( |
| 210 | auth: ResolvedAuth, |
| 211 | timeoutMs: number = DEFAULT_TIMEOUT_MS, |
| 212 | ): Effect.Effect<OnePasswordService, OnePasswordError> => |
| 213 | Effect.sync(() => { |
| 214 | const run = ( |
| 215 | base: readonly string[], |
| 216 | operation: string, |
| 217 | ): Effect.Effect<string, OnePasswordError> => { |
| 218 | const spawn = Effect.promise((signal) => |
| 219 | opCliExec({ args: cliArgs(auth, base), env: cliEnv(auth), timeoutMs, signal }), |
| 220 | ).pipe( |
| 221 | Effect.flatMap((result) => { |
| 222 | if (result.ok) return Effect.succeed(result.stdout); |
| 223 | return Effect.fail( |
| 224 | result.timedOut |
| 225 | ? new OnePasswordError({ |
| 226 | operation, |
| 227 | message: makeTimeoutMessage(operation, timeoutMs), |
| 228 | }) |
| 229 | : new OnePasswordError({ |
| 230 | operation, |
| 231 | message: messageWithCause(`1Password CLI ${operation} failed`, result), |
| 232 | }), |
| 233 | ); |
| 234 | }), |
| 235 | ); |
| 236 | return (auth.kind === "desktop-app" ? cliPromptLock.withPermits(1)(spawn) : spawn).pipe( |
| 237 | Effect.withSpan(`onepassword.cli.${operation}`), |
| 238 | ); |
| 239 | }; |
| 240 | |
| 241 | const runJson = <A>( |
| 242 | base: readonly string[], |
| 243 | operation: string, |
| 244 | decodeRows: (raw: string) => Effect.Effect<A, Schema.SchemaError>, |
| 245 | ): Effect.Effect<A, OnePasswordError> => |
| 246 | run([...base, "--format=json"], operation).pipe( |
| 247 | Effect.flatMap((raw) => |
| 248 | decodeRows(raw).pipe( |
| 249 | Effect.mapError( |
| 250 | (cause) => |
| 251 | new OnePasswordError({ |
| 252 | operation, |
| 253 | message: messageWithCause( |
| 254 | `1Password CLI ${operation} returned unexpected output`, |
| 255 | cause, |
| 256 | ), |
| 257 | }), |
| 258 | ), |
| 259 | ), |
| 260 | ), |
| 261 | ); |
| 262 | |
| 263 | return OnePasswordServiceTag.of({ |
| 264 | // `op read` appends a trailing newline to the field value; strip it the |
| 265 | // same way op-js's `read.parse` did so stored secrets stay unchanged. |
| 266 | resolveSecret: (uri) => |
no test coverage detected