@distilled.cloud/fly-io 1.0.0-rc.5 → 1.0.0-rc.7

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 +49 -7
  18. package/lib/protocol.d.ts.map +1 -1
  19. package/lib/protocol.js +529 -29
  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 +28 -4
  46. package/src/credentials.ts +53 -7
  47. package/src/errors.ts +39 -0
  48. package/src/index.ts +32 -1
  49. package/src/pagination.ts +12 -0
  50. package/src/protocol.ts +747 -34
  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
@@ -3,6 +3,18 @@ import * as Effect from "effect/Effect";
3
3
  import * as Layer from "effect/Layer";
4
4
  import * as Redacted from "effect/Redacted";
5
5
  export declare const DEFAULT_API_BASE_URL = "https://api.machines.dev/v1";
6
+ /** UI-EX REST + GraphQL host (MPG, Tigris, Redis). Not overridable via an invented env var. */
7
+ export declare const DEFAULT_FLY_API_BASE_URL = "https://api.fly.io";
8
+ /** Sprites REST root. Auth is a bearer minted from `FLY_API_TOKEN` — never `SPRITES_TOKEN`. */
9
+ export declare const DEFAULT_SPRITES_API_BASE_URL = "https://api.sprites.dev/v1";
10
+ /**
11
+ * Normalize a Fly API hostname into the Machines API root.
12
+ *
13
+ * - unset / empty → `https://api.machines.dev/v1`
14
+ * - already ends with `/v1` → used as-is (trailing slashes stripped)
15
+ * - otherwise `/v1` is appended
16
+ */
17
+ export declare const normalizeApiBaseUrl: (hostname?: string) => string;
6
18
  export interface Config {
7
19
  readonly apiKey: Redacted.Redacted<string>;
8
20
  readonly apiBaseUrl: string;
@@ -11,5 +23,10 @@ declare const Credentials_base: Context.ServiceClass<Credentials, "Fly-ioCredent
11
23
  export declare class Credentials extends Credentials_base {
12
24
  }
13
25
  export declare const CredentialsFromEnv: Layer.Layer<Credentials, never, never>;
26
+ /** Convenience layer from a plain API token + optional base URL. */
27
+ export declare const credentials: (config: {
28
+ readonly apiKey: string;
29
+ readonly apiBaseUrl?: string;
30
+ }) => Layer.Layer<Credentials>;
14
31
  export {};
15
32
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;;AAED,qBAAa,WAAY,SAAQ,gBAGT;CAAG;AAM3B,eAAO,MAAM,kBAAkB,wCAe9B,CAAC"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,eAAO,MAAM,oBAAoB,gCAAgC,CAAC;AAElE,+FAA+F;AAC/F,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAE7D,+FAA+F;AAC/F,eAAO,MAAM,4BAA4B,+BAA+B,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,cAAe,MAAM,KAAG,MAKvD,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;;AAED,qBAAa,WAAY,SAAQ,gBAGT;CAAG;AAW3B,eAAO,MAAM,kBAAkB,wCAgB9B,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,WAAW,WAAY;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,KAAG,KAAK,CAAC,KAAK,CAAC,WAAW,CAOxB,CAAC"}
@@ -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";
@@ -13,15 +20,40 @@ import * as Effect from "effect/Effect";
13
20
  import * as Layer from "effect/Layer";
14
21
  import * as Redacted from "effect/Redacted";
15
22
  export const DEFAULT_API_BASE_URL = "https://api.machines.dev/v1";
