@executor-js/plugin-onepassword 0.0.1 → 0.1.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/README.md CHANGED
@@ -1,29 +1,31 @@
1
- # @executor/plugin-onepassword
1
+ # @executor-js/plugin-onepassword
2
2
 
3
3
  [1Password](https://1password.com) integration for the executor. Provides a secret source that resolves values from a 1Password vault, backed by either the desktop app (connect.sock) or a service account token.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```sh
8
- bun add @executor/sdk @executor/plugin-onepassword
8
+ bun add @executor-js/sdk @executor-js/plugin-onepassword
9
9
  # or
10
- npm install @executor/sdk @executor/plugin-onepassword
10
+ npm install @executor-js/sdk @executor-js/plugin-onepassword
11
11
  ```
12
12
 
13
13
  ## Usage
14
14
 
15
15
  ```ts
16
- import { createExecutor } from "@executor/sdk";
17
- import { onepasswordPlugin } from "@executor/plugin-onepassword";
16
+ import { createExecutor } from "@executor-js/sdk";
17
+ import { onepasswordPlugin } from "@executor-js/plugin-onepassword";
18
18
 
19
19
  const executor = await createExecutor({
20
- scope: { name: "my-app" },
20
+ onElicitation: "accept-all",
21
21
  plugins: [onepasswordPlugin()] as const,
22
22
  });
23
23
 
24
24
  // Point the plugin at your account
25
25
  await executor.onepassword.configure({
26
26
  auth: { kind: "desktop-app", accountName: "my-account" },
27
+ vaultId: "my-vault-id",
28
+ name: "Personal",
27
29
  });
28
30
 
29
31
  // Inspect connection / list vaults
@@ -34,20 +36,38 @@ const vaults = await executor.onepassword.listVaults({
34
36
  });
35
37
  ```
36
38
 
37
- For CI and headless environments, use a service-account token instead of the desktop app:
39
+ For CI and headless environments, use a service-account token instead of the desktop app. Store the token through the executor's secret store first, then reference it by id:
38
40
 
39
41
  ```ts
42
+ import { createExecutor } from "@executor-js/sdk";
43
+ import { onepasswordPlugin } from "@executor-js/plugin-onepassword";
44
+ import { fileSecretsPlugin } from "@executor-js/plugin-file-secrets";
45
+
46
+ const executor = await createExecutor({
47
+ onElicitation: "accept-all",
48
+ plugins: [fileSecretsPlugin(), onepasswordPlugin()] as const,
49
+ });
50
+
51
+ await executor.secrets.set({
52
+ id: "op-token",
53
+ name: "1Password service account",
54
+ value: process.env.OP_SERVICE_ACCOUNT_TOKEN!,
55
+ scope: executor.scopes[0]!.id,
56
+ });
57
+
40
58
  await executor.onepassword.configure({
41
- auth: { kind: "service-account", token: process.env.OP_SERVICE_ACCOUNT_TOKEN! },
59
+ auth: { kind: "service-account", tokenSecretId: "op-token" },
60
+ vaultId: "my-vault-id",
61
+ name: "CI",
42
62
  });
43
63
  ```
44
64
 
45
65
  ## Using with Effect
46
66
 
47
- If you're building on `@executor/sdk` (the raw Effect entry), import this plugin from its `/core` subpath instead:
67
+ If you're building on `@executor-js/sdk/core` (the raw Effect entry), import this plugin from its `/core` subpath instead — it returns the Effect-shaped plugin with `Effect.Effect<...>`-returning methods rather than promisified wrappers:
48
68
 
49
69
  ```ts
50
- import { onepasswordPlugin } from "@executor/plugin-onepassword";
70
+ import { onepasswordPlugin } from "@executor-js/plugin-onepassword/core";
51
71
  ```
52
72
 
53
73
  ## Status
@@ -1,22 +1,21 @@
1
- import { HttpApiEndpoint, HttpApiGroup } from "@effect/platform";
1
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
2
+ import { Schema } from "effect";
3
+ import { InternalError } from "@executor-js/api";
2
4
  import { OnePasswordError } from "../sdk/errors";
3
5
  import { OnePasswordConfig, Vault, ConnectionStatus } from "../sdk/types";
4
- declare const OnePasswordGroup_base: HttpApiGroup.HttpApiGroup<"onepassword", HttpApiEndpoint.HttpApiEndpoint<"getConfig", "GET", {
5
- readonly scopeId: string & import("effect/Brand").Brand<"ScopeId">;
6
- }, never, never, never, OnePasswordConfig | null, never, never, never> | HttpApiEndpoint.HttpApiEndpoint<"configure", "PUT", {
7
- readonly scopeId: string & import("effect/Brand").Brand<"ScopeId">;
8
- }, never, OnePasswordConfig, never, void, OnePasswordError, never, never> | HttpApiEndpoint.HttpApiEndpoint<"removeConfig", "DELETE", {
9
- readonly scopeId: string & import("effect/Brand").Brand<"ScopeId">;
10
- }, never, never, never, void, never, never, never> | HttpApiEndpoint.HttpApiEndpoint<"status", "GET", {
11
- readonly scopeId: string & import("effect/Brand").Brand<"ScopeId">;
12
- }, never, never, never, ConnectionStatus, OnePasswordError, never, never> | HttpApiEndpoint.HttpApiEndpoint<"listVaults", "GET", {
13
- readonly scopeId: string & import("effect/Brand").Brand<"ScopeId">;
14
- }, {
15
- readonly authKind: "desktop-app" | "service-account";
16
- readonly account: string;
17
- }, never, never, {
18
- readonly vaults: readonly Vault[];
19
- }, OnePasswordError, never, never>, never, never, false>;
20
- export declare class OnePasswordGroup extends OnePasswordGroup_base {
21
- }
22
- export {};
6
+ export declare const OnePasswordGroup: HttpApiGroup.HttpApiGroup<"onepassword", HttpApiEndpoint.HttpApiEndpoint<"getConfig", "GET", "/scopes/:scopeId/onepassword/config", HttpApiEndpoint.StringTree<Schema.Struct<{
7
+ scopeId: Schema.brand<Schema.String, "ScopeId">;
8
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.NullOr<typeof OnePasswordConfig>>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"configure", "PUT", "/scopes/:scopeId/onepassword/config", HttpApiEndpoint.StringTree<Schema.Struct<{
9
+ scopeId: Schema.brand<Schema.String, "ScopeId">;
10
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<typeof OnePasswordConfig>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Void>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"removeConfig", "DELETE", "/scopes/:scopeId/onepassword/config", HttpApiEndpoint.StringTree<Schema.Struct<{
11
+ scopeId: Schema.brand<Schema.String, "ScopeId">;
12
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Void>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"status", "GET", "/scopes/:scopeId/onepassword/status", HttpApiEndpoint.StringTree<Schema.Struct<{
13
+ scopeId: Schema.brand<Schema.String, "ScopeId">;
14
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<typeof ConnectionStatus>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never> | HttpApiEndpoint.HttpApiEndpoint<"listVaults", "GET", "/scopes/:scopeId/onepassword/vaults", HttpApiEndpoint.StringTree<Schema.Struct<{
15
+ scopeId: Schema.brand<Schema.String, "ScopeId">;
16
+ }>>, HttpApiEndpoint.StringTree<Schema.Struct<{
17
+ readonly authKind: Schema.Literals<readonly ["desktop-app", "service-account"]>;
18
+ readonly account: Schema.String;
19
+ }>>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.StringTree<never>, HttpApiEndpoint.Json<Schema.Struct<{
20
+ readonly vaults: Schema.$Array<typeof Vault>;
21
+ }>>, HttpApiEndpoint.Json<typeof InternalError | typeof OnePasswordError>, never, never>, false>;
@@ -1,7 +1,7 @@
1
1
  import { Context } from "effect";
2
2
  import type { OnePasswordExtension } from "../sdk/plugin";
3
- declare const OnePasswordExtensionService_base: Context.TagClass<OnePasswordExtensionService, "OnePasswordExtensionService", OnePasswordExtension>;
3
+ declare const OnePasswordExtensionService_base: Context.ServiceClass<OnePasswordExtensionService, "OnePasswordExtensionService", OnePasswordExtension>;
4
4
  export declare class OnePasswordExtensionService extends OnePasswordExtensionService_base {
5
5
  }
6
- export declare const OnePasswordHandlers: import("effect/Layer").Layer<import("@effect/platform/HttpApiGroup").ApiGroup<"executor", "onepassword">, never, OnePasswordExtensionService>;
6
+ export declare const OnePasswordHandlers: import("effect/Layer").Layer<import("effect/unstable/httpapi/HttpApiGroup").ApiGroup<"executor", "onepassword">, never, import("effect/unstable/http/HttpRouter").Request<"Requires", OnePasswordExtensionService>>;
7
7
  export {};
@@ -0,0 +1,446 @@
1
+ // src/sdk/errors.ts
2
+ import { Schema } from "effect";
3
+ var OnePasswordError = class extends Schema.TaggedErrorClass()(
4
+ "OnePasswordError",
5
+ {
6
+ operation: Schema.String,
7
+ message: Schema.String
8
+ },
9
+ { httpApiStatus: 502 }
10
+ ) {
11
+ };
12
+
13
+ // src/sdk/types.ts
14
+ import { Schema as Schema2 } from "effect";
15
+ var DesktopAppAuth = class extends Schema2.Class("DesktopAppAuth")({
16
+ kind: Schema2.Literal("desktop-app"),
17
+ /** 1Password account domain, e.g. "my.1password.com" */
18
+ accountName: Schema2.String
19
+ }) {
20
+ };
21
+ var ServiceAccountAuth = class extends Schema2.Class("ServiceAccountAuth")({
22
+ kind: Schema2.Literal("service-account"),
23
+ /** The service account token (stored as a secret) */
24
+ tokenSecretId: Schema2.String
25
+ }) {
26
+ };
27
+ var OnePasswordAuth = Schema2.Union([DesktopAppAuth, ServiceAccountAuth]);
28
+ var OnePasswordConfig = class extends Schema2.Class("OnePasswordConfig")({
29
+ auth: OnePasswordAuth,
30
+ /** Vault to scope operations to */
31
+ vaultId: Schema2.String,
32
+ /** Human label */
33
+ name: Schema2.String
34
+ }) {
35
+ };
36
+ var Vault = class extends Schema2.Class("Vault")({
37
+ id: Schema2.String,
38
+ name: Schema2.String
39
+ }) {
40
+ };
41
+ var ConnectionStatus = class extends Schema2.Class("ConnectionStatus")({
42
+ connected: Schema2.Boolean,
43
+ vaultName: Schema2.optional(Schema2.String),
44
+ error: Schema2.optional(Schema2.String)
45
+ }) {
46
+ };
47
+
48
+ // src/sdk/service.ts
49
+ import { Context, Duration, Effect } from "effect";
50
+ import * as op from "@1password/op-js";
51
+ var OnePasswordServiceTag = class extends Context.Service()("@executor-js/plugin-onepassword/OnePasswordService") {
52
+ };
53
+ var DEFAULT_TIMEOUT_MS = 15e3;
54
+ var loadOnePasswordSdk = () => Effect.tryPromise({
55
+ try: () => import("@1password/sdk"),
56
+ catch: (cause) => new OnePasswordError({
57
+ operation: "sdk module load",
58
+ message: cause instanceof Error ? cause.message : String(cause)
59
+ })
60
+ });
61
+ var makeTimeoutMessage = (operation, timeoutMs) => [
62
+ `${operation}: timed out after ${Math.floor(timeoutMs / 1e3)}s.`,
63
+ "Troubleshooting:",
64
+ "1. Make sure the 1Password desktop app is open and unlocked",
65
+ "2. Check for an approval prompt in the 1Password app \u2014 it may be behind other windows",
66
+ "3. Ensure 'Developer > Connect with 1Password CLI' is enabled in 1Password Settings",
67
+ "4. Make sure no other app or terminal is waiting for 1Password approval (only one prompt at a time)",
68
+ "5. Try quitting 1Password completely and reopening it, then retry"
69
+ ].join("\n");
70
+ var timeoutWithOnePasswordError = (operation, timeoutMs) => Effect.timeoutOrElse({
71
+ duration: Duration.millis(timeoutMs),
72
+ orElse: () => Effect.fail(
73
+ new OnePasswordError({
74
+ operation,
75
+ message: makeTimeoutMessage(operation, timeoutMs)
76
+ })
77
+ )
78
+ });
79
+ var makeNativeSdkService = (auth, timeoutMs = DEFAULT_TIMEOUT_MS) => Effect.gen(function* () {
80
+ const sdk = yield* loadOnePasswordSdk().pipe(
81
+ timeoutWithOnePasswordError("sdk module load", timeoutMs)
82
+ );
83
+ const client = yield* Effect.tryPromise({
84
+ try: () => sdk.createClient({
85
+ auth: auth.kind === "desktop-app" ? new sdk.DesktopAuth(auth.accountName) : auth.token,
86
+ integrationName: "Executor",
87
+ integrationVersion: "0.0.0"
88
+ }),
89
+ catch: (cause) => new OnePasswordError({
90
+ operation: "client setup",
91
+ message: cause instanceof Error ? cause.message : String(cause)
92
+ })
93
+ }).pipe(
94
+ timeoutWithOnePasswordError("client setup", timeoutMs)
95
+ );
96
+ const wrap = (fn, operation) => Effect.tryPromise({
97
+ try: fn,
98
+ catch: (cause) => new OnePasswordError({
99
+ operation,
100
+ message: cause instanceof Error ? cause.message : String(cause)
101
+ })
102
+ }).pipe(
103
+ timeoutWithOnePasswordError(operation, timeoutMs),
104
+ Effect.withSpan(`onepassword.sdk.${operation}`)
105
+ );
106
+ return OnePasswordServiceTag.of({
107
+ resolveSecret: (uri) => wrap(() => client.secrets.resolve(uri), "secret resolution"),
108
+ listVaults: () => wrap(() => client.vaults.list({ decryptDetails: true }), "vault listing").pipe(
109
+ Effect.map((vaults) => vaults.map((v) => ({ id: v.id, title: v.title })))
110
+ ),
111
+ listItems: (vaultId) => wrap(() => client.items.list(vaultId), "item listing").pipe(
112
+ Effect.map((items) => items.map((i) => ({ id: i.id, title: i.title })))
113
+ )
114
+ });
115
+ }).pipe(Effect.withSpan("onepassword.sdk.make_service"));
116
+ var makeCliService = (auth) => Effect.sync(() => {
117
+ if (auth.kind === "service-account") {
118
+ op.setServiceAccount(auth.token);
119
+ } else {
120
+ op.setGlobalFlags({ account: auth.accountName });
121
+ }
122
+ const wrapSync = (fn, operation) => Effect.try({
123
+ try: fn,
124
+ catch: (cause) => new OnePasswordError({
125
+ operation,
126
+ message: cause instanceof Error ? cause.message : String(cause)
127
+ })
128
+ }).pipe(Effect.withSpan(`onepassword.cli.${operation}`));
129
+ return OnePasswordServiceTag.of({
130
+ resolveSecret: (uri) => wrapSync(() => op.read.parse(uri), "secret resolution"),
131
+ listVaults: () => wrapSync(() => op.vault.list(), "vault listing").pipe(
132
+ Effect.map((vaults) => vaults.map((v) => ({ id: v.id, title: v.name })))
133
+ ),
134
+ listItems: (vaultId) => wrapSync(() => op.item.list({ vault: vaultId }), "item listing").pipe(
135
+ Effect.map((items) => items.map((i) => ({ id: i.id, title: i.title })))
136
+ )
137
+ });
138
+ }).pipe(Effect.withSpan("onepassword.cli.make_service"));
139
+ var makeOnePasswordService = (auth, options) => {
140
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
141
+ if (options?.preferSdk) {
142
+ return makeNativeSdkService(auth, timeoutMs);
143
+ }
144
+ return makeCliService(auth).pipe(
145
+ Effect.catch(
146
+ (cliError) => (
147
+ // CLI unavailable (e.g. `op` not installed) — fall back to SDK
148
+ makeNativeSdkService(auth, timeoutMs).pipe(Effect.mapError(() => cliError))
149
+ )
150
+ )
151
+ );
152
+ };
153
+
154
+ // src/sdk/plugin.ts
155
+ import { Effect as Effect3, Schema as Schema4 } from "effect";
156
+ import {
157
+ definePlugin,
158
+ StorageError
159
+ } from "@executor-js/sdk/core";
160
+
161
+ // src/api/group.ts
162
+ import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
163
+ import { Schema as Schema3 } from "effect";
164
+ import { ScopeId } from "@executor-js/sdk/core";
165
+ import { InternalError } from "@executor-js/api";
166
+ var ScopeParams = { scopeId: ScopeId };
167
+ var ConfigurePayload = OnePasswordConfig;
168
+ var ListVaultsParams = Schema3.Struct({
169
+ authKind: Schema3.Literals(["desktop-app", "service-account"]),
170
+ account: Schema3.String
171
+ });
172
+ var ListVaultsResponse = Schema3.Struct({
173
+ vaults: Schema3.Array(Vault)
174
+ });
175
+ var GetConfigResponse = Schema3.NullOr(OnePasswordConfig);
176
+ var OnePasswordGroup = HttpApiGroup.make("onepassword").add(
177
+ HttpApiEndpoint.get("getConfig", "/scopes/:scopeId/onepassword/config", {
178
+ params: ScopeParams,
179
+ success: GetConfigResponse,
180
+ error: [InternalError, OnePasswordError]
181
+ })
182
+ ).add(
183
+ HttpApiEndpoint.put("configure", "/scopes/:scopeId/onepassword/config", {
184
+ params: ScopeParams,
185
+ payload: ConfigurePayload,
186
+ success: Schema3.Void,
187
+ error: [InternalError, OnePasswordError]
188
+ })
189
+ ).add(
190
+ HttpApiEndpoint.delete("removeConfig", "/scopes/:scopeId/onepassword/config", {
191
+ params: ScopeParams,
192
+ success: Schema3.Void,
193
+ error: [InternalError, OnePasswordError]
194
+ })
195
+ ).add(
196
+ HttpApiEndpoint.get("status", "/scopes/:scopeId/onepassword/status", {
197
+ params: ScopeParams,
198
+ success: ConnectionStatus,
199
+ error: [InternalError, OnePasswordError]
200
+ })
201
+ ).add(
202
+ HttpApiEndpoint.get("listVaults", "/scopes/:scopeId/onepassword/vaults", {
203
+ params: ScopeParams,
204
+ query: ListVaultsParams,
205
+ success: ListVaultsResponse,
206
+ error: [InternalError, OnePasswordError]
207
+ })
208
+ );
209
+
210
+ // src/api/handlers.ts
211
+ import { HttpApiBuilder } from "effect/unstable/httpapi";
212
+ import { Context as Context2, Effect as Effect2 } from "effect";
213
+ import { addGroup, capture } from "@executor-js/api";
214
+ var OnePasswordExtensionService = class extends Context2.Service()("OnePasswordExtensionService") {
215
+ };
216
+ var ExecutorApiWithOnePassword = addGroup(OnePasswordGroup);
217
+ var OnePasswordHandlers = HttpApiBuilder.group(
218
+ ExecutorApiWithOnePassword,
219
+ "onepassword",
220
+ (handlers) => handlers.handle(
221
+ "getConfig",
222
+ () => capture(Effect2.gen(function* () {
223
+ const ext = yield* OnePasswordExtensionService;
224
+ return yield* ext.getConfig();
225
+ }))
226
+ ).handle(
227
+ "configure",
228
+ ({ payload }) => capture(Effect2.gen(function* () {
229
+ const ext = yield* OnePasswordExtensionService;
230
+ yield* ext.configure(payload);
231
+ }))
232
+ ).handle(
233
+ "removeConfig",
234
+ () => capture(Effect2.gen(function* () {
235
+ const ext = yield* OnePasswordExtensionService;
236
+ yield* ext.removeConfig();
237
+ }))
238
+ ).handle(
239
+ "status",
240
+ () => capture(Effect2.gen(function* () {
241
+ const ext = yield* OnePasswordExtensionService;
242
+ return yield* ext.status();
243
+ }))
244
+ ).handle(
245
+ "listVaults",
246
+ ({ query: urlParams }) => capture(Effect2.gen(function* () {
247
+ const ext = yield* OnePasswordExtensionService;
248
+ const auth = urlParams.authKind === "desktop-app" ? { kind: "desktop-app", accountName: urlParams.account } : { kind: "service-account", tokenSecretId: urlParams.account };
249
+ const vaults = yield* ext.listVaults(auth);
250
+ return { vaults: [...vaults] };
251
+ }))
252
+ )
253
+ );
254
+
255
+ // src/sdk/plugin.ts
256
+ var CREDENTIAL_FIELD = "credential";
257
+ var DEFAULT_TIMEOUT_MS2 = 15e3;
258
+ var CONFIG_KEY = "config";
259
+ var decodeConfig = Schema4.decodeUnknownSync(OnePasswordConfig);
260
+ var blobStorageError = (operation) => (cause) => new StorageError({
261
+ message: `onepassword blob ${operation}: ${cause instanceof Error ? cause.message : String(cause)}`,
262
+ cause
263
+ });
264
+ var makeOnePasswordStore = (blobs, writeScope) => ({
265
+ getConfig: () => blobs.get(CONFIG_KEY).pipe(
266
+ Effect3.mapError(blobStorageError("read")),
267
+ Effect3.flatMap((raw) => {
268
+ if (raw === null) return Effect3.succeed(null);
269
+ return Effect3.try({
270
+ try: () => decodeConfig(JSON.parse(raw)),
271
+ catch: (cause) => new OnePasswordError({
272
+ operation: "config decode",
273
+ message: cause instanceof Error ? cause.message : String(cause)
274
+ })
275
+ });
276
+ })
277
+ ),
278
+ saveConfig: (config) => blobs.put(
279
+ CONFIG_KEY,
280
+ JSON.stringify({
281
+ auth: config.auth,
282
+ vaultId: config.vaultId,
283
+ name: config.name
284
+ }),
285
+ { scope: writeScope }
286
+ ).pipe(Effect3.mapError(blobStorageError("write"))),
287
+ deleteConfig: () => blobs.delete(CONFIG_KEY, { scope: writeScope }).pipe(Effect3.mapError(blobStorageError("delete")))
288
+ });
289
+ var resolveAuth = (auth, ctx) => {
290
+ if (auth.kind === "desktop-app") {
291
+ return Effect3.succeed({
292
+ kind: "desktop-app",
293
+ accountName: auth.accountName
294
+ });
295
+ }
296
+ return ctx.secrets.get(auth.tokenSecretId).pipe(
297
+ Effect3.mapError(
298
+ (err) => "_tag" in err && err._tag === "SecretOwnedByConnectionError" ? new OnePasswordError({
299
+ operation: "auth resolution",
300
+ message: `Service account token secret "${auth.tokenSecretId}" not found`
301
+ }) : err
302
+ ),
303
+ Effect3.flatMap((token) => {
304
+ if (token === null) {
305
+ return Effect3.fail(
306
+ new OnePasswordError({
307
+ operation: "auth resolution",
308
+ message: `Service account token secret "${auth.tokenSecretId}" not found`
309
+ })
310
+ );
311
+ }
312
+ return Effect3.succeed({
313
+ kind: "service-account",
314
+ token
315
+ });
316
+ })
317
+ );
318
+ };
319
+ var getServiceFromConfig = (config, ctx, timeoutMs, preferSdk) => resolveAuth(config.auth, ctx).pipe(
320
+ Effect3.flatMap(
321
+ (resolved) => makeOnePasswordService(resolved, { timeoutMs, preferSdk })
322
+ )
323
+ );
324
+ var makeProvider = (ctx, timeoutMs, preferSdk) => ({
325
+ key: "onepassword",
326
+ writable: false,
327
+ // 1Password vaults are named in the stored config; the executor-scope
328
+ // arg isn't used for routing here. A future refactor could let the
329
+ // plugin store per-scope vault bindings and pick based on `scope`.
330
+ get: (secretId, _scope) => ctx.storage.getConfig().pipe(
331
+ Effect3.flatMap((config) => {
332
+ if (!config) return Effect3.succeed(null);
333
+ const uri = secretId.startsWith("op://") ? secretId : `op://${config.vaultId}/${secretId}/${CREDENTIAL_FIELD}`;
334
+ return getServiceFromConfig(config, ctx, timeoutMs, preferSdk).pipe(
335
+ Effect3.flatMap((svc) => svc.resolveSecret(uri)),
336
+ Effect3.map((v) => v),
337
+ Effect3.orElseSucceed(() => null)
338
+ );
339
+ }),
340
+ Effect3.orElseSucceed(() => null)
341
+ ),
342
+ list: () => ctx.storage.getConfig().pipe(
343
+ Effect3.flatMap((config) => {
344
+ if (!config)
345
+ return Effect3.succeed(
346
+ []
347
+ );
348
+ return getServiceFromConfig(config, ctx, timeoutMs, preferSdk).pipe(
349
+ Effect3.flatMap((svc) => svc.listItems(config.vaultId)),
350
+ Effect3.map(
351
+ (items) => items.map((item2) => ({ id: item2.id, name: item2.title }))
352
+ )
353
+ );
354
+ }),
355
+ Effect3.orElseSucceed(
356
+ () => []
357
+ )
358
+ )
359
+ });
360
+ var onepasswordPlugin = definePlugin(
361
+ (options) => {
362
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
363
+ const preferSdk = options?.preferSdk;
364
+ return {
365
+ id: "onepassword",
366
+ packageName: "@executor-js/plugin-onepassword",
367
+ storage: ({ blobs, scopes }) => makeOnePasswordStore(blobs, scopes.at(-1).id),
368
+ extension: (ctx) => {
369
+ return {
370
+ configure: (config) => ctx.storage.saveConfig(config),
371
+ getConfig: () => ctx.storage.getConfig(),
372
+ removeConfig: () => ctx.storage.deleteConfig(),
373
+ status: () => Effect3.gen(function* () {
374
+ const config = yield* ctx.storage.getConfig();
375
+ if (!config) {
376
+ return new ConnectionStatus({
377
+ connected: false,
378
+ error: "Not configured"
379
+ });
380
+ }
381
+ const svc = yield* getServiceFromConfig(
382
+ config,
383
+ ctx,
384
+ timeoutMs,
385
+ preferSdk
386
+ );
387
+ const vaults = yield* svc.listVaults();
388
+ const vault2 = vaults.find((v) => v.id === config.vaultId);
389
+ return new ConnectionStatus({
390
+ connected: true,
391
+ vaultName: vault2?.title
392
+ });
393
+ }),
394
+ listVaults: (auth) => Effect3.gen(function* () {
395
+ const resolved = yield* resolveAuth(auth, ctx);
396
+ const svc = yield* makeOnePasswordService(resolved, {
397
+ timeoutMs,
398
+ preferSdk
399
+ });
400
+ const vaults = yield* svc.listVaults();
401
+ return vaults.map((v) => new Vault({ id: v.id, name: v.title })).sort((a, b) => a.name.localeCompare(b.name));
402
+ }),
403
+ resolve: (uri) => Effect3.gen(function* () {
404
+ const config = yield* ctx.storage.getConfig();
405
+ if (!config) {
406
+ return yield* Effect3.fail(
407
+ new OnePasswordError({
408
+ operation: "resolve",
409
+ message: "1Password is not configured"
410
+ })
411
+ );
412
+ }
413
+ const svc = yield* getServiceFromConfig(
414
+ config,
415
+ ctx,
416
+ timeoutMs,
417
+ preferSdk
418
+ );
419
+ return yield* svc.resolveSecret(uri);
420
+ })
421
+ };
422
+ },
423
+ secretProviders: (ctx) => [makeProvider(ctx, timeoutMs, preferSdk)],
424
+ routes: () => OnePasswordGroup,
425
+ handlers: () => OnePasswordHandlers,
426
+ extensionService: OnePasswordExtensionService
427
+ };
428
+ }
429
+ );
430
+
431
+ export {
432
+ OnePasswordError,
433
+ DesktopAppAuth,
434
+ ServiceAccountAuth,
435
+ OnePasswordAuth,
436
+ OnePasswordConfig,
437
+ Vault,
438
+ ConnectionStatus,
439
+ OnePasswordServiceTag,
440
+ makeNativeSdkService,
441
+ makeCliService,
442
+ makeOnePasswordService,
443
+ makeOnePasswordStore,
444
+ onepasswordPlugin
445
+ };
446
+ //# sourceMappingURL=chunk-2NSVLCQP.js.map