@distilled.cloud/fly-io 1.0.0-rc.4 → 1.0.0-rc.6

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 (56) hide show
  1. package/lib/credentials.d.ts +17 -0
  2. package/lib/credentials.d.ts.map +1 -1
  3. package/lib/credentials.js +39 -7
  4. package/lib/credentials.js.map +1 -1
  5. package/lib/errors.d.ts +32 -0
  6. package/lib/errors.d.ts.map +1 -1
  7. package/lib/errors.js +33 -0
  8. package/lib/errors.js.map +1 -1
  9. package/lib/index.d.ts +27 -2
  10. package/lib/index.d.ts.map +1 -1
  11. package/lib/index.js +27 -2
  12. package/lib/index.js.map +1 -1
  13. package/lib/pagination.d.ts +5 -0
  14. package/lib/pagination.d.ts.map +1 -0
  15. package/lib/pagination.js +5 -0
  16. package/lib/pagination.js.map +1 -0
  17. package/lib/protocol.d.ts +18 -7
  18. package/lib/protocol.d.ts.map +1 -1
  19. package/lib/protocol.js +505 -28
  20. package/lib/protocol.js.map +1 -1
  21. package/lib/services/addons.d.ts +466 -0
  22. package/lib/services/addons.d.ts.map +1 -0
  23. package/lib/services/addons.js +613 -0
  24. package/lib/services/addons.js.map +1 -0
  25. package/lib/services/index.d.ts +3 -0
  26. package/lib/services/index.d.ts.map +1 -1
  27. package/lib/services/index.js +3 -0
  28. package/lib/services/index.js.map +1 -1
  29. package/lib/services/machines.d.ts +1175 -1198
  30. package/lib/services/machines.d.ts.map +1 -1
  31. package/lib/services/machines.js +1297 -1310
  32. package/lib/services/machines.js.map +1 -1
  33. package/lib/services/mpg.d.ts +376 -0
  34. package/lib/services/mpg.d.ts.map +1 -0
  35. package/lib/services/mpg.js +570 -0
  36. package/lib/services/mpg.js.map +1 -0
  37. package/lib/services/sprites.d.ts +321 -0
  38. package/lib/services/sprites.d.ts.map +1 -0
  39. package/lib/services/sprites.js +407 -0
  40. package/lib/services/sprites.js.map +1 -0
  41. package/lib/traits.d.ts +18 -8
  42. package/lib/traits.d.ts.map +1 -1
  43. package/lib/traits.js +13 -3
  44. package/lib/traits.js.map +1 -1
  45. package/package.json +37 -13
  46. package/src/credentials.ts +53 -7
  47. package/src/errors.ts +39 -0
  48. package/src/index.ts +31 -1
  49. package/src/pagination.ts +12 -0
  50. package/src/protocol.ts +715 -32
  51. package/src/services/addons.ts +1313 -0
  52. package/src/services/index.ts +3 -0
  53. package/src/services/machines.ts +2998 -3049
  54. package/src/services/mpg.ts +1188 -0
  55. package/src/services/sprites.ts +917 -0
  56. package/src/traits.ts +37 -3
@@ -1,10 +1,17 @@
1
1
  /**
2
2
  * Fly.io credentials — hand-written.
3
3
  *
4
- * API-compatible port of the distilled v0 fly-io credentials module: the
5
- * `Credentials` service holds an *effect* that resolves the current
4
+ * The `Credentials` service holds an *effect* that resolves the current
6
5
  * credentials on every request. The protocol layer resolves it per request
7
- * and formats the `Authorization: Bearer <apiKey>` header.
6
+ * and formats the `Authorization` header.
7
+ *
8
+ * Alchemy and `flyctl` read `FLY_API_TOKEN`. `FLY_IO_API_KEY` is kept as a
9
+ * fallback for older distilled consumers. Optional `FLY_API_HOSTNAME`
10
+ * overrides the Machines API root (default `https://api.machines.dev/v1`).
11
+ *
12
+ * Managed REST (MPG), GraphQL add-ons (Tigris, Redis), and Sprites all
13
+ * reuse this token. Sprites never reads a separate env var: the protocol
14
+ * mints a Sprites bearer from `FLY_API_TOKEN` (see `SpritesProtocol`).
8
15
  */
9
16
  import { ConfigError } from "@distilled.cloud/core/errors";
10
17
  import * as EffectConfig from "effect/Config";