23
+ /** UI-EX REST + GraphQL host (MPG, Tigris, Redis). Not overridable via an invented env var. */
24
+ export const DEFAULT_FLY_API_BASE_URL = "https://api.fly.io";
25
+ /** Sprites REST root. Auth is a bearer minted from `FLY_API_TOKEN` — never `SPRITES_TOKEN`. */
26
+ export const DEFAULT_SPRITES_API_BASE_URL = "https://api.sprites.dev/v1";
27
+ /**
28
+ * Normalize a Fly API hostname into the Machines API root.
29
+ *
30
+ * - unset / empty → `https://api.machines.dev/v1`
31
+ * - already ends with `/v1` → used as-is (trailing slashes stripped)
32
+ * - otherwise `/v1` is appended
33
+ */
34
+ export const normalizeApiBaseUrl = (hostname) => {
35
+ if (hostname === undefined)
36
+ return DEFAULT_API_BASE_URL;
37
+ const trimmed = hostname.trim().replace(/\/+$/, "");
38
+ if (trimmed.length === 0)
39
+ return DEFAULT_API_BASE_URL;
40
+ return trimmed.endsWith("/v1") ? trimmed : `${trimmed}/v1`;
41
+ };
16
42
  export class Credentials extends Context.Service()("Fly-ioCredentials") {
17
43
  }
18
44
  const envConfig = EffectConfig.all({
19
- apiKey: EffectConfig.string("FLY_IO_API_KEY"),
45
+ apiKey: EffectConfig.string("FLY_API_TOKEN").pipe(EffectConfig.orElse(() => EffectConfig.string("FLY_IO_API_KEY"))),
46
+ apiBaseUrl: EffectConfig.string("FLY_API_HOSTNAME").pipe(EffectConfig.withDefault("")),
20
47
  });
21
48
  export const CredentialsFromEnv = Layer.succeed(Credentials, envConfig.pipe(Effect.mapError(() => new ConfigError({
22
- message: "FLY_IO_API_KEY environment variable is required",
23
- })), Effect.map(({ apiKey }) => ({
49
+ message: "FLY_API_TOKEN (or FLY_IO_API_KEY) environment variable is required",
50
+ })), Effect.map(({ apiKey, apiBaseUrl }) => ({
24
51
  apiKey: Redacted.make(apiKey),
25
- apiBaseUrl: DEFAULT_API_BASE_URL,
52
+ apiBaseUrl: normalizeApiBaseUrl(apiBaseUrl || undefined),
26
53
  })), Effect.orDie));
54
+ /** Convenience layer from a plain API token + optional base URL. */
55
+ export const credentials = (config) => Layer.succeed(Credentials, Effect.succeed({
56
+ apiKey: Redacted.make(config.apiKey),
57
+ apiBaseUrl: normalizeApiBaseUrl(config.apiBaseUrl),
58
+ }));
27
59
  //# sourceMappingURL=credentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAOlE,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAG7C,CAAC,mBAAmB,CAAC;CAAG;AAE3B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC;IACjC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC;CAC9C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAC7C,WAAW,EACX,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,QAAQ,CACb,GAAG,EAAE,CACH,IAAI,WAAW,CAAC;IACd,OAAO,EAAE,iDAAiD;CAC3D,CAAC,CACL,EACD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1B,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7B,UAAU,EAAE,oBAAoB;CACjC,CAAC,CAAC,EACH,MAAM,CAAC,KAAK,CACb,CACF,CAAC"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAElE,+FAA+F;AAC/F,MAAM,CAAC,MAAM,wBAAwB,GAAG,oBAAoB,CAAC;AAE7D,+FAA+F;AAC/F,MAAM,CAAC,MAAM,4BAA4B,GAAG,4BAA4B,CAAC;AAEzE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAiB,EAAU,EAAE;IAC/D,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,oBAAoB,CAAC;IACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,oBAAoB,CAAC;IACtD,OAAO,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC;AAC7D,CAAC,CAAC;AAOF,MAAM,OAAO,WAAY,SAAQ,OAAO,CAAC,OAAO,EAG7C,CAAC,mBAAmB,CAAC;CAAG;AAE3B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC;IACjC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAC/C,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CACjE;IACD,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,IAAI,CACtD,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC,CAC7B;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,OAAO,CAC7C,WAAW,EACX,SAAS,CAAC,IAAI,CACZ,MAAM,CAAC,QAAQ,CACb,GAAG,EAAE,CACH,IAAI,WAAW,CAAC;IACd,OAAO,EACL,oEAAoE;CACvE,CAAC,CACL,EACD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;IAC7B,UAAU,EAAE,mBAAmB,CAAC,UAAU,IAAI,SAAS,CAAC;CACzD,CAAC,CAAC,EACH,MAAM,CAAC,KAAK,CACb,CACF,CAAC;AAEF,oEAAoE;AACpE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAG3B,EAA4B,EAAE,CAC7B,KAAK,CAAC,OAAO,CACX,WAAW,EACX,MAAM,CAAC,OAAO,CAAC;IACb,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,UAAU,EAAE,mBAAmB,CAAC,MAAM,CAAC,UAAU,CAAC;CACnD,CAAC,CACH,CAAC"}
