@distilled.cloud/doppler 1.0.0-rc.12 → 1.0.0-rc.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@distilled.cloud/doppler",
3
- "version": "1.0.0-rc.12",
3
+ "version": "1.0.0-rc.13",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/alchemy-run/distilled",
@@ -64,15 +64,15 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@distilled.cloud/core": "1.0.0-rc.12"
67
+ "@distilled.cloud/core": "1.0.0-rc.13"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@types/bun": "1.3.14",
71
71
  "@types/node": "26.2.0",
72
- "@effect/platform-bun": ">=4.0.0-rc.115 || >=4.0.0"
72
+ "@effect/platform-bun": "^4.0.0"
73
73
  },
74
74
  "peerDependencies": {
75
- "effect": ">=4.0.0-rc.115 || >=4.0.0"
75
+ "effect": "^4.0.0"
76
76
  },
77
77
  "scripts": {
78
78
  "build": "tsc -b",
@@ -24,15 +24,17 @@ export class Credentials extends Context.Service<
24
24
  Effect.Effect<Config>
25
25
  >()("DopplerCredentials") {}
26
26
 
27
- /** Layer from a plain API token + optional base URL. */
27
+ /** Layer from a plain or redacted API token and optional base URL. */
28
28
  export const fromApiKey = (config: {
29
- readonly apiKey: string;
29
+ readonly apiKey: string | Redacted.Redacted<string>;
30
30
  readonly apiBaseUrl?: string;
31
31
  }): Layer.Layer<Credentials> =>
32
32
  Layer.succeed(
33
33
  Credentials,
34
34
  Effect.succeed({
35
- apiKey: Redacted.make(config.apiKey),
35
+ apiKey: Redacted.isRedacted(config.apiKey)
36
+ ? config.apiKey
37
+ : Redacted.make(config.apiKey),
36
38
  apiBaseUrl: config.apiBaseUrl ?? DEFAULT_API_BASE_URL,
37
39
  }),
38
40
  );
package/src/protocol.ts CHANGED
@@ -18,13 +18,13 @@
18
18
  import * as Effect from "effect/Effect";
19
19
  import type * as Layer from "effect/Layer";
20
20
  import * as Redacted from "effect/Redacted";
21
- import type * as HttpClient from "effect/unstable/http/HttpClient";
22
- import type * as HttpClientError from "effect/unstable/http/HttpClientError";
21
+ import type * as HttpClient from "effect/http/HttpClient";
22
+ import type * as HttpClientError from "effect/http/HttpClientError";
23
23
  import type * as API from "@distilled.cloud/core/api";
24
24
  import { makeRestProtocol } from "@distilled.cloud/core/protocol-rest";
25
25
  import type { API_ERRORS, ConfigError } from "@distilled.cloud/core/errors";
26
26
  import { Credentials, type Config } from "./credentials.ts";
27
- import { UnknownDopplerError } from "./errors.ts";
27
+ import { UnknownDopplerError, DopplerParseError } from "./errors.ts";
28
28
 
29
29
  /**
30
30
  * Error channel shared by every generated Doppler operation. Generated
@@ -36,7 +36,8 @@ export type DopplerOpError =
36
36
  | InstanceType<(typeof API_ERRORS)[number]>
37
37
  | UnknownDopplerError
38
38
  | ConfigError
39
- | HttpClientError.HttpClientError;
39
+ | HttpClientError.HttpClientError
40
+ | DopplerParseError;
40
41
 
41
42
  /** Context (requirements) shared by every generated Doppler operation. */
42
43
  export type DopplerOpContext = Credentials | HttpClient.HttpClient;
@@ -52,6 +53,9 @@ export const DopplerProtocol: Layer.Layer<API.Protocol> =
52
53
  baseUrl: (creds) => creds.apiBaseUrl,
53
54
  headers: (creds) => ({
54
55
  Authorization: `Bearer ${Redacted.value(creds.apiKey)}`,
56
+ // Download negotiates its default format from Accept; without it the
57
+ // API returns 415 unless the caller explicitly supplies format=json.
58
+ Accept: "application/json",
55
59
  }),
56
60
  // Doppler's error body is `{ messages?: string[], message?: string,
57
61
  // success?: boolean }`. The factory's default envelope covers `message`;
@@ -88,4 +92,21 @@ export const DopplerProtocol: Layer.Layer<API.Protocol> =
88
92
  message,
89
93
  body,
90
94
  }),
