@theholocron/holocron-plugin-doppler 2.0.0-alpha.19 → 2.0.0-alpha.21

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/dist/index.d.mts CHANGED
@@ -1,58 +1,7 @@
1
- import { EnsureResult, Vault } from "@theholocron/cli";
1
+ import { AuthError, EnsureResult, ResolveTokenInput, RestClient, RestClient as RestClient$1, Vault } from "@theholocron/cli";
2
2
 
3
3
  //#region src/auth.d.ts
4
- /**
5
- * Token resolution for the Doppler plugin.
6
- *
7
- * Resolution order (matches the standard 4-step precedence set by
8
- * `.notes/tech-auth-bootstrap.spec.md`):
9
- * 1. explicit `cliToken` argument (from `--token` flag)
10
- * 2. HOLOCRON_DOPPLER_TOKEN env var (preferred — explicit intent)
11
- * 3. DOPPLER_TOKEN env var (Doppler-native, works in CI)
12
- * 4. keyring (com.theholocron.cli / "doppler")
13
- * 5. AuthError with a hint pointing at `doppler configure`
14
- */
15
- declare class AuthError extends Error {
16
- name: string;
17
- }
18
- interface ResolveTokenInput {
19
- /** From `--token` CLI flag. */
20
- cliToken?: string;
21
- /** Env vars; passed in for testability. Defaults to `process.env`. */
22
- env?: NodeJS.ProcessEnv;
23
- /** Keyring lookup fn; passed in for testability. Defaults to `getToken(provider)`. */
24
- keyring?: (provider: string) => string | null;
25
- }
26
- declare function resolveToken(input?: ResolveTokenInput): string;
27
- //#endregion
28
- //#region src/rest.d.ts
29
- /**
30
- * Thin REST wrapper around api.doppler.com/v3.
31
- *
32
- * Same pattern as the GitHub / Vercel / Neon REST clients — bearer
33
- * auth, JSON-only bodies, transport-failure wrapping with `status: 0`
34
- * so the orchestrator's soft-skip path sees a clear "Doppler GET /path
35
- * failed" message instead of a generic `TypeError: fetch failed`.
36
- */
37
- interface RestClientOptions {
38
- token: string;
39
- fetch?: typeof fetch;
40
- baseUrl?: string;
41
- }
42
- interface RequestOptions {
43
- method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
44
- body?: unknown;
45
- query?: Record<string, string>;
46
- /** Treat this response as void even if 200 is returned. */
47
- expectNoContent?: boolean;
48
- }
49
- declare class DopplerRestClient {
50
- private readonly token;
51
- private readonly fetchImpl;
52
- readonly baseUrl: string;
53
- constructor(opts: RestClientOptions);
54
- request<T>(path: string, opts?: RequestOptions): Promise<T>;
55
- }
4
+ declare const resolveToken: (input?: import("@theholocron/http-client").ResolveTokenInput) => string;
56
5
  //#endregion
57
6
  //#region src/capabilities/vault.d.ts