package/lib/errors.d.ts CHANGED
@@ -36,6 +36,38 @@ declare const FlyIoParseError_base: Schema.Class<FlyIoParseError, Schema.TaggedS
36
36
  /** Schema parse error wrapper. */
37
37
  export declare class FlyIoParseError extends FlyIoParseError_base {
38
38
  }
39
+ declare const SpritesNotEnabled_base: Schema.Class<SpritesNotEnabled, Schema.TaggedStruct<"SpritesNotEnabled", {
40
+ readonly code: Schema.optional<Schema.Int>;
41
+ readonly message: Schema.optional<Schema.String>;
42
+ }>, import("effect/Cause").YieldableError> & (new (...args: any[]) => {
43
+ "@distilled.cloud/error/categories": {
44
+ AuthError: true;
45
+ };
46
+ });
47
+ /**
48
+ * Sprites is not enabled for the Fly organization that owns `FLY_API_TOKEN`.
49
+ *
50
+ * Returned by `POST /v1/organizations/{org}/tokens` as HTTP 401 with a
51
+ * message matching `sprites not enabled`. Sprite CRUD never sees a
52
+ * `SPRITES_TOKEN` — this is the mint-time entitlement signal.
53
+ */
54
+ export declare class SpritesNotEnabled extends SpritesNotEnabled_base {
55
+ }
56
+ declare const CreateExtensionTosAgreementNotAuthorized_base: Schema.Class<CreateExtensionTosAgreementNotAuthorized, Schema.TaggedStruct<"CreateExtensionTosAgreementNotAuthorized", {
57
+ readonly code: Schema.optional<Schema.Int>;
58
+ readonly message: Schema.optional<Schema.String>;
59
+ }>, import("effect/Cause").YieldableError> & (new (...args: any[]) => {
60
+ "@distilled.cloud/error/categories": {
61
+ AuthError: true;
62
+ };
63
+ });
64
+ /**
65
+ * The Fly token cannot record add-on provider ToS agreement
66
+ * (`createExtensionTosAgreement`). GraphQL returns this as a 200
67
+ * with `Not authorized to access this createextensiontosagreement`.
68
+ */
69
+ export declare class CreateExtensionTosAgreementNotAuthorized extends CreateExtensionTosAgreementNotAuthorized_base {
70
+ }
39
71
  /**
40
72
  * Errors any Fly.io operation may surface in addition to the status-mapped
41
73
  * per-operation errors.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEvF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;;;;;;;AAGxC;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,sBAOP;CAAG;;;;;;;;;AAEnC,kCAAkC;AAClC,qBAAa,eAAgB,SAAQ,oBAMN;CAAG;AAElC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,YAAY,CAAC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEvF,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;;;;;;;;;;AAIxC;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,sBAOP;CAAG;;;;;;;;;AAEnC,kCAAkC;AAClC,qBAAa,eAAgB,SAAQ,oBAMN;CAAG;;;;;;;;;AAElC;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,sBAMT;CAAG;;;;;;;;;AAKjC;;;;GAIG;AACH,qBAAa,wCAAyC,SAAQ,6CAMhC;CAAG;AASjC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAE/D;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,YAAY,CAAC"}
package/lib/errors.js CHANGED
@@ -10,6 +10,7 @@
10
10
  export { BadGateway, BadRequest, Conflict, ConfigError, Forbidden, GatewayTimeout, InternalServerError, Locked, NotFound, ServiceUnavailable, TooManyRequests, Unauthorized, UnprocessableEntity, HTTP_STATUS_MAP, DEFAULT_ERRORS, API_ERRORS, } from "@distilled.cloud/core/errors";
11
11
  import * as Schema from "effect/Schema";
12
12
  import * as Category from "@distilled.cloud/core/category";
13
+ import { applyErrorMatchers } from "@distilled.cloud/core/trait";
13
14
  /**
14
15
  * Unknown Fly.io error — returned when a failure matches no status-mapped
15
16
  * error class. Carries the raw body for later cataloging.
@@ -26,4 +27,36 @@ export class FlyIoParseError extends Schema.TaggedError()("FlyIoParseError", {
26
27
  cause: Schema.Unknown,
27
28
  }).pipe(Category.withParseError) {
28
29
  }
30
+ /**
31
+ * Sprites is not enabled for the Fly organization that owns `FLY_API_TOKEN`.
32
+ *
33
+ * Returned by `POST /v1/organizations/{org}/tokens` as HTTP 401 with a
34
+ * message matching `sprites not enabled`. Sprite CRUD never sees a
35
+ * `SPRITES_TOKEN` — this is the mint-time entitlement signal.
36
+ */
37
+ export class SpritesNotEnabled extends Schema.TaggedError()("SpritesNotEnabled", {
38
+ code: Schema.optional(Schema.Int),
39
+ message: Schema.optional(Schema.String),
40
+ }).pipe(Category.withAuthError) {
41
+ }
42
+ applyErrorMatchers(SpritesNotEnabled, [
43
+ { status: 401, message: { matches: "[Ss]prites not enabled" } },
44
+ ]);
45
+ /**
46
+ * The Fly token cannot record add-on provider ToS agreement
47
+ * (`createExtensionTosAgreement`). GraphQL returns this as a 200
48
+ * with `Not authorized to access this createextensiontosagreement`.
49
+ */
50
+ export class CreateExtensionTosAgreementNotAuthorized extends Schema.TaggedError()("CreateExtensionTosAgreementNotAuthorized", {
51
+ code: Schema.optional(Schema.Int),
52
+ message: Schema.optional(Schema.String),
53
+ }).pipe(Category.withAuthError) {
54
+ }
55
+ applyErrorMatchers(CreateExtensionTosAgreementNotAuthorized, [
56
+ {
57
+ message: {
58
+ matches: "[Nn]ot authorized to access this createextensiontosagreement",
59
+ },
60
+ },
61
+ ]);
29
62
  //# sourceMappingURL=errors.js.map
