import * as flagship from "@distilled.cloud/cloudflare/flagship"; import * as Provider from "../../Provider.ts"; import { Resource } from "../../Resource.ts"; import { CloudflareEnvironment } from "../CloudflareEnvironment.ts"; import type { Providers } from "../Providers.ts"; declare const TypeId: "Cloudflare.Flagship.Flag"; type TypeId = typeof TypeId; /** * Comparison operator applied to a targeting condition. */ export type FlagConditionOperator = "equals" | "not_equals" | "greater_than" | "less_than" | "greater_than_or_equals" | "less_than_or_equals" | "contains" | "starts_with" | "ends_with" | "in" | "not_in"; /** * A single targeting condition: either a flat attribute comparison or a * nested group of clauses combined with AND/OR. */ export type FlagCondition = { /** * Evaluation-context attribute to match on (e.g. `country`, `userId`). */ attribute: string; /** * Comparison operator. */ operator: FlagConditionOperator; /** * Value to compare against. */ value: unknown; } | { /** * Nested conditions combined with `logicalOperator`. */ clauses: FlagCondition[]; /** * How the clauses combine. */ logicalOperator: "AND" | "OR"; }; /** * Percentage rollout applied after a rule's conditions match. */ export type FlagRollout = { /** * Percentage of matching contexts served the rule's variation (0-100). */ percentage: number; /** * Context attribute used for rollout bucketing. * @default the context's targeting key */ attribute?: string; }; /** * A targeting rule. Rules are evaluated in ascending `priority`; the first * matching rule wins. */ export type FlagRule = { /** * Conditions that must all match for the rule to apply. */ conditions: FlagCondition[]; /** * Evaluation order — lower runs first. */ priority: number; /** * Variation (key in `variations`) served when the rule matches. */ serveVariation: string; /** * Optional percentage rollout applied after the conditions match. */ rollout?: FlagRollout; }; /** * Value type of a flag's variations. */ export type FlagType = "boolean" | "string" | "number" | "json"; export type FlagProps = { /** * The Flagship app the flag belongs to. Changing the app triggers a * replacement. */ appId: string; /** * Unique flag key within the app — used in all evaluation and SDK calls. * Changing the key triggers a replacement. If omitted, a unique key is * generated from the app, stage, and logical ID. * @default ${app}-${stage}-${id} */ key?: string; /** * When false, the flag bypasses all rules and always serves * `defaultVariation`. * @default true */ enabled?: boolean; /** * Variation served when no rule matches or the flag is disabled. Must be a * key in `variations`. */ defaultVariation: string; /** * Map of variation name to value. All values must be the same type * (boolean, string, number, or JSON object/array). Each serialized value * must be 10KB or smaller. */ variations: Record; /** * Targeting rules evaluated in ascending `priority`; the first matching * rule wins. An empty array means the flag always serves * `defaultVariation`. * @default [] */ rules?: FlagRule[]; /** * Human readable description of the flag. */ description?: string; /** * Value type of the flag's variations. Inferred from the variation values * on write, so it can usually be omitted. */ type?: FlagType; }; export type FlagAttributes = { /** * The Flagship app the flag belongs to. */ appId: string; /** * The Cloudflare account the flag belongs to. */ accountId: string; /** * Unique flag key within the app. */ key: string; /** * Whether the flag's rules are evaluated. */ enabled: boolean; /** * Variation served when no rule matches or the flag is disabled. */ defaultVariation: string; /** * Map of variation name to value. */ variations: Record; /** * Targeting rules. */ rules: FlagRule[]; /** * Human readable description of the flag. */ description: string | undefined; /** * Value type of the flag's variations, as inferred by Cloudflare. */ type: FlagType | undefined; /** * When the flag was last modified. */ updatedAt: string | undefined; /** * Email of the actor who last modified the flag, or `edge-gateway` for * gateway-authenticated changes. */ updatedBy: string | undefined; }; export type Flag = Resource; /** * A feature flag in a Cloudflare Flagship app. * * A flag maps a key to a set of variations plus targeting rules. Workers * evaluate flags through the `Flagship` binding (or the REST evaluate * endpoint); changing variations, rules, enablement, or the default * variation takes effect without redeploying code. Everything except the * flag key and the parent app is mutable in place. * ### Creating a Flag * **Example:** Boolean flag * ```typescript * const app = yield* Cloudflare.Flagship.App("Flags", {}); * * const flag = yield* Cloudflare.Flagship.Flag("NewCheckout", { * appId: app.appId, * key: "new-checkout", * defaultVariation: "off", * variations: { off: false, on: true }, * }); * ``` * * **Example:** String flag with multiple variations * ```typescript * const flag = yield* Cloudflare.Flagship.Flag("CheckoutFlow", { * appId: app.appId, * key: "checkout-flow", * defaultVariation: "v1", * variations: { v1: "classic", v2: "express", v3: "one-click" }, * }); * ``` * * ### Targeting Rules * **Example:** Serve a variation to a specific country * ```typescript * const flag = yield* Cloudflare.Flagship.Flag("DarkMode", { * appId: app.appId, * key: "dark-mode", * defaultVariation: "off", * variations: { off: false, on: true }, * rules: [ * { * priority: 1, * conditions: [ * { attribute: "country", operator: "equals", value: "US" }, * ], * serveVariation: "on", * }, * ], * }); * ``` * * **Example:** Percentage rollout * ```typescript * const flag = yield* Cloudflare.Flagship.Flag("NewSearch", { * appId: app.appId, * key: "new-search", * defaultVariation: "off", * variations: { off: false, on: true }, * rules: [ * { * priority: 1, * conditions: [], * serveVariation: "on", * rollout: { percentage: 25 }, * }, * ], * }); * ``` * * ### Toggling a Flag * **Example:** Disable a flag without removing its rules * ```typescript * const flag = yield* Cloudflare.Flagship.Flag("NewCheckout", { * appId: app.appId, * key: "new-checkout", * enabled: false, * defaultVariation: "off", * variations: { off: false, on: true }, * }); * ``` * * @see https://developers.cloudflare.com/flagship/ * @see https://developers.cloudflare.com/api/resources/flagship/ * * @resource * @product Flagship * @category Developer Platform */ export declare const Flag: import("../../Resource.ts").ResourceClass; /** * Returns true if the given value is a Flagship Flag resource. */ export declare const isFlag: (value: unknown) => value is Flag; export declare const FlagProvider: () => import("effect/Layer").Layer, never, CloudflareEnvironment | import("../../Stack.ts").Stack | import("../../Stage.ts").Stage | flagship.CloudflareOpContext>; export {}; //# sourceMappingURL=Flag.d.ts.map