@homeflare/alchemy 0.48.0 → 0.49.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.
Files changed (97) hide show
  1. package/README.md +11 -0
  2. package/dist/cloudflare/cloudflared-tunnel-api.d.ts +87 -0
  3. package/dist/cloudflare/cloudflared-tunnel-api.d.ts.map +1 -0
  4. package/dist/cloudflare/cloudflared-tunnel-form.d.ts +49 -0
  5. package/dist/cloudflare/cloudflared-tunnel-form.d.ts.map +1 -0
  6. package/dist/cloudflare/cloudflared-tunnel-harness.d.ts +45 -0
  7. package/dist/cloudflare/cloudflared-tunnel-harness.d.ts.map +1 -0
  8. package/dist/cloudflare/cloudflared-tunnel-lifecycle.d.ts +21 -0
  9. package/dist/cloudflare/cloudflared-tunnel-lifecycle.d.ts.map +1 -0
  10. package/dist/cloudflare/cloudflared-tunnel.d.ts +39 -0
  11. package/dist/cloudflare/cloudflared-tunnel.d.ts.map +1 -0
  12. package/dist/cloudflare/fake-access.d.ts +40 -0
  13. package/dist/cloudflare/fake-access.d.ts.map +1 -0
  14. package/dist/cloudflare/fake-mesh.d.ts +7 -2
  15. package/dist/cloudflare/fake-mesh.d.ts.map +1 -1
  16. package/dist/cloudflare/fake-tunnel.d.ts +48 -0
  17. package/dist/cloudflare/fake-tunnel.d.ts.map +1 -0
  18. package/dist/cloudflare/index.d.ts +15 -4
  19. package/dist/cloudflare/index.d.ts.map +1 -1
  20. package/dist/cloudflare/index.js +518 -7
  21. package/dist/cloudflare/index.js.map +15 -4
  22. package/dist/cloudflare/providers.d.ts +1 -1
  23. package/dist/cloudflare/providers.d.ts.map +1 -1
  24. package/dist/cloudflare/saas-oidc-api.d.ts +88 -0
  25. package/dist/cloudflare/saas-oidc-api.d.ts.map +1 -0
  26. package/dist/cloudflare/saas-oidc-consumer.d.ts +22 -0
  27. package/dist/cloudflare/saas-oidc-consumer.d.ts.map +1 -0
  28. package/dist/cloudflare/saas-oidc-error.d.ts +22 -0
  29. package/dist/cloudflare/saas-oidc-error.d.ts.map +1 -0
  30. package/dist/cloudflare/saas-oidc-form.d.ts +48 -0
  31. package/dist/cloudflare/saas-oidc-form.d.ts.map +1 -0
  32. package/dist/cloudflare/saas-oidc-harness.d.ts +50 -0
  33. package/dist/cloudflare/saas-oidc-harness.d.ts.map +1 -0
  34. package/dist/cloudflare/saas-oidc-lifecycle.d.ts +14 -0
  35. package/dist/cloudflare/saas-oidc-lifecycle.d.ts.map +1 -0
  36. package/dist/cloudflare/saas-oidc-props.d.ts +139 -0
  37. package/dist/cloudflare/saas-oidc-props.d.ts.map +1 -0
  38. package/dist/cloudflare/saas-oidc-team.d.ts +9 -0
  39. package/dist/cloudflare/saas-oidc-team.d.ts.map +1 -0
  40. package/dist/cloudflare/saas-oidc-wire.d.ts +58 -0
  41. package/dist/cloudflare/saas-oidc-wire.d.ts.map +1 -0
  42. package/dist/cloudflare/saas-oidc.d.ts +36 -0
  43. package/dist/cloudflare/saas-oidc.d.ts.map +1 -0
  44. package/dist/talos/cluster-adapter-errors.d.ts.map +1 -1
  45. package/dist/talos/cluster-adapter.d.ts +2 -1
  46. package/dist/talos/cluster-adapter.d.ts.map +1 -1
  47. package/dist/talos/index.js +19 -8
  48. package/dist/talos/index.js.map +6 -6
  49. package/dist/talos/mint-temp-file.d.ts.map +1 -1
  50. package/dist/talos/talosctl.d.ts +29 -0
  51. package/dist/talos/talosctl.d.ts.map +1 -1
  52. package/docs/cloudflared-tunnel.md +136 -0
  53. package/docs/credentials.md +1 -1
  54. package/docs/ownership.md +3 -2
  55. package/docs/saas-oidc.md +185 -0
  56. package/docs/talos-openbao-adapter.md +3 -2
  57. package/docs/upstream-conformance-families.md +1 -1
  58. package/docs/upstream-conformance.md +3 -0
  59. package/package.json +1 -1
  60. package/src/cloudflare/cloudflared-tunnel-api.ts +150 -0
  61. package/src/cloudflare/cloudflared-tunnel-edges.test.ts +179 -0
  62. package/src/cloudflare/cloudflared-tunnel-form.ts +78 -0
  63. package/src/cloudflare/cloudflared-tunnel-harness.ts +126 -0
  64. package/src/cloudflare/cloudflared-tunnel-lifecycle.ts +146 -0
  65. package/src/cloudflare/cloudflared-tunnel-state.test.ts +104 -0
  66. package/src/cloudflare/cloudflared-tunnel.test.ts +164 -0
  67. package/src/cloudflare/cloudflared-tunnel.ts +116 -0
  68. package/src/cloudflare/fake-access.ts +196 -0
  69. package/src/cloudflare/fake-mesh.ts +6 -3
  70. package/src/cloudflare/fake-tunnel.ts +148 -0
  71. package/src/cloudflare/index.ts +27 -4
  72. package/src/cloudflare/providers.ts +16 -3
  73. package/src/cloudflare/saas-oidc-api.ts +224 -0
  74. package/src/cloudflare/saas-oidc-consumer.ts +35 -0
  75. package/src/cloudflare/saas-oidc-error.ts +52 -0
  76. package/src/cloudflare/saas-oidc-form.test.ts +227 -0
  77. package/src/cloudflare/saas-oidc-form.ts +190 -0
  78. package/src/cloudflare/saas-oidc-harness.ts +140 -0
  79. package/src/cloudflare/saas-oidc-lifecycle.ts +150 -0
  80. package/src/cloudflare/saas-oidc-parse-error.test.ts +180 -0
  81. package/src/cloudflare/saas-oidc-props.ts +147 -0
  82. package/src/cloudflare/saas-oidc-read.test.ts +85 -0
  83. package/src/cloudflare/saas-oidc-stable.test.ts +38 -0
  84. package/src/cloudflare/saas-oidc-state.test.ts +128 -0
  85. package/src/cloudflare/saas-oidc-team.test.ts +88 -0
  86. package/src/cloudflare/saas-oidc-team.ts +70 -0
  87. package/src/cloudflare/saas-oidc-wire.ts +116 -0
  88. package/src/cloudflare/saas-oidc.test.ts +201 -0
  89. package/src/cloudflare/saas-oidc.ts +107 -0
  90. package/src/talos/cluster-adapter-errors.ts +2 -1
  91. package/src/talos/cluster-adapter-move.test.ts +2 -0
  92. package/src/talos/cluster-adapter.ts +2 -1
  93. package/src/talos/mint-temp-file.test.ts +44 -0
  94. package/src/talos/mint-temp-file.ts +16 -4
  95. package/src/talos/talosctl-probe-kill.test.ts +56 -0
  96. package/src/talos/talosctl.test.ts +54 -1
  97. package/src/talos/talosctl.ts +34 -2
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `HomeFlare.Access.SaasOidcApplication` — the pure helpers the lifecycle uses: validation, the
3
+ * issuer URLs, drift, the write body and the attribute mapping. The props and attributes types are
4
+ * declared in saas-oidc-props.ts and re-exported here.
5
+ *
6
+ * ⛔ THE ATTRIBUTES NEVER HOLD THE CLIENT SECRET, and nothing here can: `ObservedApp`
7
+ * (saas-oidc-api.ts) has no field for it. A client that authenticates with PKCE alone declares
8
+ * `allowPkceWithoutClientSecret: true`, and then no secret exists to keep.
9
+ * ★ THE ISSUER IS `https://<teamDomain>/cdn-cgi/access/sso/oidc/<clientId>`. The team domain is a
10
+ * prop; the openbao copy this came from hardcoded one account's. Cloudflare also reports the
11
+ * same host in the app's own `domain` field (Alchemy's `Access.Application` doc: for `saas`
12
+ * "Cloudflare uses the OIDC issuer"), and `checkTeam` refuses a declaration that disagrees with it.
13
+ */
14
+ import { SaasOidcError } from './saas-oidc-error.ts';
15
+ import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-props.ts';
16
+ import type { AppWrite, ObservedApp } from './saas-oidc-wire.ts';
17
+ export type { OidcGrantType, OidcScope, SaasOidcApplicationAttributes, SaasOidcApplicationProps, } from './saas-oidc-props.ts';
18
+ /** ⛔ Fail closed on a declaration the API would accept but nobody meant. */
19
+ export declare const validateSaasOidc: (props: SaasOidcApplicationProps) => SaasOidcError | undefined;
20
+ export declare const issuerFor: (teamDomain: string, clientId: string) => string;
21
+ /**
22
+ * ⛔ A DECLARED TEAM DOMAIN THAT DISAGREES WITH THE APP'S OWN `domain` is refused: the issuer in
23
+ * the attributes would point at a different team than the one that holds the app.
24
+ * ⛔ WHEN CLOUDFLARE REPORTS NO `domain` there is nothing to compare, so the team the row already
25
+ * recorded (`knownTeam`, from state) stands in: a declaration that moves it is refused, because
26
+ * `issuer` is a declared stable and must not move under the row. With no `knownTeam` either
27
+ * (a first create or a cold adoption) there is nothing to compare against and the declaration
28
+ * stands.
29
+ */
30
+ export declare const checkTeam: (teamDomain: string, app: ObservedApp, knownTeam?: string) => SaasOidcError | undefined;
31
+ /** The request body for a create or an update. */
32
+ export declare const writeBody: (news: SaasOidcApplicationProps, name: string) => AppWrite;
33
+ /**
34
+ * Does the live app differ from the declaration? Compared: name, auth type, redirect URIs, scopes,
35
+ * grant types (each as a set), both lifetimes, the PKCE flag and the policies IN ORDER — the
36
+ * openbao copy's set plus the policy order, kept so adopting a live app is not newly a write.
37
+ * ⚠️ NOT COMPARED: `sessionDuration`, `allowedIdps`, `autoRedirectToIdentity`, `appLauncherVisible`,
38
+ * `appLauncherUrl`. They are written on create and on any sync, but a change to only those does
39
+ * not trigger one. Carried over unchanged; see saas-oidc.md.
40
+ */
41
+ export declare const needsSync: (news: SaasOidcApplicationProps, observed: ObservedApp, name: string) => boolean;
42
+ /**
43
+ * The attributes of a live app, or `undefined` when it lacks an id, an `aud` or a client id (so it
44
+ * is not a SaaS OIDC app this package can describe). `teamDomain` is the declared one, or, for a
45
+ * read that has no declaration (state written before the prop existed), the host Cloudflare reports.
46
+ */
47
+ export declare const toAttributes: (app: ObservedApp, accountId: string, fallbackName: string, declaredTeam: string | undefined) => SaasOidcApplicationAttributes | undefined;
48
+ //# sourceMappingURL=saas-oidc-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-form.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-form.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIjE,YAAY,EACV,aAAa,EACb,SAAS,EACT,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAI9B,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,UAAW,wBAAwB,KAAG,aAAa,GAAG,SAmBlF,CAAC;AAEF,eAAO,MAAM,SAAS,eAAgB,MAAM,YAAY,MAAM,KAAG,MACJ,CAAC;AAI9D;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,eACR,MAAM,OACb,WAAW,cACJ,MAAM,KACjB,aAAa,GAAG,SAalB,CAAC;AAKF,kDAAkD;AAClD,eAAO,MAAM,SAAS,SAAU,wBAAwB,QAAQ,MAAM,KAAG,QAmBvE,CAAC;AAgBH;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,SACd,wBAAwB,YACpB,WAAW,QACf,MAAM,KACX,OAcF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAClB,WAAW,aACL,MAAM,gBACH,MAAM,gBACN,MAAM,GAAG,SAAS,KAC/B,6BAA6B,GAAG,SA6BlC,CAAC"}
@@ -0,0 +1,50 @@
1
+ import * as State from 'alchemy/State';
2
+ import * as Effect from 'effect/Effect';
3
+ import * as Exit from 'effect/Exit';
4
+ import * as Layer from 'effect/Layer';
5
+ import { type FakeAccess } from './fake-access.ts';
6
+ import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-form.ts';
7
+ import { SaasOidcApplication } from './saas-oidc.ts';
8
+ export declare const strict: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
9
+ export declare const ids: {
10
+ fqn: string;
11
+ id: string;
12
+ instanceId: string;
13
+ };
14
+ export declare const extra: {
15
+ bindings: never;
16
+ session: never;
17
+ };
18
+ export type P = Effect.Success<typeof SaasOidcApplication.Provider>;
19
+ /** A public PKCE client, the shape Headlamp declares (Q6). */
20
+ export declare const publicClient: (over?: Partial<SaasOidcApplicationProps>) => SaasOidcApplicationProps;
21
+ /** The wire `saas_app` of a live app that matches `publicClient()` exactly (no drift to sync). */
22
+ export declare const LIVE_OIDC: {
23
+ auth_type: string;
24
+ redirect_uris: string[];
25
+ scopes: string[];
26
+ grant_types: string[];
27
+ access_token_lifetime: string;
28
+ allow_pkce_without_client_secret: boolean;
29
+ };
30
+ /** Build the provider over the fake and hand it to `use`. */
31
+ export declare const run: <A, E>(fake: FakeAccess, use: (p: P) => Effect.Effect<A, E, never>) => Promise<A>;
32
+ export declare const reconcile: (p: P, news: SaasOidcApplicationProps, output?: SaasOidcApplicationAttributes) => Effect.Effect<SaasOidcApplicationAttributes, any, never>;
33
+ export declare const read: (p: P, olds: SaasOidcApplicationProps, output?: SaasOidcApplicationAttributes) => Effect.Effect<SaasOidcApplicationAttributes | undefined, any, never>;
34
+ /** The writes the fake saw, in order: `['POST', 'PUT', …]`. */
35
+ export declare const writes: (fake: FakeAccess) => string[];
36
+ type Rows = Record<string, Record<string, Record<string, State.ResourceState>>>;
37
+ /**
38
+ * ★ THE REAL ENGINE, NOT A MODEL OF IT: `Plan.make` + `apply` over an in-memory state store, as
39
+ * mesh-node-harness.ts does. `rows` is that store, so a test can serialise exactly what Alchemy
40
+ * would persist.
41
+ */
42
+ export declare const engine: (fake: FakeAccess, extra?: Layer.Layer<never, never, never>) => {
43
+ deploy: <A, E, R>(declare: Effect.Effect<A, E, R>) => Promise<Exit.Exit<unknown, unknown>>;
44
+ rows: Rows;
45
+ status: (fqn: string) => "created" | "creating" | "deleting" | "replaced" | "replacing" | "updated" | "updating" | undefined;
46
+ };
47
+ /** The failure sentence of a deploy, or `''` when it succeeded. */
48
+ export declare const failureOf: (exit: Exit.Exit<unknown, unknown>) => string;
49
+ export {};
50
+ //# sourceMappingURL=saas-oidc-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-harness.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-harness.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,KAAK,MAAM,eAAe,CAAC;AAGvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAA+B,MAAM,gBAAgB,CAAC;AAclF,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CACpB,CAAC;AAEnE,eAAO,MAAM,GAAG;IAAK,GAAG;IAAoB,EAAE;IAAc,UAAU;CAAS,CAAC;AAChF,eAAO,MAAM,KAAK;IAAK,QAAQ,EAAQ,KAAK;IAAE,OAAO,EAAe,KAAK;CAAE,CAAC;AAE5E,MAAM,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AAEpE,8DAA8D;AAC9D,eAAO,MAAM,YAAY,UACjB,OAAO,CAAC,wBAAwB,CAAC,KACtC,wBAaD,CAAC;AAEH,kGAAkG;AAClG,eAAO,MAAM,SAAS;IACpB,SAAS;IACT,aAAa;IACb,MAAM;IACN,WAAW;IACX,qBAAqB;IACrB,gCAAgC;CACjC,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,CAAC,QAAQ,UAAU,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,eAWlF,CAAC;AAEJ,eAAO,MAAM,SAAS,MACjB,CAAC,QACE,wBAAwB,WACrB,6BAA6B,6DAC6B,CAAC;AAEtE,eAAO,MAAM,IAAI,MACZ,CAAC,QACE,wBAAwB,WACrB,6BAA6B,yEAKvC,CAAC;AAEF,+DAA+D;AAC/D,eAAO,MAAM,MAAM,SAAU,UAAU,aAC2B,CAAC;AAEnE,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,MAAM,SAAU,UAAU,UAAS,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;aAO9D,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;;kBAexC,MAAM;CAEvB,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,SAAS,SAAU,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,WACG,CAAC"}
@@ -0,0 +1,14 @@
1
+ import * as Effect from 'effect/Effect';
2
+ import { SaasOidcError } from './saas-oidc-error.ts';
3
+ import { type SaasOidcApplicationAttributes, type SaasOidcApplicationProps } from './saas-oidc-form.ts';
4
+ /**
5
+ * Owned: refresh by the stored id ONLY (gone is `undefined`, never a same-named app). Cold: find the app by `applicationId` or exact name and hand it
6
+ * back `Unowned`, so Alchemy refuses to take it over until the stack says `adopt(true)`.
7
+ * ★ `olds` MAY PREDATE `teamDomain` (state written by the openbao copy of this resource): the host
8
+ * Cloudflare reports for the app stands in, so the first plan after the move can still read.
9
+ */
10
+ export declare const readSaasOidc: (accountId: string, id: string, olds: SaasOidcApplicationProps | undefined, output: SaasOidcApplicationAttributes | undefined) => Effect.Effect<SaasOidcApplicationAttributes | undefined, import("@distilled.cloud/cloudflare/zero-trust").AccessReferenceNotFound | import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/cloudflare/Credentials").CredentialsError | import("@distilled.cloud/grafana").DefaultErrors, import("alchemy").InstanceId | import("alchemy").Stack | import("alchemy").Stage | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
11
+ /** observe, ensure (create or sync), read back. A no-op when nothing drifted. */
12
+ export declare const reconcileSaasOidc: (accountId: string, id: string, news: SaasOidcApplicationProps, output: SaasOidcApplicationAttributes | undefined) => Effect.Effect<SaasOidcApplicationAttributes, import("@distilled.cloud/cloudflare/zero-trust").AccessDestinationConflict | import("@distilled.cloud/cloudflare/zero-trust").AccessReferenceNotFound | import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | import("@distilled.cloud/cloudflare/zero-trust").OrganizationNotFound | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, import("alchemy").InstanceId | import("alchemy").Stack | import("alchemy").Stage | import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
13
+ export declare const deleteSaasOidc: (output: SaasOidcApplicationAttributes) => Effect.Effect<void, import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, import("@distilled.cloud/cloudflare/Protocol").CloudflareOpContext>;
14
+ //# sourceMappingURL=saas-oidc-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-lifecycle.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-lifecycle.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EACL,KAAK,6BAA6B,EAClC,KAAK,wBAAwB,EAM9B,MAAM,qBAAqB,CAAC;AAqC7B;;;;;GAKG;AACH,eAAO,MAAM,YAAY,cACZ,MAAM,MACb,MAAM,QACJ,wBAAwB,GAAG,SAAS,UAClC,6BAA6B,GAAG,SAAS,uyBAiB/C,CAAC;AASL,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,cACjB,MAAM,MACb,MAAM,QACJ,wBAAwB,UACtB,6BAA6B,GAAG,SAAS,g+BAmD/C,CAAC;AAEL,eAAO,MAAM,cAAc,WAAY,6BAA6B,opBACjB,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * The declared shape of `HomeFlare.Access.SaasOidcApplication` and what it reports back, apart from
3
+ * the pure helpers that use them (saas-oidc-form.ts re-exports both types, so imports keep working).
4
+ *
5
+ * ★ EVERY PROP FIELD CARRIES A JSDOC (provider standard S5). Where the wording below is the API's,
6
+ * it is the SDK's own field doc on the request type
7
+ * (`@distilled.cloud/cloudflare@1.0.0-rc.13` `zero-trust` `CreateAccessApplicationForAccountRequest`
8
+ * and `AccessApplicationsCreateRequestSaasAppOIDCSaaSApp`, src/services/zero_trust.ts:9025-9053 and
9
+ * :9728-9794), so a reader gets the vendor's meaning without leaving the editor.
10
+ * ⛔ THE ATTRIBUTES NEVER HOLD THE CLIENT SECRET, and nothing here can: there is no field for it.
11
+ */
12
+ /**
13
+ * An OIDC flow Access can serve for the client: the five literals the SDK names
14
+ * (`AccessApplicationsCreateRequestSaasAppOIDCSaaSAppGrantTypesItem`, zero_trust.ts:8946-8951).
15
+ */
16
+ export type OidcGrantType = 'authorization_code' | 'authorization_code_with_pkce' | 'refresh_tokens' | 'hybrid' | 'implicit';
17
+ /** The user information the client may request from Access. */
18
+ export type OidcScope = 'openid' | 'email' | 'profile' | 'groups';
19
+ export interface SaasOidcApplicationProps {
20
+ /**
21
+ * Live Access application UUID. Set this when adopting a SaaS app that already exists. Without
22
+ * it the app is found by exact `name` among saas apps, which also works but refuses two matches.
23
+ */
24
+ readonly applicationId?: string;
25
+ /** The app's name. Defaults to a physical name derived from the logical id. */
26
+ readonly name?: string;
27
+ /**
28
+ * The Zero Trust team domain the issuer lives on, a bare hostname such as
29
+ * `example.cloudflareaccess.com`: no scheme, no path. Not read from the environment, so the
30
+ * issuer in the attributes is the one the declaration says.
31
+ */
32
+ readonly teamDomain: string;
33
+ /**
34
+ * How long Access sessions for this app last, in the API's duration format (`300ms` or `2h45m`).
35
+ * Written on create and on any sync; not drift-checked.
36
+ * @default '24h'
37
+ */
38
+ readonly sessionDuration?: string;
39
+ /**
40
+ * Ids of the identity providers users may pick for this app. Written on create and on any sync;
41
+ * not drift-checked.
42
+ * @default every IdP configured in the account (the field is left out of the write)
43
+ */
44
+ readonly allowedIdps?: ReadonlyArray<string>;
45
+ /**
46
+ * `true` makes users skip the identity-provider selection step; the API requires exactly one
47
+ * entry in `allowedIdps` then. Written on create and on any sync; not drift-checked.
48
+ * @default left out of the write (the API's default)
49
+ */
50
+ readonly autoRedirectToIdentity?: boolean;
51
+ /**
52
+ * Show the app in the App Launcher. Written on create and on any sync; not drift-checked.
53
+ * @default false
54
+ */
55
+ readonly appLauncherVisible?: boolean;
56
+ /**
57
+ * Ids of reusable Access policies, in ascending order of precedence (the SDK's own wording:
58
+ * zero_trust.ts:9774). The ORDER is part of the declaration: a reorder is drift and is synced.
59
+ */
60
+ readonly policies: ReadonlyArray<string>;
61
+ /** The OIDC client: the `saas_app` object of the Access application. */
62
+ readonly saasApp: {
63
+ /** The authentication protocol of the SaaS app. Only `oidc` is supported by this resource. */
64
+ readonly authType: 'oidc';
65
+ /**
66
+ * The permitted URLs for Cloudflare to return authorization codes and tokens to. Compared as
67
+ * a set (order is not significant to the API).
68
+ */
69
+ readonly redirectUris: ReadonlyArray<string>;
70
+ /** The user information shared with the client. Compared as a set. */
71
+ readonly scopes: ReadonlyArray<OidcScope>;
72
+ /** The OIDC flows the client may use. Compared as a set. */
73
+ readonly grantTypes: ReadonlyArray<OidcGrantType>;
74
+ /** Lifetime of the access token after creation: `m` or `h` units, `1m` to `24h` (the SDK field doc). */
75
+ readonly accessTokenLifetime: string;
76
+ /**
77
+ * How long a refresh token is valid after creation: `m`, `h` or `d` units, longer than `1m`
78
+ * (the SDK field doc). Needed for the `refresh_tokens` grant. Sent as `refreshTokenOptions.lifetime`.
79
+ * @default left out of the write
80
+ */
81
+ readonly refreshTokenLifetime?: string;
82
+ /**
83
+ * `true` makes this a PUBLIC client: the token endpoint does not require a client secret when
84
+ * the `authorization_code_with_pkce` grant is used, and then no secret exists to keep. Refused
85
+ * without that grant.
86
+ * @default false (a confidential client)
87
+ */
88
+ readonly allowPkceWithoutClientSecret?: boolean;
89
+ /**
90
+ * The URL the app's tile in the App Launcher sends users to. Written on create and on any
91
+ * sync; not drift-checked.
92
+ * @default left out of the write
93
+ */
94
+ readonly appLauncherUrl?: string;
95
+ };
96
+ }
97
+ export interface SaasOidcApplicationAttributes {
98
+ /** The Access application UUID. */
99
+ readonly applicationId: string;
100
+ /** The application audience tag, the `aud` of the Access JWTs for this app. */
101
+ readonly aud: string;
102
+ /** The `domain` Cloudflare reports for the app (the OIDC issuer without its scheme). */
103
+ readonly domain: string;
104
+ /** The app's name as Cloudflare reports it. */
105
+ readonly name: string;
106
+ /** The account the app lives in. */
107
+ readonly accountId: string;
108
+ /** The declared team domain (or, for state that predates the prop, the host Cloudflare reports). */
109
+ readonly teamDomain: string;
110
+ /** The OIDC client id, for the relying party's configuration. */
111
+ readonly clientId: string;
112
+ /** `https://<teamDomain>/cdn-cgi/access/sso/oidc/<clientId>`. */
113
+ readonly issuer: string;
114
+ /** `<issuer>/authorization`. */
115
+ readonly authorizationEndpoint: string;
116
+ /** `<issuer>/token`. */
117
+ readonly tokenEndpoint: string;
118
+ /** The signing keys, for a verifier that validates ID tokens. */
119
+ readonly jwksEndpoint: string;
120
+ /** `<issuer>/userinfo`. */
121
+ readonly userinfoEndpoint: string;
122
+ /** `<issuer>/.well-known/openid-configuration`. */
123
+ readonly configurationEndpoint: string;
124
+ /** The redirect URIs the live app permits. */
125
+ readonly redirectUris: ReadonlyArray<string>;
126
+ /** The scopes the live app serves. */
127
+ readonly scopes: ReadonlyArray<string>;
128
+ /** The grant types the live app allows. */
129
+ readonly grantTypes: ReadonlyArray<string>;
130
+ /** The live access token lifetime, or `''` when Cloudflare reports none. */
131
+ readonly accessTokenLifetime: string;
132
+ /** The live refresh token lifetime, or `''` when Cloudflare reports none. */
133
+ readonly refreshTokenLifetime: string;
134
+ /** When Cloudflare created the app, if it says. */
135
+ readonly createdAt: string | undefined;
136
+ /** When Cloudflare last updated the app, if it says. */
137
+ readonly updatedAt: string | undefined;
138
+ }
139
+ //# sourceMappingURL=saas-oidc-props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-props.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-props.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import * as zeroTrust from '@distilled.cloud/cloudflare/zero-trust';
2
+ import * as Effect from 'effect/Effect';
3
+ import { SaasOidcError } from './saas-oidc-error.ts';
4
+ /**
5
+ * A refusal when the account's organization is read and its domain is not the declared one; else
6
+ * `undefined` (it matches, or it could not be read, see above). Hostnames compare case-insensitively.
7
+ */
8
+ export declare const checkTeamBeforeCreate: (accountId: string, teamDomain: string) => Effect.Effect<SaasOidcError | undefined, import("@distilled.cloud/cloudflare/Errors").CloudflareError | import("@distilled.cloud/cloudflare/Errors").CloudflareHttpError | import("@distilled.cloud/cloudflare/Errors").CloudflareRateLimited | import("@distilled.cloud/caddy").ConfigError | import("effect/http/HttpClientError").HttpClientError | import("@distilled.cloud/cloudflare/Errors").InvalidRoute | import("@distilled.cloud/cloudflare/Credentials").OAuthRefreshError | zeroTrust.OrganizationNotFound | SaasOidcError | import("@distilled.cloud/cloudflare/Errors").UnknownCloudflareError | import("@distilled.cloud/grafana").DefaultErrors, zeroTrust.CloudflareOpContext>;
9
+ //# sourceMappingURL=saas-oidc-team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-team.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-team.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,SAAS,MAAM,wCAAwC,CAAC;AACpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,aAAa,EAAY,MAAM,sBAAsB,CAAC;AAyB/D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,cAAe,MAAM,cAAc,MAAM,qqBASxE,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The wire shapes of a SaaS OIDC application, and the parse that reads them: pure, no Effect, no
3
+ * request. saas-oidc-api.ts says why the read is raw JSON (the SDK's responses drop `saas_app`).
4
+ *
5
+ * ⛔ `parseApp` COPIES NAMED FIELDS ONLY, and `client_secret` is not among them: an `ObservedApp`
6
+ * has nowhere to hold the client secret, so no code path can persist or log one.
7
+ */
8
+ /** The OIDC half of a live SaaS app, from the wire JSON. */
9
+ export interface ObservedSaas {
10
+ readonly authType: string | undefined;
11
+ readonly clientId: string | undefined;
12
+ readonly redirectUris: ReadonlyArray<string> | undefined;
13
+ readonly scopes: ReadonlyArray<string> | undefined;
14
+ readonly grantTypes: ReadonlyArray<string> | undefined;
15
+ readonly accessTokenLifetime: string | undefined;
16
+ readonly refreshTokenLifetime: string | undefined;
17
+ readonly allowPkceWithoutClientSecret: boolean | undefined;
18
+ }
19
+ /** A live Access application as this package sees it. ⛔ There is no secret field, on purpose. */
20
+ export interface ObservedApp {
21
+ readonly id: string | undefined;
22
+ readonly aud: string | undefined;
23
+ readonly type: string | undefined;
24
+ readonly name: string | undefined;
25
+ readonly domain: string | undefined;
26
+ readonly createdAt: string | undefined;
27
+ readonly updatedAt: string | undefined;
28
+ readonly policyIds: ReadonlyArray<string>;
29
+ readonly saasApp: ObservedSaas | undefined;
30
+ }
31
+ /** What a create or an update sends. Built by `writeBody` in saas-oidc-form.ts. */
32
+ export interface AppWrite {
33
+ readonly name: string;
34
+ readonly sessionDuration: string;
35
+ readonly allowedIdps: ReadonlyArray<string> | undefined;
36
+ readonly autoRedirectToIdentity: boolean | undefined;
37
+ readonly appLauncherVisible: boolean;
38
+ readonly policies: ReadonlyArray<string>;
39
+ readonly saasApp: {
40
+ readonly authType: 'oidc';
41
+ readonly redirectUris: ReadonlyArray<string>;
42
+ readonly scopes: ReadonlyArray<string>;
43
+ readonly grantTypes: ReadonlyArray<string>;
44
+ readonly accessTokenLifetime: string;
45
+ readonly refreshTokenOptions?: {
46
+ readonly lifetime: string;
47
+ };
48
+ readonly allowPkceWithoutClientSecret: boolean;
49
+ readonly appLauncherUrl: string | undefined;
50
+ };
51
+ }
52
+ export declare const record: (value: unknown) => Record<string, unknown> | undefined;
53
+ /**
54
+ * Named fields only, from Cloudflare's snake_case JSON. ⛔ `client_secret` is not among them, and
55
+ * `public_key`, `custom_claims` and `hybrid_and_implicit_options` are not used by this resource.
56
+ */
57
+ export declare const parseApp: (raw: Record<string, unknown>) => ObservedApp;
58
+ //# sourceMappingURL=saas-oidc-wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc-wire.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc-wire.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,QAAQ,CAAC,4BAA4B,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5D;AAED,iGAAiG;AACjG,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAC;CAC5C;AAED,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IACxD,QAAQ,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QACvC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAC3C,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;QACrC,QAAQ,CAAC,mBAAmB,CAAC,EAAE;YAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7D,QAAQ,CAAC,4BAA4B,EAAE,OAAO,CAAC;QAC/C,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;KAC7C,CAAC;CACH;AAOD,eAAO,MAAM,MAAM,UAAW,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAGnD,CAAC;AAuBhB;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAG,WA2BvD,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `HomeFlare.Access.SaasOidcApplication` — a Cloudflare Access SaaS application that makes Access an
3
+ * OIDC identity provider for one relying party (OpenBao's JWT/OIDC auth, Headlamp, a Kubernetes
4
+ * API server). Usage and the secret rules: docs/saas-oidc.md.
5
+ *
6
+ * 🔴 WHY THIS EXISTS ALONGSIDE `Cloudflare.Access.Application`. Alchemy beta.81's Application has
7
+ * no `saas_app` field (its source mentions `saas` only as a type and in two comments), and
8
+ * `@distilled.cloud/cloudflare` rc.13 decodes a saas app's GET and create response WITHOUT it, so
9
+ * the client id cannot be read back through either. See saas-oidc-api.ts.
10
+ *
11
+ * ⛔ THE TYPE ID IS A STATE KEY, AND THIS ONE WAS MOVED, NOT RENAMED. It is the string the
12
+ * homeflare-openbao stack's live `OpenBaoOidcSaas` row was written under. A different string would
13
+ * make the next plan see a new resource and an orphaned one: a second OIDC app, with a new
14
+ * client id and `aud`, and a delete of the live one unless it were retained. `tests` pin it.
15
+ *
16
+ * ★ `retain` BY DEFAULT, like every kit resource whose deletion breaks its consumers: deleting the
17
+ * app deletes the client id every relying party is configured with. The openbao declaration
18
+ * already pipes `RemovalPolicy.retain()`; `delete` stays fully implemented for a declaration
19
+ * that opts in with `.pipe(RemovalPolicy.destroy())`.
20
+ */
21
+ import { Credentials } from '@distilled.cloud/cloudflare/Credentials';
22
+ import * as Cloudflare from 'alchemy/Cloudflare';
23
+ import * as Provider from 'alchemy/Provider';
24
+ import { Resource, type ResourceClass } from 'alchemy/Resource';
25
+ import * as HttpClient from 'effect/http/HttpClient';
26
+ import type { Providers } from './providers.ts';
27
+ import type { SaasOidcApplicationAttributes, SaasOidcApplicationProps } from './saas-oidc-form.ts';
28
+ export interface SaasOidcApplication extends Resource<'HomeFlare.Access.SaasOidcApplication', SaasOidcApplicationProps, SaasOidcApplicationAttributes, never, Providers> {
29
+ }
30
+ export declare const SaasOidcApplication: ResourceClass<SaasOidcApplication>;
31
+ /**
32
+ * ★ `Provider.effect`, CAPTURING THE THREE SERVICES AT BUILD, as MeshNodeProvider does
33
+ * (mesh-node.ts): correct whether or not the stack also merges `Cloudflare.providers()`.
34
+ */
35
+ export declare const SaasOidcApplicationProvider: () => import("effect/Layer").Layer<Provider.Provider<SaasOidcApplication>, never, Cloudflare.CloudflareEnvironment | Credentials | HttpClient.HttpClient | import("alchemy").Stack | import("alchemy").Stage>;
36
+ //# sourceMappingURL=saas-oidc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saas-oidc.d.ts","sourceRoot":"","sources":["../../src/cloudflare/saas-oidc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,UAAU,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,UAAU,MAAM,wBAAwB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEnG,MAAM,WAAW,mBAAoB,SAAQ,QAAQ,CACnD,sCAAsC,EACtC,wBAAwB,EACxB,6BAA6B,EAC7B,KAAK,EACL,SAAS,CACV;CAAG;AAEJ,eAAO,MAAM,mBAAmB,EAAE,aAAa,CAAC,mBAAmB,CAG/D,CAAC;AAOL;;;GAGG;AACH,eAAO,MAAM,2BAA2B,+MAqDrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cluster-adapter-errors.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter-errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cluster-adapter-errors.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter-errors.ts"],"names":[],"mappings":";;;AAMA,sEAAsE;AACtE,qBAAa,0BAA2B,SAAQ,gCAA+C;IAC7F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,qFAAqF;AACrF,qBAAa,wBAAyB,SAAQ,8BAA6C;IACzF,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,8FAA8F;AAC9F,qBAAa,sBAAuB,SAAQ,4BAA2C;IACrF,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAQ7B;CACF;;;;AAED,+FAA+F;AAC/F,qBAAa,iBAAkB,SAAQ,uBAAsC;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAQ7B;CACF;;;;AAED,oGAAoG;AACpG,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,qGAAqG;AACrG,qBAAa,yBAA0B,SAAQ,+BAA8C;IAC3F,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,4DAA4D;AAC5D,qBAAa,oBAAqB,SAAQ,0BAAyC;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,8FAA8F;AAC9F,qBAAa,2BAA4B,SAAQ,iCAAgD;IAC/F,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,4FAA4F;AAC5F,qBAAa,4BAA6B,SAAQ,kCAAiD;IACjG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF;;;;AAED,qFAAqF;AACrF,qBAAa,8BAA+B,SAAQ,oCAElD;IACA,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,mGAAmG;AACnG,qBAAa,2BAA4B,SAAQ,iCAAgD;IAC/F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAM7B;CACF;;;;AAED;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,gCAA+C;IAC7F,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAK7B;CACF;;;;AAED,uFAAuF;AACvF,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC;CACpB,CAAC;IACA,IAAa,OAAO,IAAI,MAAM,CAO7B;CACF"}
@@ -33,7 +33,8 @@
33
33
  * (`TalosClusterMoved`); a move is a NEW identity resource per physical cluster, so the old
34
34
  * rows keep their old uid and their cleanup reaches only the old cluster.
35
35
  * ⛔ ONE 10 s DEADLINE covers the vault read AND the uid GET (`withConnectDeadline`): a hung `bao`
36
- * or silent apiserver fails with `TalosOpenBaoConnectTimeout` and the `bao` child is killed.
36
+ * fails with `TalosOpenBaoConnectTimeout` and the `bao` child is killed. The uid GET has its own
37
+ * 5 s deadline inside it, so a silent apiserver fails first with `TalosClusterIdentityTimeout`.
37
38
  * ⚠️ The in-flight HTTPS GET is NOT aborted: upstream `readObject` takes no signal
38
39
  * (`internal/client.ts:75`), so the socket lives until the OS gives up. Left for the upstream ask.
39
40
  *
@@ -1 +1 @@
1
- {"version":3,"file":"cluster-adapter.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,KAAK,gBAAgB,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,EAC3B,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,0BAA0B,EAE1B,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,OAAO,QAAQ,+BAA+B,CAAC;IAC7C,UAAU,YAAY;QACpB;;;WAGG;QACH,eAAe,EAAE;YACf;;;;eAIG;YACH,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE/E,kGAAkG;AAClG,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG;IAChD,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG,sBAGpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,YACrB,kBAAkB,cACf,UAAU,YACb,QAAQ,CAAC,QAAQ,KACzB,MAAM,CAAC,MAAM,CACd,gBAAgB,EACd,oBAAoB,GACpB,0BAA0B,GAC1B,wBAAwB,GACxB,sBAAsB,GACtB,2BAA2B,GAC3B,4BAA4B,GAC5B,8BAA8B,GAC9B,2BAA2B,GAC3B,0BAA0B,GAC1B,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GACzB,KAAK,EACP,mBAAmB,CAAC,mBAAmB,CAyDrC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,WACtB,kBAAkB,KACzB,KAAK,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAYjF,CAAC"}
1
+ {"version":3,"file":"cluster-adapter.d.ts","sourceRoot":"","sources":["../../src/talos/cluster-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,OAAO,EAEL,KAAK,qBAAqB,EAC1B,oBAAoB,EACpB,KAAK,gBAAgB,EACtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,KAAK,mBAAmB,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EACL,KAAK,4BAA4B,EACjC,2BAA2B,EAC3B,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,0BAA0B,EAC/B,sBAAsB,EACtB,0BAA0B,EAE1B,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAEL,KAAK,mBAAmB,EAGzB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,8BAA8B,EAC9B,iBAAiB,EACjB,yBAAyB,EACzB,wBAAwB,EACxB,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,0BAA0B,EAC1B,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEvF,OAAO,QAAQ,+BAA+B,CAAC;IAC7C,UAAU,YAAY;QACpB;;;WAGG;QACH,eAAe,EAAE;YACf;;;;eAIG;YACH,GAAG,EAAE,MAAM,CAAC;SACb,CAAC;KACH;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE/E,kGAAkG;AAClG,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG;IAChD,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACzE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,QAAS,MAAM,KAAG,sBAGpD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,YACrB,kBAAkB,cACf,UAAU,YACb,QAAQ,CAAC,QAAQ,KACzB,MAAM,CAAC,MAAM,CACd,gBAAgB,EACd,oBAAoB,GACpB,0BAA0B,GAC1B,wBAAwB,GACxB,sBAAsB,GACtB,2BAA2B,GAC3B,4BAA4B,GAC5B,8BAA8B,GAC9B,2BAA2B,GAC3B,0BAA0B,GAC1B,oBAAoB,GACpB,oBAAoB,GACpB,yBAAyB,GACzB,KAAK,EACP,mBAAmB,CAAC,mBAAmB,CAyDrC,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,WACtB,kBAAkB,KACzB,KAAK,CAAC,KAAK,CAAC,qBAAqB,EAAE,KAAK,EAAE,mBAAmB,CAAC,mBAAmB,CAYjF,CAAC"}
@@ -71,7 +71,7 @@ class TalosClusterIdentityUnreadable extends Data.TaggedError("TalosClusterIdent
71
71
 
72
72
  class TalosClusterIdentityTimeout extends Data.TaggedError("TalosClusterIdentityTimeout") {
73
73
  get message() {
74
- return `talos-openbao cluster '${this.cluster}': no answer to the kube-system uid read within ` + `${this.seconds}s. Refused (failed closed) rather than waiting on a silent apiserver.`;
74
+ return `talos-openbao cluster '${this.cluster}': no answer to the kube-system uid read within ` + `${this.seconds}s (the identity read's own deadline, inside the 10 s connect deadline). ` + "Refused (failed closed) rather than waiting on a silent apiserver.";
75
75
  }
76
76
  }
77
77
 
@@ -240,7 +240,7 @@ var resolveBao = () => {
240
240
  };
241
241
 
242
242
  // src/talos/mint-temp-file.ts
243
- import { closeSync, openSync, writeFileSync } from "node:fs";
243
+ import { closeSync, openSync, unlinkSync, writeFileSync } from "node:fs";
244
244
  import { unlink } from "node:fs/promises";
245
245
  import { randomUUID } from "node:crypto";
246
246
  import { tmpdir } from "node:os";
@@ -252,9 +252,16 @@ var mintKvTempFile = (raw, label) => Effect3.gen(function* () {
252
252
  try: () => {
253
253
  const fd = openSync(path, "wx", 384);
254
254
  try {
255
- writeFileSync(fd, raw);
256
- } finally {
257
- closeSync(fd);
255
+ try {
256
+ writeFileSync(fd, raw);
257
+ } finally {
258
+ closeSync(fd);
259
+ }
260
+ } catch (cause) {
261
+ try {
262
+ unlinkSync(path);
263
+ } catch {}
264
+ throw cause;
258
265
  }
259
266
  },
260
267
  catch: (cause) => new Error(`writing ${label} temp file: ${String(cause)}`)
@@ -590,15 +597,19 @@ var capture = (binary, argv) => Effect8.gen(function* () {
590
597
  stdout: child.stdout.pipe(Stream3.decodeText, Stream3.mkString, Effect8.map((text) => text.trim()))
591
598
  }, { concurrency: "unbounded" })), Effect8.scoped);
592
599
  });
600
+ var VERSION_PROBE_TIMEOUT = Duration5.seconds(10);
593
601
  var reportsPinnedVersion = (stdout) => stdout.split(/[^\w.+-]+/).includes(TALOSCTL_PINNED_VERSION);
594
- var checkOverrideVersion = (binary, source) => capture(binary, ["version", "--client"]).pipe(Effect8.flatMap((out) => out.exitCode === 0 && reportsPinnedVersion(out.stdout) ? Effect8.void : Effect8.fail(new TalosBinaryRefused("version --client", `${source} is not talosctl ${TALOSCTL_PINNED_VERSION} (exit ${String(out.exitCode)})`, binary))));
602
+ var checkOverrideVersion = (binary, source, timeout = VERSION_PROBE_TIMEOUT) => capture(binary, ["version", "--client"]).pipe(Effect8.timeoutOrElse({
603
+ duration: timeout,
604
+ orElse: () => Effect8.fail(new TalosBinaryRefused("version --client", `${source} did not answer within ${String(Duration5.toSeconds(timeout))}s`, binary))
605
+ }), Effect8.flatMap((out) => out.exitCode === 0 && reportsPinnedVersion(out.stdout) ? Effect8.void : Effect8.fail(new TalosBinaryRefused("version --client", `${source} is not talosctl ${TALOSCTL_PINNED_VERSION} (exit ${String(out.exitCode)})`, binary))));
595
606
  var talosctl = (args, options) => Effect8.gen(function* () {
596
607
  const requested = talosctlBinary(options.binary);
597
608
  const resolved = requested === DEFAULT_TALOSCTL_BINARY ? yield* resolveDefault(requested) : requested;
598
609
  const fromOption = options.binary?.trim();
599
610
  const source = requested === DEFAULT_TALOSCTL_BINARY ? "talosctl on PATH" : fromOption !== undefined && fromOption !== "" ? "the `binary` option" : TALOSCTL_BINARY_ENV;
600
611
  const binary = yield* checkBinaryPath(resolved, source);
601
- yield* checkOverrideVersion(binary, source);
612
+ yield* checkOverrideVersion(binary, source, options.versionProbeTimeout);
602
613
  const argv = [
603
614
  ...args,
604
615
  "--talosconfig",
@@ -1074,5 +1085,5 @@ export {
1074
1085
  talosOpenBaoConnection
1075
1086
  };
1076
1087
 
1077
- //# debugId=0069C805BB1B149764756E2164756E21
1088
+ //# debugId=E9E48AF60568B1C664756E2164756E21
1078
1089
  //# sourceMappingURL=index.js.map