package/lib/errors.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,gCAAgC,CAAC;AAE3D;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,EAAqB,CAC5E,mBAAmB,EACnB;IACE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC,OAAO;CACrB,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;CAAG;AAEnC,kCAAkC;AAClC,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAmB,CACxE,iBAAiB,EACjB;IACE,IAAI,EAAE,MAAM,CAAC,OAAO;IACpB,KAAK,EAAE,MAAM,CAAC,OAAO;CACtB,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;CAAG"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,UAAU,EACV,UAAU,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,8BAA8B,CAAC;AAGtC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,QAAQ,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,EAAqB,CAC5E,mBAAmB,EACnB;IACE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC,OAAO;CACrB,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;CAAG;AAEnC,kCAAkC;AAClC,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAmB,CACxE,iBAAiB,EACjB;IACE,IAAI,EAAE,MAAM,CAAC,OAAO;IACpB,KAAK,EAAE,MAAM,CAAC,OAAO;CACtB,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;CAAG;AAElC;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,EAAqB,CAC5E,mBAAmB,EACnB;IACE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACxC,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;CAAG;AACjC,kBAAkB,CAAC,iBAAiB,EAAE;IACpC,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,wBAAwB,EAAE,EAAE;CAChE,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,OAAO,wCAAyC,SAAQ,MAAM,CAAC,WAAW,EAA4C,CAC1H,0CAA0C,EAC1C;IACE,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;CACxC,CACF,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;CAAG;AACjC,kBAAkB,CAAC,wCAAwC,EAAE;IAC3D;QACE,OAAO,EAAE;YACP,OAAO,EAAE,8DAA8D;SACxE;KACF;CACF,CAAC,CAAC"}
package/lib/index.d.ts CHANGED
@@ -4,11 +4,36 @@
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
- export { FlyIoProtocol, type FlyIoOpError, type FlyIoOpContext, } from "./protocol.ts";
35
+ export { FlyIoProtocol, FlyApiProtocol, FlyGraphqlProtocol, SpritesProtocol, MachineIdentity, type FlyIoOpError, type FlyIoOpContext, type SpritesOpError, type SpritesOpContext, } from "./protocol.ts";
12
36
  export * as Retry from "./retry.ts";
