@theholocron/holocron-plugin-doppler 2.0.0-alpha.20 → 2.0.0-alpha.22
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 +12 -56
- package/dist/index.mjs +26 -83
- package/package.json +9 -8
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:
|
|
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:
|
|
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,
|
|
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,
|
|
1
|
+
import { AuthError, ProviderApiError, createResolveToken, createRestClient } from "@theholocron/cli";
|
|
2
2
|
//#region src/auth.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
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:
|
|
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,
|
|
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.
|
|
3
|
+
"version": "2.0.0-alpha.22",
|
|
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.
|
|
24
|
+
"@theholocron/cli": "2.0.0-alpha.22"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@theholocron/
|
|
29
|
-
"@tsconfig
|
|
30
|
-
"@
|
|
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": "^
|
|
39
|
-
"@theholocron/cli": "2.0.0-alpha.
|
|
39
|
+
"vitest": "^4.1.10",
|
|
40
|
+
"@theholocron/cli": "2.0.0-alpha.22"
|
|
40
41
|
},
|
|
41
42
|
"publishConfig": {
|
|
42
43
|
"access": "public"
|