95
+ parseError: ({ body, cause }) => new DopplerParseError({ body, cause }),
96
+ });
97
+
98
+ /** Unauthenticated browser-login operations never resolve or send credentials. */
99
+ export type DopplerPublicOpContext = HttpClient.HttpClient;
100
+ export const DopplerPublicProtocol: Layer.Layer<API.Protocol> =
101
+ makeRestProtocol({
102
+ credentials: Effect.succeed(undefined),
103
+ baseUrl: () => "https://api.doppler.com",
104
+ headers: () => ({ Accept: "application/json" }),
105
+ unknownError: ({ code, message }) =>
106
+ new UnknownDopplerError({
107
+ code: code === undefined ? undefined : String(code),
108
+ message,
109
+ body: undefined,
110
+ }),
111
+ parseError: ({ body, cause }) => new DopplerParseError({ body, cause }),
91
112
  });
@@ -0,0 +1,59 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { runValidationModes } from "@distilled.cloud/core/testing";
3
+ import * as Redacted from "effect/Redacted";
4
+ import { DopplerParseError } from "./errors.ts";
5
+ import * as Retry from "./retry.ts";
6
+ import { generateCliAuth } from "./services/doppler.ts";
7
+ import type { DopplerOpError } from "./protocol.ts";
8
+
9
+ // generateCliAuth declares required `code`, `polling_code` (sensitive), and
10
+ // `auth_url`. It uses the unauthenticated protocol, so no credentials.
11
+ const run = (body: string) =>
12
+ runValidationModes(
13
+ generateCliAuth({
14
+ hostname: "host",
15
+ version: "3.0.0",
16
+ os: "linux",
17
+ arch: "x64",
18
+ }).pipe(Retry.none),
19
+ { body },
20
+ );
21
+
22
+ describe("Doppler response validation", () => {
23
+ test("a matching body succeeds unchanged in both modes", async () => {
24
+ const body = {
25
+ code: "abc",
26
+ polling_code: "secret",
27
+ auth_url: "https://dashboard.doppler.com/workplace/auth/cli",
28
+ };
29
+ const { lenient, strict } = await run(JSON.stringify(body));
30
+ for (const result of [lenient, strict]) {
31
+ expect(result).toMatchObject({
32
+ _tag: "Success",
33
+ success: { code: body.code, auth_url: body.auth_url },
34
+ });
35
+ const pollingCode: Redacted.Redacted<string> = (result as any).success
36
+ .polling_code;
37
+ expect(Redacted.value(pollingCode)).toBe("secret");
38
+ }
39
+ });
40
+
41
+ test("a body missing required members: lenient returns it, strict fails", async () => {
42
+ const body = { code: "abc" };
43
+ const { lenient, strict } = await run(JSON.stringify(body));
44
+ expect(lenient).toMatchObject({ _tag: "Success", success: body });
45
+ expect(strict._tag).toBe("Failure");
46
+ expect((strict as any).failure).toBeInstanceOf(DopplerParseError);
47
+ });
48
+
49
+ test("a non-JSON body: lenient returns the text, strict fails", async () => {
50
+ const { lenient, strict } = await run("not json");
51
+ expect(lenient).toMatchObject({ _tag: "Success", success: "not json" });
52
+ expect((strict as any).failure).toBeInstanceOf(DopplerParseError);
53
+ });
54
+ });
55
+
56
+ // DopplerParseError is part of every operation's declared error type.
57
+ export const parseErrorIsDeclared: [DopplerParseError] extends [DopplerOpError]
58
+ ? true
59
+ : false = true;
@@ -6,6 +6,8 @@ import * as C from "@distilled.cloud/core/category";
6
6
  import * as T from "../traits.ts";