@@ -15,6 +22,26 @@ import * as Redacted from "effect/Redacted";
15
22
 
16
23
  export const DEFAULT_API_BASE_URL = "https://api.machines.dev/v1";
17
24
 
25
+ /** UI-EX REST + GraphQL host (MPG, Tigris, Redis). Not overridable via an invented env var. */
26
+ export const DEFAULT_FLY_API_BASE_URL = "https://api.fly.io";
27
+
28
+ /** Sprites REST root. Auth is a bearer minted from `FLY_API_TOKEN` — never `SPRITES_TOKEN`. */
29
+ export const DEFAULT_SPRITES_API_BASE_URL = "https://api.sprites.dev/v1";
30
+
31
+ /**
32
+ * Normalize a Fly API hostname into the Machines API root.
33
+ *
34
+ * - unset / empty → `https://api.machines.dev/v1`
35
+ * - already ends with `/v1` → used as-is (trailing slashes stripped)
36
+ * - otherwise `/v1` is appended
37
+ */
38
+ export const normalizeApiBaseUrl = (hostname?: string): string => {
39
+ if (hostname === undefined) return DEFAULT_API_BASE_URL;
40
+ const trimmed = hostname.trim().replace(/\/+$/, "");
41
+ if (trimmed.length === 0) return DEFAULT_API_BASE_URL;
42
+ return trimmed.endsWith("/v1") ? trimmed : `${trimmed}/v1`;
43
+ };
44
+
18
45
  export interface Config {
19
46
  readonly apiKey: Redacted.Redacted<string>;
20
47
  readonly apiBaseUrl: string;
@@ -26,7 +53,12 @@ export class Credentials extends Context.Service<
26
53
  >()("Fly-ioCredentials") {}
27
54
 
28
55
  const envConfig = EffectConfig.all({
29
- apiKey: EffectConfig.string("FLY_IO_API_KEY"),
56
+ apiKey: EffectConfig.string("FLY_API_TOKEN").pipe(
57
+ EffectConfig.orElse(() => EffectConfig.string("FLY_IO_API_KEY")),
58
+ ),
59
+ apiBaseUrl: EffectConfig.string("FLY_API_HOSTNAME").pipe(
60
+ EffectConfig.withDefault(""),
61
+ ),
30
62
  });
31
63
 
32
64
  export const CredentialsFromEnv = Layer.succeed(
@@ -35,13 +67,27 @@ export const CredentialsFromEnv = Layer.succeed(
35
67
  Effect.mapError(
36
68
  () =>
37
69
  new ConfigError({
38
- message: "FLY_IO_API_KEY environment variable is required",
70
+ message:
71
+ "FLY_API_TOKEN (or FLY_IO_API_KEY) environment variable is required",
39
72
  }),
40
73
  ),
41
- Effect.map(({ apiKey }) => ({
74
+ Effect.map(({ apiKey, apiBaseUrl }) => ({
42
75
  apiKey: Redacted.make(apiKey),
43
- apiBaseUrl: DEFAULT_API_BASE_URL,
76
+ apiBaseUrl: normalizeApiBaseUrl(apiBaseUrl || undefined),
44
77
  })),
45
78
  Effect.orDie,
46
79
  ),
47
80
  );
81
+
82
+ /** Convenience layer from a plain API token + optional base URL. */
83
+ export const credentials = (config: {
84
+ readonly apiKey: string;
85
+ readonly apiBaseUrl?: string;
86
+ }): Layer.Layer<Credentials> =>
87
+ Layer.succeed(
88
+ Credentials,
89
+ Effect.succeed({
90
+ apiKey: Redacted.make(config.apiKey),
91
+ apiBaseUrl: normalizeApiBaseUrl(config.apiBaseUrl),
92
+ }),
93
+ );
package/src/errors.ts CHANGED
@@ -29,6 +29,7 @@ import type { DefaultErrors as CoreDefaultErrors } from "@distilled.cloud/core/e
29
29
 
30
30
  import * as Schema from "effect/Schema";
31
31
  import * as Category from "@distilled.cloud/core/category";
32
+ import { applyErrorMatchers } from "@distilled.cloud/core/trait";
32
33
 
33
34
  /**
34
35
  * Unknown Fly.io error — returned when a failure matches no status-mapped
@@ -52,6 +53,44 @@ export class FlyIoParseError extends Schema.TaggedError<FlyIoParseError>()(
52
53
  },
53
54
  ).pipe(Category.withParseError) {}
54
55
 
56
+ /**
57
+ * Sprites is not enabled for the Fly organization that owns `FLY_API_TOKEN`.
58
+ *
59
+ * Returned by `POST /v1/organizations/{org}/tokens` as HTTP 401 with a
60
+ * message matching `sprites not enabled`. Sprite CRUD never sees a
61
+ * `SPRITES_TOKEN` — this is the mint-time entitlement signal.
62
+ */
63
+ export class SpritesNotEnabled extends Schema.TaggedError<SpritesNotEnabled>()(
64
+ "SpritesNotEnabled",
65
+ {
66
+ code: Schema.optional(Schema.Int),
67
+ message: Schema.optional(Schema.String),
68
+ },
69
+ ).pipe(Category.withAuthError) {}
70
+ applyErrorMatchers(SpritesNotEnabled, [
71
+ { status: 401, message: { matches: "[Ss]prites not enabled" } },
72
+ ]);
73
+
74
+ /**
75
+ * The Fly token cannot record add-on provider ToS agreement
76
+ * (`createExtensionTosAgreement`). GraphQL returns this as a 200
77
+ * with `Not authorized to access this createextensiontosagreement`.
78
+ */
79
+ export class CreateExtensionTosAgreementNotAuthorized extends Schema.TaggedError<CreateExtensionTosAgreementNotAuthorized>()(
80
+ "CreateExtensionTosAgreementNotAuthorized",
81
+ {
82
+ code: Schema.optional(Schema.Int),
83
+ message: Schema.optional(Schema.String),
84
+ },
85
+ ).pipe(Category.withAuthError) {}
86
+ applyErrorMatchers(CreateExtensionTosAgreementNotAuthorized, [
87
+ {
88
+ message: {
89
+ matches: "[Nn]ot authorized to access this createextensiontosagreement",
90
+ },
91
+ },
92
+ ]);
93
+
55
94
  /**
56
95
  * Errors any Fly.io operation may surface in addition to the status-mapped
57
96
  * per-operation errors.
package/src/index.ts CHANGED
@@ -4,14 +4,44 @@
4
4
  * `./services` is generated by `scripts/generate.ts` from the Smithy model
5
5
  * written by `scripts/convert.ts` (OpenAPI → Smithy via the shared core
6
6
  * converter). Everything else in this folder is hand-written.
7
+ *
8
+ * The generated barrel is re-exported at the package root, same as every
9
+ * other distilled SDK's service modules:
10
+ *
11
+ * @example Package namespace
12
+ * ```ts
13
+ * import * as Fly from "@distilled.cloud/fly-io";
14
+ *
15
+ * yield* Fly.machines.listApps({ org_slug });
16
+ * yield* Fly.mpg.createCluster({
17
+ * name, region, org_slug, plan, pg_major_version: "16", storage_in_gb: 10,
18
+ * });
19
+ * yield* Fly.addons.createAddOn({
20
+ * input: { type: "tigris", name, options: { website: { domain_name: "" } } },
21
+ * });
22
+ * yield* Fly.sprites.createSprite({ name, labels: ["alchemy"] });
23
+ * ```
24
+ *
25
+ * @example Per-service path
26
+ * ```ts
27
+ * import * as Machines from "@distilled.cloud/fly-io/machines";
28
+ *
29
+ * yield* Machines.listApps({ org_slug });
30
+ * ```
7
31
  */
8
32
  export * from "./credentials.ts";
9
33
  export * from "./errors.ts";
10
34
  export * as T from "./traits.ts";
11
35
  export {
12
36
  FlyIoProtocol,
37
+ FlyApiProtocol,
38
+ FlyGraphqlProtocol,
39
+ SpritesProtocol,
13
40
  type FlyIoOpError,
14
41
  type FlyIoOpContext,
42
+ type SpritesOpError,
43
+ type SpritesOpContext,
15
44
  } from "./protocol.ts";
16
45
  export * as Retry from "./retry.ts";
17
- export * as Services from "./services/index.ts";
46
+ export * as Pagination from "./pagination.ts";
47
+ export * from "./services/index.ts";
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Fly.io pagination — cursor (Sprites list) and Relay (GraphQL add-ons).
3
+ */
4
+ export {
5
+ paginateCursor,
6
+ paginateRelay,
7
+ extractItems,
8
+ getItems,
9
+ getPath,
10
+ type PaginatedTrait,
11
+ type PaginationStrategy,
12
+ } from "@distilled.cloud/core/pagination";