13
- export * as Services from "./services/index.ts";
37
+ export * as Pagination from "./pagination.ts";
38
+ export * from "./services/index.ts";
14
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,cAAc,qBAAqB,CAAC"}
package/lib/index.js CHANGED
@@ -4,11 +4,36 @@
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.js";
9
33
  export * from "./errors.js";
10
34
  export * as T from "./traits.js";
11
- export { FlyIoProtocol, } from "./protocol.js";
35
+ export { FlyIoProtocol, FlyApiProtocol, FlyGraphqlProtocol, SpritesProtocol, MachineIdentity, } from "./protocol.js";
12
36
  export * as Retry from "./retry.js";
13
- export * as Services from "./services/index.js";
37
+ export * as Pagination from "./pagination.js";
38
+ export * from "./services/index.js";
14
39
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,aAAa,GAGd,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,eAAe,GAKhB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAC9C,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Fly.io pagination — cursor (Sprites list) and Relay (GraphQL add-ons).
3
+ */
4
+ export { paginateCursor, paginateRelay, extractItems, getItems, getPath, type PaginatedTrait, type PaginationStrategy, } from "@distilled.cloud/core/pagination";
5
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,KAAK,cAAc,EACnB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Fly.io pagination — cursor (Sprites list) and Relay (GraphQL add-ons).
3
+ */
4
+ export { paginateCursor, paginateRelay, extractItems, getItems, getPath, } from "@distilled.cloud/core/pagination";
5
+ //# sourceMappingURL=pagination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,cAAc,EACd,aAAa,EACb,YAAY,EACZ,QAAQ,EACR,OAAO,GAGR,MAAM,kCAAkC,CAAC"}
package/lib/protocol.d.ts CHANGED
@@ -1,18 +1,60 @@
1
- import type * as Layer from "effect/Layer";
2
- import type * as HttpClient from "effect/unstable/http/HttpClient";
1
+ /**
2
+ * Fly.io protocols — Machines REST, UI-EX REST (MPG), GraphQL add-ons, and
3
+ * Sprites REST.
4
+ *
5
+ * Machines (`FlyIoProtocol`) is a plain bearer-token JSON API at
6
+ * `api.machines.dev/v1`. MPG (`FlyApiProtocol`) is the same token against
7
+ * `https://api.fly.io`. GraphQL add-ons (`FlyGraphqlProtocol`) POST
8
+ * `{ query, operationName, variables }` to `https://api.fly.io/graphql`.
9
+ *
10
+ * Sprites (`SpritesProtocol`) also resolve `FLY_API_TOKEN` (same
11
+ * {@link Credentials} as Machines). Sprite CRUD rejects a Fly macaroon as
12
+ * Bearer, so the protocol mints a Sprites bearer once:
13
+ *
14
+ * POST https://api.sprites.dev/v1/organizations/{org}/tokens
15
+ * Authorization: FlyV1 {FLY_API_TOKEN}
16
+ *
17
+ * Org slug comes from Machines `GET /tokens/current` (GraphQL fallback).
18
+ * The minted token is cached process-wide, then sent as
19
+ * `Authorization: Bearer` on sprite ops. There is no `SPRITES_TOKEN`.
20
+ */
21
+ import * as Context from "effect/Context";
22
+ import * as Layer from "effect/Layer";
23
+ import * as HttpClient from "effect/unstable/http/HttpClient";
3
24
  import type * as HttpClientError from "effect/unstable/http/HttpClientError";