7
7
  import {
8
8
  DopplerProtocol,
9
+ DopplerPublicProtocol,
10
+ type DopplerPublicOpContext,
9
11
  type DopplerOpError,
10
12
  type DopplerOpContext,
11
13
  } from "../protocol.ts";
@@ -357,18 +359,44 @@ export const AuthOidcRequest = /*@__PURE__*/ S.suspend(() =>
357
359
  }) as any as S.Schema<AuthOidcRequest>;
358
360
 
359
361
  export interface AuthOidcResponse {
360
- token?: string;
361
- expires_at?: string;
362
+ token: string | Redacted.Redacted<string>;
363
+ expires_at: string;
362
364
  }
363
365
  export const AuthOidcResponse = /*@__PURE__*/ S.suspend(() =>
364
366
  S.Struct({
365
- token: S.optional(S.String),
366
- expires_at: S.optional(S.String),
367
+ token: S.String.pipe(T.SensitiveValue({})),
368
+ expires_at: S.String,
367
369
  }),
368
370
  ).annotate({
369
371
  identifier: "AuthOidcResponse",
370
372
  }) as any as S.Schema<AuthOidcResponse>;
371
373
 
374
+ export interface AuthorizeCliAuthRequest {
375
+ code: string | Redacted.Redacted<string>;
376
+ }
377
+ export const AuthorizeCliAuthRequest = /*@__PURE__*/ S.suspend(() =>
378
+ S.Struct({
379
+ code: S.String.pipe(T.SensitiveValue({})),
380
+ }).pipe(T.Http({ method: "POST", uri: "/v3/auth/cli/authorize", code: 200 })),
381
+ ).annotate({
382
+ identifier: "AuthorizeCliAuthRequest",
383
+ }) as any as S.Schema<AuthorizeCliAuthRequest>;
384
+
385
+ export interface AuthorizeCliAuthResponse {
386
+ token: string | Redacted.Redacted<string>;
387
+ name: string;
388
+ dashboard_url: string;
389
+ }
390
+ export const AuthorizeCliAuthResponse = /*@__PURE__*/ S.suspend(() =>
391
+ S.Struct({
392
+ token: S.String.pipe(T.SensitiveValue({})),
393
+ name: S.String,
394
+ dashboard_url: S.String,
395
+ }),
396
+ ).annotate({
397
+ identifier: "AuthorizeCliAuthResponse",
398
+ }) as any as S.Schema<AuthorizeCliAuthResponse>;
399
+
372
400
  export interface CloneConfigRequest {
373
401
  /** Unique identifier for the project object. */
374
402
  project: string;
@@ -1329,10 +1357,55 @@ export const CreateIntegrationRequest = /*@__PURE__*/ S.suspend(() =>
1329
1357
  identifier: "CreateIntegrationRequest",
1330
1358
  }) as any as S.Schema<CreateIntegrationRequest>;
1331
1359
 
