@theholocron/holocron-plugin-1password 2.0.0-alpha.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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/index.d.mts +83 -0
- package/dist/index.mjs +241 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Newton Koumantzelis
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# `@theholocron/holocron-plugin-1password`
|
|
2
|
+
|
|
3
|
+
1Password plugin for [Holocron](../cli). Implements the **required**
|
|
4
|
+
`vault` capability via shell-out to the `op` CLI
|
|
5
|
+
(https://developer.1password.com/docs/cli).
|
|
6
|
+
|
|
7
|
+
## Why shell-out, not REST
|
|
8
|
+
|
|
9
|
+
1Password's "REST API" is the **Connect server** — a Docker container
|
|
10
|
+
you have to run yourself (or pay for the cloud-hosted version). For a
|
|
11
|
+
solo / small-team workflow, that's overkill. The `op` CLI is what every
|
|
12
|
+
developer already has installed and uses for hand-debugging anyway, so:
|
|
13
|
+
|
|
14
|
+
- **Local dev:** developer's signed-in `op` CLI (biometric unlock via
|
|
15
|
+
the desktop app)
|
|
16
|
+
- **CI:** `OP_SERVICE_ACCOUNT_TOKEN` env var; `op` auto-detects it
|
|
17
|
+
- **Either way:** same binary, same commands, same code path
|
|
18
|
+
|
|
19
|
+
The plugin's job is just to drive the CLI; auth handling is the CLI's.
|
|
20
|
+
|
|
21
|
+
## Prerequisite
|
|
22
|
+
|
|
23
|
+
The `op` binary must be on PATH. Install:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
brew install 1password-cli # macOS
|
|
27
|
+
# or follow https://developer.1password.com/docs/cli/get-started
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The plugin throws a clear error at construction time if `op` isn't
|
|
31
|
+
found.
|
|
32
|
+
|
|
33
|
+
## Config
|
|
34
|
+
|
|
35
|
+
```jsonc
|
|
36
|
+
{
|
|
37
|
+
"providers": {
|
|
38
|
+
"vault": ["1password", {
|
|
39
|
+
"vault": "rando", // 1P vault name
|
|
40
|
+
"account": "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // optional: 1P account UUID
|
|
41
|
+
}]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- `vault` (required) — the 1Password vault name items live in.
|
|
47
|
+
- `account` (optional) — 1P account UUID. Passes `--account <UUID>` on
|
|
48
|
+
every `op` call so the integration targets a specific account even
|
|
49
|
+
when the developer has multiple signed in (e.g., work + personal).
|
|
50
|
+
Find via `op account list`.
|
|
51
|
+
|
|
52
|
+
## What's implemented
|
|
53
|
+
|
|
54
|
+
| Method | What it does |
|
|
55
|
+
| ---------------------- | ------------------------------------------------------------------------------ |
|
|
56
|
+
| `read(reference)` | `op read <reference>` — resolves `op://Vault/Item/field`. `--no-newline`. |
|
|
57
|
+
| `write(reference, v)` | Probe + `op item edit` if exists, else `op item create --category=API Credential`. |
|
|
58
|
+
| `list()` | `op item list --vault=<vault> --format=json` — names of items in the vault. |
|
|
59
|
+
| `environments()` | `op environment list --format=json` — names of 1P Environments. |
|
|
60
|
+
| `readEnvironment(id)` | `op environment read <id>` — parses KEY=VALUE lines into a record. |
|
|
61
|
+
| `whoami()` (via doctor)| `op whoami --format=json` — tolerates the JSON-shape drift across CLI versions and auth modes. |
|
|
62
|
+
|
|
63
|
+
## Status
|
|
64
|
+
|
|
65
|
+
**v0.0.0 — first port.** Ports `rando-id/rando.id`
|
|
66
|
+
`adapters/op-cli.ts`. The stdio shape (`['inherit', 'pipe', 'pipe']`)
|
|
67
|
+
is critical: it gives `op` a TTY signal so it can fire the desktop
|
|
68
|
+
biometric unlock dialog when running locally. CI runs see no TTY and
|
|
69
|
+
fall back to whatever auth mode the env var configures.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { Vault } from "@theholocron/cli";
|
|
3
|
+
|
|
4
|
+
//#region src/auth.d.ts
|
|
5
|
+
declare class AuthError extends Error {
|
|
6
|
+
name: string;
|
|
7
|
+
}
|
|
8
|
+
interface VerifyInput {
|
|
9
|
+
/** Override the spawn function in tests. */
|
|
10
|
+
spawn?: typeof spawnSync;
|
|
11
|
+
/** Path to the op binary. Defaults to "op". */
|
|
12
|
+
binary?: string;
|
|
13
|
+
}
|
|
14
|
+
declare function verifyOpInstalled(input?: VerifyInput): void;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/shell.d.ts
|
|
17
|
+
interface OpResult {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
stdout: string;
|
|
20
|
+
stderr: string;
|
|
21
|
+
}
|
|
22
|
+
interface OpShellOptions {
|
|
23
|
+
/** Override the spawn function in tests. */
|
|
24
|
+
spawn?: typeof spawnSync;
|
|
25
|
+
/** Path to the op binary. Defaults to "op". */
|
|
26
|
+
binary?: string;
|
|
27
|
+
/** 1Password account UUID. When set, passed as `--account` on every call. */
|
|
28
|
+
account?: string;
|
|
29
|
+
}
|
|
30
|
+
interface RunOptions {
|
|
31
|
+
/** Skip `--account` injection for commands that operate above the account level (e.g., `account list`). */
|
|
32
|
+
skipAccount?: boolean;
|
|
33
|
+
}
|
|
34
|
+
declare class OpShell {
|
|
35
|
+
private readonly spawnImpl;
|
|
36
|
+
readonly binary: string;
|
|
37
|
+
readonly account?: string;
|
|
38
|
+
constructor(opts?: OpShellOptions);
|
|
39
|
+
/** Run `op <args>`, returning a uniform result. */
|
|
40
|
+
run(args: string[], opts?: RunOptions): OpResult;
|
|
41
|
+
/** Run + throw if non-zero. Mirrors REST clients' `request<T>` ergonomic. */
|
|
42
|
+
runOrThrow(args: string[], context: string, opts?: RunOptions): string;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/capabilities/vault.d.ts
|
|
46
|
+
interface OpVaultOptions {
|
|
47
|
+
/** 1P vault name items live in. Required — list/write default here. */
|
|
48
|
+
vault: string;
|
|
49
|
+
}
|
|
50
|
+
declare class OpVault implements Vault {
|
|
51
|
+
private readonly shell;
|
|
52
|
+
readonly key: "vault";
|
|
53
|
+
readonly providerName = "1password";
|
|
54
|
+
private readonly vaultName;
|
|
55
|
+
constructor(shell: OpShell, opts: OpVaultOptions);
|
|
56
|
+
read(reference: string): Promise<string>;
|
|
57
|
+
write(reference: string, value: string): Promise<void>;
|
|
58
|
+
list(): Promise<string[]>;
|
|
59
|
+
environments(): Promise<string[]>;
|
|
60
|
+
readEnvironment(environmentId: string): Promise<Record<string, string>>;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/index.d.ts
|
|
64
|
+
interface OpPluginOptions extends VerifyInput {
|
|
65
|
+
/** 1P vault name items live in. Required. */
|
|
66
|
+
vault: string;
|
|
67
|
+
/** Optional 1P account UUID; passed as `--account` on every op call. */
|
|
68
|
+
account?: string;
|
|
69
|
+
}
|
|
70
|
+
interface PluginContext {
|
|
71
|
+
options: OpPluginOptions;
|
|
72
|
+
shell: OpShell;
|
|
73
|
+
}
|
|
74
|
+
declare function createContext(options: OpPluginOptions): PluginContext;
|
|
75
|
+
declare function vault(ctx: PluginContext): Vault;
|
|
76
|
+
declare function createPlugin(options: OpPluginOptions): {
|
|
77
|
+
name: string;
|
|
78
|
+
capabilities: {
|
|
79
|
+
vault: () => Vault;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
//#endregion
|
|
83
|
+
export { AuthError, OpPluginOptions, OpShell, OpVault, PluginContext, VerifyInput, createContext, createPlugin, vault, verifyOpInstalled };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { ProviderApiError } from "@theholocron/cli";
|
|
3
|
+
//#region src/auth.ts
|
|
4
|
+
/**
|
|
5
|
+
* 1Password plugin "auth" is just verifying the `op` binary is on
|
|
6
|
+
* PATH — the CLI handles its own auth (keychain biometric unlock for
|
|
7
|
+
* local dev, OP_SERVICE_ACCOUNT_TOKEN for CI).
|
|
8
|
+
*
|
|
9
|
+
* No `resolveToken()` like the REST plugins; instead, `verifyOpInstalled`
|
|
10
|
+
* runs a fast `op --version` check. `createPlugin` calls it eagerly so
|
|
11
|
+
* a missing binary fails fast and clearly, not as a mystery error when
|
|
12
|
+
* the first `vault.read()` happens later.
|
|
13
|
+
*/
|
|
14
|
+
var AuthError = class extends Error {
|
|
15
|
+
name = "AuthError";
|
|
16
|
+
};
|
|
17
|
+
function verifyOpInstalled(input = {}) {
|
|
18
|
+
const spawnImpl = input.spawn ?? spawnSync;
|
|
19
|
+
const binary = input.binary ?? "op";
|
|
20
|
+
const result = spawnImpl(binary, ["--version"], {
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
stdio: [
|
|
23
|
+
"ignore",
|
|
24
|
+
"pipe",
|
|
25
|
+
"pipe"
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
if (result.error) throw new AuthError(`1Password CLI (\`${binary}\`) not found on PATH. Install via \`brew install 1password-cli\` or see https://developer.1password.com/docs/cli/get-started.`);
|
|
29
|
+
if (result.status !== 0) throw new AuthError(`\`${binary} --version\` failed: ${(result.stderr ?? "").trim() || `exit ${result.status ?? "?"}`}`);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/capabilities/vault.ts
|
|
33
|
+
/**
|
|
34
|
+
* `vault` capability for 1Password.
|
|
35
|
+
*
|
|
36
|
+
* Shells out to the `op` CLI for every operation. Reference format
|
|
37
|
+
* is 1P's native `op://Vault/Item/field` URI.
|
|
38
|
+
*
|
|
39
|
+
* Write semantics: 1P doesn't have an upsert. We probe `op item get`
|
|
40
|
+
* first; if it returns 0 the item exists and we `op item edit`,
|
|
41
|
+
* otherwise we `op item create --category=API Credential`. The
|
|
42
|
+
* fallback gives us an idempotent create-or-update without us
|
|
43
|
+
* parsing edit's stderr to detect "not found".
|
|
44
|
+
*/
|
|
45
|
+
var OpVault = class {
|
|
46
|
+
shell;
|
|
47
|
+
key = "vault";
|
|
48
|
+
providerName = "1password";
|
|
49
|
+
vaultName;
|
|
50
|
+
constructor(shell, opts) {
|
|
51
|
+
this.shell = shell;
|
|
52
|
+
if (!opts.vault) throw new Error("OpVault requires `vault` (1P vault name) in options");
|
|
53
|
+
this.vaultName = opts.vault;
|
|
54
|
+
}
|
|
55
|
+
async read(reference) {
|
|
56
|
+
return this.shell.runOrThrow([
|
|
57
|
+
"read",
|
|
58
|
+
reference,
|
|
59
|
+
"--no-newline"
|
|
60
|
+
], `read ${reference}`);
|
|
61
|
+
}
|
|
62
|
+
async write(reference, value) {
|
|
63
|
+
const parsed = parseReference(reference);
|
|
64
|
+
if (this.shell.run([
|
|
65
|
+
"item",
|
|
66
|
+
"get",
|
|
67
|
+
parsed.item,
|
|
68
|
+
`--vault=${parsed.vault}`,
|
|
69
|
+
"--format=json"
|
|
70
|
+
]).ok) {
|
|
71
|
+
this.shell.runOrThrow([
|
|
72
|
+
"item",
|
|
73
|
+
"edit",
|
|
74
|
+
parsed.item,
|
|
75
|
+
`--vault=${parsed.vault}`,
|
|
76
|
+
`${parsed.field}=${value}`
|
|
77
|
+
], `item edit ${parsed.item}`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.shell.runOrThrow([
|
|
81
|
+
"item",
|
|
82
|
+
"create",
|
|
83
|
+
`--title=${parsed.item}`,
|
|
84
|
+
`--vault=${parsed.vault}`,
|
|
85
|
+
"--category=API Credential",
|
|
86
|
+
`${parsed.field}=${value}`
|
|
87
|
+
], `item create ${parsed.item}`);
|
|
88
|
+
}
|
|
89
|
+
async list() {
|
|
90
|
+
const stdout = this.shell.runOrThrow([
|
|
91
|
+
"item",
|
|
92
|
+
"list",
|
|
93
|
+
`--vault=${this.vaultName}`,
|
|
94
|
+
"--format=json"
|
|
95
|
+
], `item list --vault=${this.vaultName}`);
|
|
96
|
+
if (!stdout) return [];
|
|
97
|
+
return JSON.parse(stdout).map((i) => i.title);
|
|
98
|
+
}
|
|
99
|
+
async environments() {
|
|
100
|
+
const stdout = this.shell.runOrThrow([
|
|
101
|
+
"environment",
|
|
102
|
+
"list",
|
|
103
|
+
"--format=json"
|
|
104
|
+
], "environment list");
|
|
105
|
+
if (!stdout) return [];
|
|
106
|
+
return JSON.parse(stdout).map((e) => e.name);
|
|
107
|
+
}
|
|
108
|
+
async readEnvironment(environmentId) {
|
|
109
|
+
return parseEnvironmentDump(this.shell.runOrThrow([
|
|
110
|
+
"environment",
|
|
111
|
+
"read",
|
|
112
|
+
environmentId
|
|
113
|
+
], `environment read ${environmentId}`));
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Parse `op://Vault/Item/field` into its parts. Throws when the
|
|
118
|
+
* shape doesn't match — surfacing bad inputs at the boundary keeps
|
|
119
|
+
* downstream `op item edit/create` from emitting cryptic errors.
|
|
120
|
+
*/
|
|
121
|
+
function parseReference(reference) {
|
|
122
|
+
if (!reference.startsWith("op://")) throw new ProviderApiError(`1Password references must start with "op://": got "${reference}"`, 400, void 0);
|
|
123
|
+
const parts = reference.slice(5).split("/");
|
|
124
|
+
if (parts.length < 3) throw new ProviderApiError(`1Password reference "${reference}" missing parts; expected op://Vault/Item/field`, 400, void 0);
|
|
125
|
+
const [vault, item, ...fieldParts] = parts;
|
|
126
|
+
return {
|
|
127
|
+
vault,
|
|
128
|
+
item,
|
|
129
|
+
field: fieldParts.join("/")
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Parse `op environment read`'s stdout (KEY=VALUE per line) into a
|
|
134
|
+
* record. Skips blank lines + `# comment` lines. Per-line format is
|
|
135
|
+
* intentionally minimal — no quoting, no escaping; if a value contains
|
|
136
|
+
* a literal newline, that's a problem for the underlying environment,
|
|
137
|
+
* not this parser.
|
|
138
|
+
*/
|
|
139
|
+
function parseEnvironmentDump(stdout) {
|
|
140
|
+
const out = {};
|
|
141
|
+
for (const line of stdout.split("\n")) {
|
|
142
|
+
const trimmed = line.trim();
|
|
143
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
144
|
+
const eq = trimmed.indexOf("=");
|
|
145
|
+
if (eq < 0) continue;
|
|
146
|
+
const key = trimmed.slice(0, eq);
|
|
147
|
+
out[key] = trimmed.slice(eq + 1);
|
|
148
|
+
}
|
|
149
|
+
return out;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/shell.ts
|
|
153
|
+
/**
|
|
154
|
+
* Thin wrapper around `spawnSync` for `op` CLI shell-outs.
|
|
155
|
+
*
|
|
156
|
+
* Equivalent to the REST clients elsewhere in the monorepo, but for
|
|
157
|
+
* the CLI-transport path. Provides:
|
|
158
|
+
*
|
|
159
|
+
* - Uniform `OpResult` shape (`ok`, `stdout`, `stderr`) so capability
|
|
160
|
+
* methods don't repeat the exit-code + decoding boilerplate
|
|
161
|
+
* - Optional `--account <UUID>` injection on every call so a single
|
|
162
|
+
* OpShell instance is scoped to one 1P account even when the user
|
|
163
|
+
* has multiple accounts signed in (work + personal)
|
|
164
|
+
* - The critical stdio shape: `['inherit', 'pipe', 'pipe']`.
|
|
165
|
+
* Inheriting stdin gives `op` a TTY signal so it can fire the
|
|
166
|
+
* desktop biometric unlock dialog locally. CI runs see no TTY and
|
|
167
|
+
* use whichever auth mode the env vars configure (service account
|
|
168
|
+
* token). Default spawnSync stdio of `['pipe','pipe','pipe']` would
|
|
169
|
+
* suppress biometric unlock and return "not signed in" instead.
|
|
170
|
+
*/
|
|
171
|
+
var OpShell = class {
|
|
172
|
+
spawnImpl;
|
|
173
|
+
binary;
|
|
174
|
+
account;
|
|
175
|
+
constructor(opts = {}) {
|
|
176
|
+
this.spawnImpl = opts.spawn ?? spawnSync;
|
|
177
|
+
this.binary = opts.binary ?? "op";
|
|
178
|
+
if (opts.account !== void 0) this.account = opts.account;
|
|
179
|
+
}
|
|
180
|
+
/** Run `op <args>`, returning a uniform result. */
|
|
181
|
+
run(args, opts = {}) {
|
|
182
|
+
const fullArgs = this.account && !opts.skipAccount ? [
|
|
183
|
+
"--account",
|
|
184
|
+
this.account,
|
|
185
|
+
...args
|
|
186
|
+
] : args;
|
|
187
|
+
const out = this.spawnImpl(this.binary, fullArgs, {
|
|
188
|
+
encoding: "utf-8",
|
|
189
|
+
stdio: [
|
|
190
|
+
"inherit",
|
|
191
|
+
"pipe",
|
|
192
|
+
"pipe"
|
|
193
|
+
]
|
|
194
|
+
});
|
|
195
|
+
if (out.error) return {
|
|
196
|
+
ok: false,
|
|
197
|
+
stdout: "",
|
|
198
|
+
stderr: out.error.message
|
|
199
|
+
};
|
|
200
|
+
return {
|
|
201
|
+
ok: out.status === 0,
|
|
202
|
+
stdout: (out.stdout ?? "").trim(),
|
|
203
|
+
stderr: (out.stderr ?? "").trim()
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/** Run + throw if non-zero. Mirrors REST clients' `request<T>` ergonomic. */
|
|
207
|
+
runOrThrow(args, context, opts = {}) {
|
|
208
|
+
const result = this.run(args, opts);
|
|
209
|
+
if (!result.ok) throw new ProviderApiError(`1Password ${context} failed: ${result.stderr || "no stderr"}`, 0, result.stderr);
|
|
210
|
+
return result.stdout;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/index.ts
|
|
215
|
+
function createContext(options) {
|
|
216
|
+
if (!options.vault) throw new Error("@theholocron/holocron-plugin-1password requires `vault` in options");
|
|
217
|
+
const verifyOpts = {};
|
|
218
|
+
if (options.spawn !== void 0) verifyOpts.spawn = options.spawn;
|
|
219
|
+
if (options.binary !== void 0) verifyOpts.binary = options.binary;
|
|
220
|
+
verifyOpInstalled(verifyOpts);
|
|
221
|
+
const shellOpts = {};
|
|
222
|
+
if (options.spawn !== void 0) shellOpts.spawn = options.spawn;
|
|
223
|
+
if (options.binary !== void 0) shellOpts.binary = options.binary;
|
|
224
|
+
if (options.account !== void 0) shellOpts.account = options.account;
|
|
225
|
+
return {
|
|
226
|
+
options,
|
|
227
|
+
shell: new OpShell(shellOpts)
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function vault(ctx) {
|
|
231
|
+
return new OpVault(ctx.shell, { vault: ctx.options.vault });
|
|
232
|
+
}
|
|
233
|
+
function createPlugin(options) {
|
|
234
|
+
const ctx = createContext(options);
|
|
235
|
+
return {
|
|
236
|
+
name: "@theholocron/holocron-plugin-1password",
|
|
237
|
+
capabilities: { vault: () => vault(ctx) }
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
//#endregion
|
|
241
|
+
export { AuthError, OpShell, OpVault, createContext, createPlugin, vault, verifyOpInstalled };
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@theholocron/holocron-plugin-1password",
|
|
3
|
+
"version": "2.0.0-alpha.0",
|
|
4
|
+
"description": "Holocron plugin for 1Password. Implements the vault capability via shell-out to the `op` CLI (https://developer.1password.com/docs/cli).",
|
|
5
|
+
"homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-1password#readme",
|
|
6
|
+
"bugs": "https://github.com/theholocron/holocron/issues",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/theholocron/holocron.git",
|
|
10
|
+
"directory": "packages/holocron-plugin-1password"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Newton Koumantzelis",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"main": "./dist/index.mjs",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.mts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"default": "./dist/index.mjs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"@theholocron/cli": "2.0.0-alpha.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@theholocron/tsconfig": "^4.1.0",
|
|
28
|
+
"@tsconfig/node-lts": "^24.0.0",
|
|
29
|
+
"@vitest/coverage-v8": "^3.2.6",
|
|
30
|
+
"eslint": "^9.36.0",
|
|
31
|
+
"globals": "^16.5.0",
|
|
32
|
+
"typescript": "^5.9.3",
|
|
33
|
+
"vitest": "^3.2.6",
|
|
34
|
+
"tsdown": "^0.22.3",
|
|
35
|
+
"@theholocron/cli": "2.0.0-alpha.0"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsdown",
|
|
46
|
+
"lint": "eslint .",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"test": "vitest run",
|
|
49
|
+
"test:watch": "vitest",
|
|
50
|
+
"test:coverage": "vitest run --coverage"
|
|
51
|
+
},
|
|
52
|
+
"types": "./dist/index.d.mts"
|
|
53
|
+
}
|