4
- import type * as API from "@distilled.cloud/core/api";
5
- import type { ConfigError } from "@distilled.cloud/core/errors";
25
+ import * as API from "@distilled.cloud/core/api";
26
+ import { type ConfigError } from "@distilled.cloud/core/errors";
6
27
  import { Credentials } from "./credentials.ts";
7
- import { type DefaultErrors } from "./errors.ts";
28
+ import { CreateExtensionTosAgreementNotAuthorized, SpritesNotEnabled, type DefaultErrors } from "./errors.ts";
8
29
  /**
9
30
  * Error channel shared by every generated Fly.io operation. Generated
10
31
  * service files annotate operations with `API.OperationMethod<I, O,
11
32
  * FlyIoOpError, FlyIoOpContext>` explicitly so the compiler never infers
12
33
  * these back out of the schema generics.
13
34
  */
14
- export type FlyIoOpError = DefaultErrors | ConfigError | HttpClientError.HttpClientError;
15
- /** Context (requirements) shared by every generated Fly.io operation. */
35
+ export type FlyIoOpError = DefaultErrors | ConfigError | CreateExtensionTosAgreementNotAuthorized | HttpClientError.HttpClientError;
36
+ /** Context (requirements) shared by Machines / MPG / GraphQL operations. */
16
37
  export type FlyIoOpContext = Credentials | HttpClient.HttpClient;
38
+ /**
39
+ * Sprites operations resolve {@link Credentials} (`FLY_API_TOKEN`) and mint
40
+ * a Sprites bearer. {@link SpritesNotEnabled} surfaces from that mint.
41
+ */
42
+ export type SpritesOpError = FlyIoOpError | SpritesNotEnabled;
43
+ export type SpritesOpContext = FlyIoOpContext;
44
+ declare const MachineIdentity_base: Context.ServiceClass<MachineIdentity, "FlyIoMachineIdentity", true>;
45
+ /**
46
+ * Per-call signal that this Machines request is the Fly Machine itself
47
+ * (unix socket `/.fly/api`). Org tokens stay on {@link Credentials} for
48
+ * GetSecret in the same process; this service only changes headers:
49
+ * omit `Authorization`, send `Connection: close`.
50
+ */
51
+ export declare class MachineIdentity extends MachineIdentity_base {
52
+ }
17
53
  export declare const FlyIoProtocol: Layer.Layer<API.Protocol>;
54
+ /** MPG UI-EX REST at `https://api.fly.io` with the Machines bearer token. */
55
+ export declare const FlyApiProtocol: Layer.Layer<API.Protocol>;
56
+ /** Sprites REST at `https://api.sprites.dev/v1`, minted from `FLY_API_TOKEN`. */
57
+ export declare const SpritesProtocol: Layer.Layer<API.Protocol>;
58
+ export declare const FlyGraphqlProtocol: Layer.Layer<API.Protocol>;
59
+ export {};
18
60
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,KAAK,UAAU,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAC7E,OAAO,KAAK,KAAK,GAAG,MAAM,2BAA2B,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAe,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAEpE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,WAAW,GACX,eAAe,CAAC,eAAe,CAAC;AAEpC,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAEjE,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAuBhD,CAAC"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAE1C,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAKtC,OAAO,KAAK,UAAU,MAAM,iCAAiC,CAAC;AAC9D,OAAO,KAAK,KAAK,eAAe,MAAM,sCAAsC,CAAC;AAG7E,OAAO,KAAK,GAAG,MAAM,2BAA2B,CAAC;AAYjD,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,WAAW,EAIZ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGL,wCAAwC,EACxC,iBAAiB,EAEjB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AASrB;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,WAAW,GACX,wCAAwC,GACxC,eAAe,CAAC,eAAe,CAAC;AAEpC,4EAA4E;AAC5E,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC;AAEjE;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC;;AAwC9C;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,oBAEpC;CAAG;AAYJ,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAkBZ,CAAC;AAEzC,6EAA6E;AAC7E,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAUjD,CAAC;AA4YL,iFAAiF;AACjF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CASrD,CAAC;AAkLF,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAOxD,CAAC"}