58
7
  interface DopplerVaultOptions {
@@ -67,7 +16,7 @@ declare class DopplerVault implements Vault {
67
16
  readonly providerName = "doppler";
68
17
  private readonly project;
69
18
  private readonly config;
70
- constructor(rest: DopplerRestClient, opts: DopplerVaultOptions);
19
+ constructor(rest: RestClient, opts: DopplerVaultOptions);
71
20
  read(reference: string): Promise<string>;
72
21
  write(reference: string, value: string): Promise<void>;
73
22
  list(): Promise<string[]>;
@@ -77,6 +26,13 @@ declare class DopplerVault implements Vault {
77
26
  ensureEnvironment(project: string, name: string): Promise<EnsureResult>;
78
27
  }
79
28
  //#endregion
29
+ //#region src/rest.d.ts
30
+ declare function createDopplerRestClient(opts: {
31
+ token: string;
32
+ baseUrl?: string;
33
+ fetch?: typeof fetch;
34
+ }): RestClient$1;
35
+ //#endregion
80
36
  //#region src/verify-token.d.ts
81
37
  /**
82
38
  * `verifyToken` — plugin-level export used by `holocron auth set` +
@@ -112,7 +68,7 @@ interface DopplerPluginOptions extends ResolveTokenInput, DopplerVaultOptions {
112
68
  }
113
69
  interface PluginContext {
114
70
  options: DopplerPluginOptions;
115
- rest: DopplerRestClient;
71
+ rest: RestClient;
116
72
  }
117
73
  declare function createContext(options: DopplerPluginOptions): PluginContext;
118
74
  declare function vault(ctx: PluginContext): Vault;
@@ -128,4 +84,4 @@ declare function createPlugin(options: DopplerPluginOptions): {
128
84
  */
129
85
  declare const AUTH_HINT: string;
130
86
  //#endregion
131
- export { AUTH_HINT, AuthError, DopplerPluginOptions, DopplerRestClient, DopplerVault, PluginContext, ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createPlugin, resolveToken, vault, verifyToken };
87
+ export { AUTH_HINT, AuthError, DopplerPluginOptions, DopplerVault, PluginContext, type ResolveTokenInput, type VerifyTokenFailure, type VerifyTokenResult, type VerifyTokenSuccess, createContext, createDopplerRestClient, createPlugin, resolveToken, vault, verifyToken };
package/dist/index.mjs CHANGED
@@ -1,26 +1,11 @@
1
- import { ProviderApiError, getToken } from "@theholocron/cli";
1
+ import { AuthError, ProviderApiError, createResolveToken, createRestClient } from "@theholocron/cli";
2
2
  //#region src/auth.ts
3
- /**
4
- * Token resolution for the Doppler plugin.
5
- *
6
- * Resolution order (matches the standard 4-step precedence set by
7
- * `.notes/tech-auth-bootstrap.spec.md`):
8
- * 1. explicit `cliToken` argument (from `--token` flag)
9
- * 2. HOLOCRON_DOPPLER_TOKEN env var (preferred — explicit intent)
10
- * 3. DOPPLER_TOKEN env var (Doppler-native, works in CI)
11
- * 4. keyring (com.theholocron.cli / "doppler")
12
- * 5. AuthError with a hint pointing at `doppler configure`
13
- */
14
- var AuthError = class extends Error {
15
- name = "AuthError";
16
- };
17
- function resolveToken(input = {}) {
18
- const env = input.env ?? process.env;
19
- const keyring = input.keyring ?? getToken;
20
- const token = input.cliToken || env.HOLOCRON_DOPPLER_TOKEN || env.DOPPLER_TOKEN || keyring("doppler");
21
- if (!token) throw new AuthError("no Doppler token found. Pass --token <TOKEN>, set HOLOCRON_DOPPLER_TOKEN / DOPPLER_TOKEN, or run: holocron auth set doppler $(doppler configure get token --plain)");
22
- return token;
23
- }
3
+ const resolveToken = createResolveToken({
4
+ envName: "HOLOCRON_DOPPLER_TOKEN",
5
+ vendorEnvName: "DOPPLER_TOKEN",
6
+ keyringService: "doppler",
7
+ errorMessage: "no Doppler token found. Pass --token <TOKEN>, set HOLOCRON_DOPPLER_TOKEN / DOPPLER_TOKEN, or run: holocron auth set doppler $(doppler configure get token --plain)"
8
+ });
24
9
  //#endregion
25
10
  //#region src/capabilities/vault.ts
26
11
  /**
@@ -172,58 +157,14 @@ function hasAlreadyExistsBody(details) {
172
157
  }
173
158
  //#endregion
174
159
  //#region src/rest.ts
175
- /**
176
- * Thin REST wrapper around api.doppler.com/v3.
177
- *
178
- * Same pattern as the GitHub / Vercel / Neon REST clients — bearer
179
- * auth, JSON-only bodies, transport-failure wrapping with `status: 0`
180
- * so the orchestrator's soft-skip path sees a clear "Doppler GET /path
181
- * failed" message instead of a generic `TypeError: fetch failed`.
182
- */
183
- var DopplerRestClient = class {
184
- token;
185
- fetchImpl;
186
- baseUrl;
187
- constructor(opts) {
188
- this.token = opts.token;
189
- this.fetchImpl = opts.fetch ?? globalThis.fetch;
190
- let url = opts.baseUrl ?? "https://api.doppler.com/v3";
191
- while (url.endsWith("/")) url = url.slice(0, -1);
192
- this.baseUrl = url;
193
- }
194
- async request(path, opts = {}) {
195
- const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : "/" + path}`);
196
- for (const [k, v] of Object.entries(opts.query ?? {})) url.searchParams.set(k, v);
197
- const fullUrl = url.toString();
198
- const headers = {
199
- authorization: `Bearer ${this.token}`,
200
- accept: "application/json"
201
- };
202
- const init = {
203
- method: opts.method ?? "GET",
204
- headers
205
- };
206
- if (opts.body !== void 0) {
207
- headers["content-type"] = "application/json";
208
- init.body = JSON.stringify(opts.body);
209
- }
210
- let res;
211
- try {
212
- res = await this.fetchImpl(fullUrl, init);
213
- } catch (err) {
214
- const detail = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
215
- throw new ProviderApiError(`Doppler ${init.method} ${path} failed: ${detail}`, 0, void 0);
216
- }
217
- if (!res.ok) {
218
- const body = await res.text().catch(() => "");
219
- throw new ProviderApiError(`Doppler ${init.method} ${path} → ${res.status}`, res.status, body);
220
- }
221
- if (opts.expectNoContent || res.status === 204) return void 0;
222
- const text = await res.text();
223
- if (!text) return void 0;
224
- return JSON.parse(text);
225
- }
226
- };
160
+ function createDopplerRestClient(opts) {
161
+ return createRestClient({
162
+ baseUrl: opts.baseUrl ?? "https://api.doppler.com/v3",
163
+ token: opts.token,
164
+ vendor: "Doppler",
165
+ fetch: opts.fetch
166
+ });
167
+ }
227
168
  //#endregion
228
169
  //#region src/verify-token.ts
229
170
  /**
@@ -237,10 +178,11 @@ var DopplerRestClient = class {
237
178
  * what we don't have yet at bootstrap time.
238
179
  */
239
180
  async function verifyToken(token, opts = {}) {
240
- const restOpts = { token };
241
- if (opts.baseUrl !== void 0) restOpts.baseUrl = opts.baseUrl;
242
- if (opts.fetch !== void 0) restOpts.fetch = opts.fetch;
243
- const rest = new DopplerRestClient(restOpts);
181
+ const rest = createDopplerRestClient({
182
+ token,
183
+ baseUrl: opts.baseUrl,
184
+ fetch: opts.fetch
185
+ });
244
186
  try {
245
187
  const me = await rest.request("/me");
246
188
  const workplace = me.workplace?.name ?? me.slug ?? "unknown";
@@ -258,12 +200,13 @@ async function verifyToken(token, opts = {}) {
258
200
  //#endregion
259
201
  //#region src/index.ts
260
202
  function createContext(options) {
261
- const restOpts = { token: resolveToken(options) };
262
- if (options.baseUrl !== void 0) restOpts.baseUrl = options.baseUrl;
263
- if (options.fetch !== void 0) restOpts.fetch = options.fetch;
264
203
  return {
265
204
  options,
266
- rest: new DopplerRestClient(restOpts)
205
+ rest: createDopplerRestClient({
206
+ token: resolveToken(options),
207
+ baseUrl: options.baseUrl,
208
+ fetch: options.fetch
209
+ })
267
210
  };
268
211
  }
269
212
  function vault(ctx) {
@@ -285,4 +228,4 @@ function createPlugin(options) {
285
228
  */
286
229
  const AUTH_HINT = "install the Doppler CLI (`brew install dopplerhq/cli/doppler`), run `doppler login`, then `holocron auth set doppler $(doppler configure get token --plain)`";
287
230
  //#endregion
288
- export { AUTH_HINT, AuthError, DopplerRestClient, DopplerVault, createContext, createPlugin, resolveToken, vault, verifyToken };
231
+ export { AUTH_HINT, AuthError, DopplerVault, createContext, createDopplerRestClient, createPlugin, resolveToken, vault, verifyToken };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theholocron/holocron-plugin-doppler",
3
- "version": "2.0.0-alpha.19",
3
+ "version": "2.0.0-alpha.21",
4
4
  "description": "Holocron plugin for Doppler. Implements the vault capability against Doppler's REST API — projects, configs, secrets, plus verifyToken + AUTH_HINT for `holocron auth`.",
5
5
  "homepage": "https://github.com/theholocron/holocron/tree/main/packages/holocron-plugin-doppler#readme",
6
6
  "bugs": "https://github.com/theholocron/holocron/issues",
@@ -21,13 +21,14 @@
21
21
  }
22
22
  },
23
23
  "peerDependencies": {
24
- "@theholocron/cli": "2.0.0-alpha.19"
24
+ "@theholocron/cli": "2.0.0-alpha.21"
25
25
  },
26
26
  "devDependencies": {
27
- "@theholocron/eslint-config": "^5.1.1",
28
- "@theholocron/tsconfig": "^4.1.0",
29
- "@tsconfig/node-lts": "^24.0.0",
30
- "@vitest/coverage-v8": "^3.2.6",
27
+ "@types/node": "^26",
28
+ "@theholocron/eslint-config": "^5.2.0",
29
+ "@theholocron/tsconfig": "^6.0.0",
30
+ "@theholocron/tsdown-config": "^5.1.2",
31
+ "@theholocron/vitest-config": "^5.2.0",
31
32
  "@vitest/eslint-plugin": "^1.6.23",
32
33
  "eslint": "^10.7.0",
33
34
  "eslint-plugin-n": "^18.2.2",
@@ -35,8 +36,8 @@
35
36
  "tsdown": "^0.22.3",
36
37
  "tsx": "^4.22.4",
37
38
  "typescript": "^5.9.3",
38
- "vitest": "^3.2.6",
39
- "@theholocron/cli": "2.0.0-alpha.19"
39
+ "vitest": "^4.1.10",
40
+ "@theholocron/cli": "2.0.0-alpha.21"
40
41
  },
41
42
  "publishConfig": {
42
43
  "access": "public"