1360
+ export interface CreateIntegrationResponseIntegrationFederationCase0 {
1361
+ kind: string;
1362
+ /** The IAM principal to grant roles to. */
1363
+ principal: string;
1364
+ }
1365
+ export const CreateIntegrationResponseIntegrationFederationCase0 =
1366
+ /*@__PURE__*/ S.suspend(() =>
1367
+ S.Struct({
1368
+ kind: S.String,
1369
+ principal: S.String,
1370
+ }),
1371
+ ).annotate({
1372
+ identifier: "CreateIntegrationResponseIntegrationFederationCase0",
1373
+ }) as any as S.Schema<CreateIntegrationResponseIntegrationFederationCase0>;
1374
+
1375
+ export interface CreateIntegrationResponseIntegrationFederationCase1 {
1376
+ kind: string;
1377
+ /** The issuer to enter on the app registration's federated credential. */
1378
+ issuer: string;
1379
+ /** The subject identifier to enter on the federated credential. */
1380
+ subject: string;
1381
+ /** The audience to enter on the federated credential. */
1382
+ audience: string;
1383
+ }
1384
+ export const CreateIntegrationResponseIntegrationFederationCase1 =
1385
+ /*@__PURE__*/ S.suspend(() =>
1386
+ S.Struct({
1387
+ kind: S.String,
1388
+ issuer: S.String,
1389
+ subject: S.String,
1390
+ audience: S.String,
1391
+ }),
1392
+ ).annotate({
1393
+ identifier: "CreateIntegrationResponseIntegrationFederationCase1",
1394
+ }) as any as S.Schema<CreateIntegrationResponseIntegrationFederationCase1>;
1395
+
1396
+ /** The keyless federation identity Doppler presents to your cloud, or null if this connection does not use keyless authentication. Grant this identity access after creating the connection. */
1397
+ export type CreateIntegrationResponseIntegrationFederation =
1398
+ | CreateIntegrationResponseIntegrationFederationCase0
1399
+ | CreateIntegrationResponseIntegrationFederationCase1;
1400
+ export const CreateIntegrationResponseIntegrationFederation =
1401
+ S.Unknown as any as S.Schema<CreateIntegrationResponseIntegrationFederation>;
1402
+
1332
1403
  export interface CreateIntegrationResponseIntegration {
1333
1404
  slug?: string;
1334
1405
  name?: string;
1335
1406
  type?: string;
1407
+ /** The keyless federation identity Doppler presents to your cloud, or null if this connection does not use keyless authentication. Grant this identity access after creating the connection. */
1408
+ federation?: CreateIntegrationResponseIntegrationFederation | null;
1336
1409
  }
1337
1410
  export const CreateIntegrationResponseIntegration = /*@__PURE__*/ S.suspend(
1338
1411
  () =>
@@ -1340,6 +1413,9 @@ export const CreateIntegrationResponseIntegration = /*@__PURE__*/ S.suspend(
1340
1413
  slug: S.optional(S.String),
1341
1414
  name: S.optional(S.String),
1342
1415
  type: S.optional(S.String),
1416
+ federation: S.optional(
1417
+ S.NullOr(CreateIntegrationResponseIntegrationFederation),
1418
+ ),
1343
1419
  }),
1344
1420
  ).annotate({
1345
1421
  identifier: "CreateIntegrationResponseIntegration",
@@ -1952,9 +2028,9 @@ export const DownloadSecretRequestNameTransformer = S.String;
1952
2028
 
1953
2029
  export interface DownloadSecretRequest {
1954
2030
  /** Unique identifier for the project object. Not required if using a Service Token. */
1955
- project: string;
2031
+ project?: string;
1956
2032
  /** Name of the config object. Not required if using a Service Token. */
1957
- config: string;
2033
+ config?: string;
1958
2034
  format?: DownloadSecretRequestFormat | (string & {});
1959
2035
  /** Transform secret names to a different case */
1960
2036
  name_transformer?: DownloadSecretRequestNameTransformer | (string & {});
@@ -1967,8 +2043,8 @@ export interface DownloadSecretRequest {
1967
2043
  }
1968
2044
  export const DownloadSecretRequest = /*@__PURE__*/ S.suspend(() =>
1969
2045
  S.Struct({
1970
- project: S.String.pipe(T.Query()),
1971
- config: S.String.pipe(T.Query()),
2046
+ project: S.optional(S.String.pipe(T.Query())),
2047
+ config: S.optional(S.String.pipe(T.Query())),
1972
2048
  format: S.optional(DownloadSecretRequestFormat.pipe(T.Query())),
1973
2049
  name_transformer: S.optional(
1974
2050
  DownloadSecretRequestNameTransformer.pipe(T.Query()),
@@ -1987,19 +2063,17 @@ export const DownloadSecretRequest = /*@__PURE__*/ S.suspend(() =>
1987
2063
  identifier: "DownloadSecretRequest",
1988
2064
  }) as any as S.Schema<DownloadSecretRequest>;
1989
2065
 
1990
- export interface DownloadSecretResponse {
1991
- STRIPE?: string;
1992
- ALGOLIA?: string;
1993
- DATABASE?: string;
1994
- USER?: string;
1995
- }
2066
+ export type DownloadSecretResponseBodyMap = {
2067
+ [key: string]: string | undefined;
2068
+ };
2069
+ export const DownloadSecretResponseBodyMap = /*@__PURE__*/ S.Record(
2070
+ S.String,
2071
+ S.String,
2072
+ ) as any as S.Schema<DownloadSecretResponseBodyMap>;
2073
+
2074
+ export type DownloadSecretResponse = DownloadSecretResponseBodyMap;
1996
2075
  export const DownloadSecretResponse = /*@__PURE__*/ S.suspend(() =>
1997
- S.Struct({
1998
- STRIPE: S.optional(S.String),
1999
- ALGOLIA: S.optional(S.String),
2000
- DATABASE: S.optional(S.String),
2001
- USER: S.optional(S.String),
2002
- }),
2076
+ DownloadSecretResponseBodyMap.pipe(T.RawResponseRoot()),
2003
2077
  ).annotate({
2004
2078
  identifier: "DownloadSecretResponse",
2005
2079
  }) as any as S.Schema<DownloadSecretResponse>;
@@ -2114,6 +2188,39 @@ export const EnableWebhookResponse = /*@__PURE__*/ S.suspend(() =>
2114
2188
  identifier: "EnableWebhookResponse",
2115
2189
  }) as any as S.Schema<EnableWebhookResponse>;
2116
2190
 
2191
+ export interface GenerateCliAuthRequest {
2192
+ hostname: string;
2193
+ /** CLI version in vMAJOR.MINOR.PATCH format. Other formats, including prerelease suffixes, are rejected. */
2194
+ version: string;
2195
+ os: string;
2196
+ arch: string;
2197
+ }
2198
+ export const GenerateCliAuthRequest = /*@__PURE__*/ S.suspend(() =>
2199
+ S.Struct({
2200
+ hostname: S.String.pipe(T.Query()),
2201
+ version: S.String.pipe(T.Query()),
2202
+ os: S.String.pipe(T.Query()),
2203
+ arch: S.String.pipe(T.Query()),
2204
+ }).pipe(T.Http({ method: "GET", uri: "/v3/auth/cli/generate/2", code: 200 })),
2205
+ ).annotate({
2206
+ identifier: "GenerateCliAuthRequest",
2207
+ }) as any as S.Schema<GenerateCliAuthRequest>;
2208
+
2209
+ export interface GenerateCliAuthResponse {
2210
+ code: string;
2211
+ polling_code: string | Redacted.Redacted<string>;
2212
+ auth_url: string;
2213
+ }
2214
+ export const GenerateCliAuthResponse = /*@__PURE__*/ S.suspend(() =>
2215
+ S.Struct({
2216
+ code: S.String,
2217
+ polling_code: S.String.pipe(T.SensitiveValue({})),
2218
+ auth_url: S.String,
2219
+ }),
2220
+ ).annotate({
2221
+ identifier: "GenerateCliAuthResponse",
2222
+ }) as any as S.Schema<GenerateCliAuthResponse>;
2223
+
2117
2224
  export interface GetChangeRequestPolicyRequest {
2118
2225
  /** Unique id of the policy */
2119
2226
  slug: string;
@@ -2333,17 +2440,49 @@ export const GetIntegrationRequest = /*@__PURE__*/ S.suspend(() =>
2333
2440
  identifier: "GetIntegrationRequest",
2334
2441
  }) as any as S.Schema<GetIntegrationRequest>;
2335
2442
 
2336
- export type GetIntegrationResponseIntegration =
2337
- CreateIntegrationResponseIntegration;
2338
- export const GetIntegrationResponseIntegration =
2339
- CreateIntegrationResponseIntegration;
2443
+ export type GetIntegrationResponseIntegrationFederationCase0 =
2444
+ CreateIntegrationResponseIntegrationFederationCase0;
2445
+ export const GetIntegrationResponseIntegrationFederationCase0 =
2446
+ CreateIntegrationResponseIntegrationFederationCase0;
2447
+
2448
+ export type GetIntegrationResponseIntegrationFederationCase1 =
2449
+ CreateIntegrationResponseIntegrationFederationCase1;
2450
+ export const GetIntegrationResponseIntegrationFederationCase1 =
2451
+ CreateIntegrationResponseIntegrationFederationCase1;
2452
+
2453
+ /** The keyless federation identity Doppler presents to your cloud, or null if this connection does not use keyless authentication. Grant this identity access after creating the connection. */
2454
+ export type GetIntegrationResponseIntegrationFederation =
2455
+ | CreateIntegrationResponseIntegrationFederationCase0
2456
+ | CreateIntegrationResponseIntegrationFederationCase1;
2457
+ export const GetIntegrationResponseIntegrationFederation =
2458
+ S.Unknown as any as S.Schema<GetIntegrationResponseIntegrationFederation>;
2459
+
2460
+ export interface GetIntegrationResponseIntegration {
2461
+ slug?: string;
2462
+ name?: string;
2463
+ type?: string;
2464
+ /** The keyless federation identity Doppler presents to your cloud, or null if this connection does not use keyless authentication. Grant this identity access after creating the connection. */
2465
+ federation?: GetIntegrationResponseIntegrationFederation | null;
2466
+ }
2467
+ export const GetIntegrationResponseIntegration = /*@__PURE__*/ S.suspend(() =>
2468
+ S.Struct({
2469
+ slug: S.optional(S.String),
2470
+ name: S.optional(S.String),
2471
+ type: S.optional(S.String),
2472
+ federation: S.optional(
2473
+ S.NullOr(GetIntegrationResponseIntegrationFederation),
2474
+ ),
2475
+ }),
2476
+ ).annotate({
2477
+ identifier: "GetIntegrationResponseIntegration",
2478
+ }) as any as S.Schema<GetIntegrationResponseIntegration>;
2340
2479
 
2341
2480
  export interface GetIntegrationResponse {
2342
- integration?: CreateIntegrationResponseIntegration;
2481
+ integration?: GetIntegrationResponseIntegration;
2343
2482
  }
2344
2483
  export const GetIntegrationResponse = /*@__PURE__*/ S.suspend(() =>
2345
2484
  S.Struct({
2346
- integration: S.optional(CreateIntegrationResponseIntegration),
2485
+ integration: S.optional(GetIntegrationResponseIntegration),
2347
2486
  }),
2348
2487
  ).annotate({
2349
2488
  identifier: "GetIntegrationResponse",
@@ -6222,6 +6361,24 @@ export const RevokeAuthResponse = /*@__PURE__*/ S.suspend(() =>
6222
6361
  identifier: "RevokeAuthResponse",
6223
6362
  }) as any as S.Schema<RevokeAuthResponse>;
6224
6363
 
6364
+ export interface RevokeCliAuthRequest {
6365
+ token: string | Redacted.Redacted<string>;
6366
+ }
6367
+ export const RevokeCliAuthRequest = /*@__PURE__*/ S.suspend(() =>
6368
+ S.Struct({
6369
+ token: S.String.pipe(T.SensitiveValue({})),
6370
+ }).pipe(T.Http({ method: "POST", uri: "/v3/auth/cli/revoke", code: 200 })),
6371
+ ).annotate({
6372
+ identifier: "RevokeCliAuthRequest",
6373
+ }) as any as S.Schema<RevokeCliAuthRequest>;
6374
+
6375
+ export type RevokeCliAuthResponse = unknown;
6376
+ export const RevokeCliAuthResponse = /*@__PURE__*/ S.suspend(() =>
6377
+ S.Unknown.pipe(T.RawResponseRoot()),
6378
+ ).annotate({
6379
+ identifier: "RevokeCliAuthResponse",
6380
+ }) as any as S.Schema<RevokeCliAuthResponse>;
6381
+
6225
6382
  export interface SecretsNamesRequest {
6226
6383
  /** Unique identifier for the project object. */
6227
6384
  project: string;
@@ -8279,12 +8436,27 @@ export const authOidc: API.OperationMethod<
8279
8436
  AuthOidcRequest,
8280
8437
  AuthOidcResponse,
8281
8438
  AuthOidcError,
8282
- DopplerOpContext
8439
+ DopplerPublicOpContext
8283
8440
  > = /*@__PURE__*/ API.make(() => ({
8284
8441
  input: AuthOidcRequest,
8285
8442
  output: AuthOidcResponse,
8286
8443
  errors: [UnknownDopplerError],
8287
- protocol: DopplerProtocol,
8444
+ protocol: DopplerPublicProtocol,
8445
+ retry: Retry.Retry,
8446
+ }));
8447
+
8448
+ export type AuthorizeCliAuthError = Conflict | DopplerOpError;
8449
+ /** Doppler CLI browser authentication. Public endpoint; no bearer token required. Wire contract from DopplerHQ/cli pkg/http/api.go. */
8450
+ export const authorizeCliAuth: API.OperationMethod<
8451
+ AuthorizeCliAuthRequest,
8452
+ AuthorizeCliAuthResponse,
8453
+ AuthorizeCliAuthError,
8454
+ DopplerPublicOpContext
8455
+ > = /*@__PURE__*/ API.make(() => ({
8456
+ input: AuthorizeCliAuthRequest,
8457
+ output: AuthorizeCliAuthResponse,
8458
+ errors: [Conflict, UnknownDopplerError],
8459
+ protocol: DopplerPublicProtocol,
8288
8460
  retry: Retry.Retry,
8289
8461
  }));
8290
8462
 
@@ -8802,6 +8974,21 @@ export const enableWebhook: API.OperationMethod<
8802
8974
  retry: Retry.Retry,
8803
8975
  }));
8804
8976
 
8977
+ export type GenerateCliAuthError = DopplerOpError;
8978
+ /** Doppler CLI browser authentication. Public endpoint; no bearer token required. Wire contract from DopplerHQ/cli pkg/http/api.go. */
8979
+ export const generateCliAuth: API.OperationMethod<
8980
+ GenerateCliAuthRequest,
8981
+ GenerateCliAuthResponse,
8982
+ GenerateCliAuthError,
8983
+ DopplerPublicOpContext
8984
+ > = /*@__PURE__*/ API.make(() => ({
8985
+ input: GenerateCliAuthRequest,
8986
+ output: GenerateCliAuthResponse,
8987
+ errors: [UnknownDopplerError],
8988
+ protocol: DopplerPublicProtocol,
8989
+ retry: Retry.Retry,
8990
+ }));
8991
+
8805
8992
  export type GetChangeRequestPolicyError = DopplerOpError;
8806
8993
  /** Retrieve Fetch an existing change request policy */
8807
8994
  export const getChangeRequestPolicy: API.OperationMethod<
@@ -9642,6 +9829,21 @@ export const revokeAuth: API.OperationMethod<
9642
9829
  retry: Retry.Retry,
9643
9830
  }));
9644
9831
 
9832
+ export type RevokeCliAuthError = DopplerOpError;
9833
+ /** Doppler CLI browser authentication. Public endpoint; no bearer token required. Wire contract from DopplerHQ/cli pkg/http/api.go. */
9834
+ export const revokeCliAuth: API.OperationMethod<
9835
+ RevokeCliAuthRequest,
9836
+ RevokeCliAuthResponse,
9837
+ RevokeCliAuthError,
9838
+ DopplerPublicOpContext
9839
+ > = /*@__PURE__*/ API.make(() => ({
9840
+ input: RevokeCliAuthRequest,
9841
+ output: RevokeCliAuthResponse,
9842
+ errors: [UnknownDopplerError],
9843
+ protocol: DopplerPublicProtocol,
9844
+ retry: Retry.Retry,
9845
+ }));
9846
+
9645
9847
  export type SecretsNamesError = DopplerOpError;
9646
9848
  /** List Names Secret Names */
9647
9849
  export const secretsNames: API.OperationMethod<