@palbase/backend 14.1.0 → 14.3.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.
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError } from './endpoint-D2yR2RD1.cjs';
2
- export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Materialized, o as Middleware, p as MiddlewareContext, q as MiddlewareHandler, N as NotFound, P as PBRequest, r as PalError, s as PalbaseAnalyticsClient, t as PalbaseAnalyticsManagementNamespace, u as PalbaseAnalyticsProperties, v as PalbaseAnalyticsQueryNamespace, w as PalbaseAttestAndroidParams, x as PalbaseAttestAndroidResult, y as PalbaseAttestiOSParams, z as PalbaseAttestiOSResult, G as PalbaseAuthClient, I as PalbaseBatchOverrideOperation, J as PalbaseBatchSetOverridesResult, K as PalbaseBindDeviceParams, O as PalbaseBucketClient, Q as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as Ref, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, b7 as TxPlanBody, b8 as TxPlanError, b9 as TxPlanHandle, ba as TxPlanOpResult, bb as TxPlanRejection, bc as TxPlanResponse, bd as TxRefError, be as TxRow, bf as TxRows, bg as TxSelectOptions, bh as TxSetShape, bi as TxSetValue, bj as TxTable, bk as TxWhere, bl as TxWireExpr, bm as TxWireGuard, bn as TxWireOp, bo as TxWireRef, bp as TxWireValue, bq as Unauthorized, U as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-D2yR2RD1.cjs';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError } from './endpoint-BG-JVUPL.cjs';
2
+ export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Materialized, o as Middleware, p as MiddlewareContext, q as MiddlewareHandler, N as NotFound, P as PBRequest, r as PalError, s as PalbaseAnalyticsClient, t as PalbaseAnalyticsManagementNamespace, u as PalbaseAnalyticsProperties, v as PalbaseAnalyticsQueryNamespace, w as PalbaseAttestAndroidParams, x as PalbaseAttestAndroidResult, y as PalbaseAttestiOSParams, z as PalbaseAttestiOSResult, G as PalbaseAuthClient, I as PalbaseBatchOverrideOperation, J as PalbaseBatchSetOverridesResult, K as PalbaseBindDeviceParams, O as PalbaseBucketClient, Q as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as Ref, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, b7 as TxPlanBody, b8 as TxPlanError, b9 as TxPlanHandle, ba as TxPlanOpResult, bb as TxPlanRejection, bc as TxPlanResponse, bd as TxRefError, be as TxRow, bf as TxRows, bg as TxSelectOptions, bh as TxSetShape, bi as TxSetValue, bj as TxTable, bk as TxWhere, bl as TxWireExpr, bm as TxWireGuard, bn as TxWireOp, bo as TxWireRef, bp as TxWireValue, bq as Unauthorized, U as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-BG-JVUPL.cjs';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { E as EnvTypedDatabase, S as SchemaDef } from './index-BcA7wqur.cjs';
5
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, h as PalbaseExtension, i as PolicyBuilder, j as PolicyCommand, k as PolicyDef, l as PolicyMode, R as RawConstraintDef, m as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TxPlan, q as TxTables, r as TypedDB, s as TypedTable, t as TypedTx, u as bigint, v as boolean, w as defineSchema, x as enumType, y as integer, z as isPalbaseExtension, A as jsonb, B as makeTypedDB, D as numeric, F as policy, G as raw, H as text, J as timestamp, K as uuid } from './index-BcA7wqur.cjs';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-j3ZZS_VS.cjs';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, h as PalbaseExtension, i as PolicyBuilder, j as PolicyCommand, k as PolicyDef, l as PolicyMode, R as RawConstraintDef, m as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TxPlan, q as TxTables, r as TypedDB, s as TypedTable, t as TypedTx, u as bigint, v as boolean, w as defineSchema, x as enumType, y as integer, z as isPalbaseExtension, A as jsonb, B as makeTypedDB, D as numeric, F as policy, G as raw, H as text, J as timestamp, K as uuid } from './index-j3ZZS_VS.cjs';
6
6
  import { EntitlementKey, LimitKey } from './purchases/keys.cjs';
7
7
  import { TableTypes, Tables } from './db/env.cjs';
8
8
  import { ZodTypeAny, z } from 'zod';
@@ -747,6 +747,92 @@ interface TwilioOptions {
747
747
  /** The union of every provider's author-facing options. `buildProvider` accepts
748
748
  * this so each provider's typed options pass without a cast. */
749
749
  type ProviderOptions = ApnsOptions | FcmOptions | SendgridOptions | SesOptions | SmtpOptions | AcsOptions | TwilioOptions;
750
+ /** The default locale a template row lands on when the author names none. Must
751
+ * match PalNotify's `model.DefaultLocale`. */
752
+ declare const DEFAULT_TEMPLATE_LOCALE: "en";
753
+ /** One locale's email content. */
754
+ interface EmailTemplateContent {
755
+ /** Subject line. Handlebars placeholders (`{{name}}`) are rendered at send. */
756
+ subject: string;
757
+ /** HTML body. */
758
+ html: string;
759
+ /** Plain-text body. Omit and the server derives one from `html` at render. */
760
+ text?: string;
761
+ /**
762
+ * Variables the sender MUST supply. Omit and they are DERIVED from the
763
+ * `{{placeholders}}` in this locale's content — see {@link extractVariables}.
764
+ * Supply explicitly to make a placeholder optional (leave it out of the list)
765
+ * or to require something a conditional references.
766
+ */
767
+ variables?: readonly string[];
768
+ }
769
+ /** An email template: base content, plus optional per-locale overrides. */
770
+ interface EmailTemplateOptions extends EmailTemplateContent {
771
+ /** Locale of the base content. Defaults to `"en"`. */
772
+ locale?: string;
773
+ /** Additional locales, keyed by BCP47 short tag (`tr`, `de`, …). */
774
+ locales?: Record<string, EmailTemplateContent>;
775
+ }
776
+ /** One locale's SMS content. */
777
+ interface SmsTemplateContent {
778
+ /** Message body. Handlebars placeholders are rendered at send. */
779
+ body: string;
780
+ /** Variables the sender must supply. Derived from `body` when omitted. */
781
+ variables?: readonly string[];
782
+ }
783
+ /** An SMS template: base content, plus optional per-locale overrides. */
784
+ interface SmsTemplateOptions extends SmsTemplateContent {
785
+ /** Locale of the base content. Defaults to `"en"`. */
786
+ locale?: string;
787
+ /** Additional locales, keyed by BCP47 short tag. */
788
+ locales?: Record<string, SmsTemplateContent>;
789
+ }
790
+ /** Author-facing templates block: slug → template. */
791
+ interface TemplatesInput {
792
+ email?: Record<string, EmailTemplateOptions>;
793
+ sms?: Record<string, SmsTemplateOptions>;
794
+ }
795
+ /** A compiled email-template row — one (slug, locale) pair, in the snake_case
796
+ * wire shape PalNotify's templates API takes. */
797
+ interface EmailTemplateDef {
798
+ slug: string;
799
+ locale: string;
800
+ subject: string;
801
+ html_body: string;
802
+ text_body?: string;
803
+ variables: string[];
804
+ }
805
+ /** A compiled SMS-template row — one (slug, locale) pair. */
806
+ interface SmsTemplateDef {
807
+ slug: string;
808
+ locale: string;
809
+ body: string;
810
+ variables: string[];
811
+ }
812
+ /** The compiled templates block: flat, per-channel row lists. Flat rows (rather
813
+ * than a nested locale map) are what the apply step iterates — one row is one
814
+ * upsert against the (slug, locale) unique key. */
815
+ interface TemplatesConfig {
816
+ email: EmailTemplateDef[];
817
+ sms: SmsTemplateDef[];
818
+ }
819
+ /**
820
+ * Pull the variable names out of Handlebars content.
821
+ *
822
+ * Only PLAIN mustaches count: `{{name}}` and `{{{name}}}`. Deliberately skipped:
823
+ * - block/section/partial/comment tokens (`{{#if}}`, `{{/if}}`, `{{else}}`,
824
+ * `{{> partial}}`, `{{! comment}}`) — structure, not data the sender passes;
825
+ * - helper calls (`{{formatDate at}}`) — the first token is a helper name;
826
+ * - `this` and `@index`-style frame references.
827
+ *
828
+ * A dotted path contributes its ROOT (`{{user.name}}` → `user`), because that is
829
+ * what the sender actually has to hand over.
830
+ *
831
+ * The list is what the server ENFORCES as required at render time, so keeping it
832
+ * to the unambiguous cases is the point: an over-eager derivation would turn an
833
+ * optional conditional into a mandatory argument and 400 real sends.
834
+ */
835
+ declare function extractVariables(...sources: (string | undefined)[]): string[];
750
836
  /** The author-facing input to `defineNotifications`. Every provider + every
751
837
  * channel is optional — declare only what you use. */
752
838
  interface NotificationsInput {
@@ -763,6 +849,8 @@ interface NotificationsInput {
763
849
  sms?: {
764
850
  twilio?: TwilioOptions;
765
851
  };
852
+ /** Email + SMS templates, keyed by slug. Applied on every deploy. */
853
+ templates?: TemplatesInput;
766
854
  }
767
855
  /** A compiled provider def. `enabled` is always present; the remaining keys are
768
856
  * the provider's non-secret fields (verbatim from the catalog). A disabled
@@ -778,6 +866,7 @@ interface NotificationsConfig {
778
866
  push: Record<string, ProviderDef>;
779
867
  email: Record<string, ProviderDef>;
780
868
  sms: Record<string, ProviderDef>;
869
+ templates: TemplatesConfig;
781
870
  }
782
871
  /**
783
872
  * Compile + validate one provider's author options into a {@link ProviderDef}.
@@ -1086,23 +1175,100 @@ type FlagOptions = {
1086
1175
  type: "boolean";
1087
1176
  default: boolean;
1088
1177
  variants?: never;
1178
+ conditions?: FlagCondition<boolean>[];
1089
1179
  description?: string;
1090
1180
  } | {
1091
1181
  type: "number";
1092
1182
  default: number;
1093
1183
  variants?: never;
1184
+ conditions?: FlagCondition<number>[];
1094
1185
  description?: string;
1095
1186
  } | {
1096
1187
  type: "string";
1097
1188
  default: string;
1098
1189
  variants?: string[];
1190
+ conditions?: FlagCondition<string>[];
1099
1191
  description?: string;
1100
1192
  } | {
1101
1193
  type: "json";
1102
1194
  default: FlagJsonObject;
1103
1195
  variants?: never;
1196
+ conditions?: FlagCondition<FlagJsonObject>[];
1104
1197
  description?: string;
1105
1198
  };
1199
+ /**
1200
+ * One targeting branch: the value this flag resolves to when `when` matches the
1201
+ * caller's client context. Branch ORDER is priority — the first match wins, and
1202
+ * a flag with no matching branch falls back to its `default`.
1203
+ *
1204
+ * `when` is a small expression over what the client declares about itself:
1205
+ *
1206
+ * ```
1207
+ * client.platform == 'ios' && client.app_version >= '2.0.0'
1208
+ * client.locale startsWith 'tr'
1209
+ * client.platform in ['ios', 'android']
1210
+ * ```
1211
+ *
1212
+ * Those are CLAIMS, not proof — the server treats them as attacker-controlled.
1213
+ * They select WHICH value a caller sees, never WHETHER they may see it, so a
1214
+ * condition must not be the thing standing between a user and something paid.
1215
+ */
1216
+ /**
1217
+ * The variables the server exposes. Mirrors `declaredVars` in
1218
+ * `modules/user-flags/internal/conditions/conditions.go`; the server rejects
1219
+ * anything it does not know, so the worst a stale copy here does is offer too
1220
+ * little.
1221
+ *
1222
+ * `client.*` is what the SDK reports about the caller. `percentile` and
1223
+ * `server.now` are DERIVED server-side and cannot be moved by a lying client,
1224
+ * which is what makes a rollout or a time window mean anything.
1225
+ */
1226
+ type StringVar = "client.platform" | "client.locale";
1227
+ type SemverVar = "client.app_version" | "client.os_version";
1228
+ type EqualityOp = "==" | "!=";
1229
+ /** Ordering only where order exists — a platform string has none. */
1230
+ type OrderedOp = EqualityOp | "<" | "<=" | ">" | ">=";
1231
+ type TextOp = EqualityOp | "startsWith" | "endsWith" | "contains";
1232
+ /** A single-quoted literal. Quoting is the mistake people make most. */
1233
+ type Quoted = `'${string}'`;
1234
+ type Comparison = `${StringVar} ${TextOp} ${Quoted}` | `${StringVar} in [${string}]` | `${SemverVar} ${OrderedOp} ${Quoted}` | `percentile ${OrderedOp} ${number}` | `server.now ${OrderedOp} ${Quoted}`;
1235
+ /**
1236
+ * One expression: a comparison, optionally chained with `&&` / `||`, or a
1237
+ * parenthesised group.
1238
+ *
1239
+ * ONE level, and the limit is TypeScript's, not a preference. Unrolling a second
1240
+ * level produced `TS2590: union type too complex`, and the failure mode there is
1241
+ * the worst possible one: the checker gives up and the type silently degrades to
1242
+ * `string`, so NOTHING is checked while the code still compiles. Measured, not
1243
+ * assumed — the two-level version accepted `client.app_verison` without
1244
+ * complaint.
1245
+ *
1246
+ * So the FIRST term is fully checked and the rest of a chain is not. That is
1247
+ * where the mistakes are: a rule is usually one comparison, and a typo in the
1248
+ * first one is the common case. A typo after an `&&` still reaches the server,
1249
+ * which parses the real grammar and rejects it.
1250
+ *
1251
+ * A group's contents go unchecked for the same reason.
1252
+ */
1253
+ type FlagConditionExpression = Comparison | `${Comparison} && ${string}` | `${Comparison} || ${string}` | `(${string})`;
1254
+ interface FlagCondition<V> {
1255
+ when: FlagConditionExpression;
1256
+ value: V;
1257
+ }
1258
+ /**
1259
+ * The COMPILED shape of a condition — the JSON actually emitted and parsed by
1260
+ * the Go apply step.
1261
+ *
1262
+ * `when` widens back to `string` here on purpose. The narrow type is an
1263
+ * authoring aid; once the expression has been trimmed and serialised it is just
1264
+ * text on the wire, and keeping the template-literal type would force a cast on
1265
+ * every string operation without checking anything the author had not already
1266
+ * been checked on.
1267
+ */
1268
+ interface CompiledFlagCondition<V> {
1269
+ when: string;
1270
+ value: V;
1271
+ }
1106
1272
  /**
1107
1273
  * The compiled, serializable flag definition — the EXACT shape emitted to JSON
1108
1274
  * and consumed by the Go apply step.
@@ -1117,6 +1283,8 @@ interface FlagDef {
1117
1283
  type: FlagType;
1118
1284
  default: FlagValue;
1119
1285
  variants: string[] | null;
1286
+ /** Ordered targeting branches, or `null` when the flag is unconditional. */
1287
+ conditions: CompiledFlagCondition<FlagValue>[] | null;
1120
1288
  description: string | null;
1121
1289
  }
1122
1290
  /** A flags config definition: the discriminant + a map of flag key →
@@ -1715,4 +1883,4 @@ declare const documents: {
1715
1883
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
1716
1884
  };
1717
1885
 
1718
- export { type AcsOptions, type ApnsOptions, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, EGRESS_CONFIG_KIND, EGRESS_TIMEOUT_DEFAULT_MS, EGRESS_TIMEOUT_MAX_MS, EGRESS_TIMEOUT_MIN_MS, type EgressConfig, type EgressInput, EntitlementKey, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagJsonObject, type FlagJsonValue, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, Job, type JobMeta, type JobOptions, LimitKey, type LimitState, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, On, OptionalUser, type OwnedTablesOf, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type ParamKind, type ParamMeta, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderName, type ProviderOptions, Purchases, type PurchasesManifest, type PurchasesService, Put, Query, QueryParams, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type RequestStore, RequireEntitlement, type ResolvedHook, type ResolvedJob, type ResolvedWebhook, Resource, type ResourceEnv, type RouteMeta, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type Seed, type SeedFor, type SeedJson, type SeedRowFor, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SignatureSpec, type SmtpOptions, Spend, type SpendMeta, type SpendOptions, Storage, type StorageConfig, type StorageInput, type StoreEnv, TEST_USERS_CONFIG_KIND, type TableGraph, TableTypes, Tables, type TestUserDef, type TestUserOptions, type TestUsersConfig, type TestUsersInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineEgress, defineError, defineFlags, defineNotifications, defineStorage, defineTestUsers, documents, entitlementFor, flag, getErrorRegistry, getJobConfig, getRoutes, getWebhookConfig, makeEnvDts, makePurchasesDts, parseFileSizeLimit, recordThrows, reservedSecretKey, spendFor, storage, testUser, validateUploadAgainstStorage };
1886
+ export { type AcsOptions, type ApnsOptions, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, DBClient, DEFAULT_TEMPLATE_LOCALE, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, EGRESS_CONFIG_KIND, EGRESS_TIMEOUT_DEFAULT_MS, EGRESS_TIMEOUT_MAX_MS, EGRESS_TIMEOUT_MIN_MS, type EgressConfig, type EgressInput, type EmailTemplateContent, type EmailTemplateDef, type EmailTemplateOptions, EntitlementKey, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagJsonObject, type FlagJsonValue, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, Job, type JobMeta, type JobOptions, LimitKey, type LimitState, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, On, OptionalUser, type OwnedTablesOf, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type ParamKind, type ParamMeta, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderName, type ProviderOptions, Purchases, type PurchasesManifest, type PurchasesService, Put, Query, QueryParams, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type RequestStore, RequireEntitlement, type ResolvedHook, type ResolvedJob, type ResolvedWebhook, Resource, type ResourceEnv, type RouteMeta, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type Seed, type SeedFor, type SeedJson, type SeedRowFor, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SignatureSpec, type SmsTemplateContent, type SmsTemplateDef, type SmsTemplateOptions, type SmtpOptions, Spend, type SpendMeta, type SpendOptions, Storage, type StorageConfig, type StorageInput, type StoreEnv, TEST_USERS_CONFIG_KIND, type TableGraph, TableTypes, Tables, type TemplatesConfig, type TemplatesInput, type TestUserDef, type TestUserOptions, type TestUsersConfig, type TestUsersInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineEgress, defineError, defineFlags, defineNotifications, defineStorage, defineTestUsers, documents, entitlementFor, extractVariables, flag, getErrorRegistry, getJobConfig, getRoutes, getWebhookConfig, makeEnvDts, makePurchasesDts, parseFileSizeLimit, recordThrows, reservedSecretKey, spendFor, storage, testUser, validateUploadAgainstStorage };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError } from './endpoint-D2yR2RD1.js';
2
- export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Materialized, o as Middleware, p as MiddlewareContext, q as MiddlewareHandler, N as NotFound, P as PBRequest, r as PalError, s as PalbaseAnalyticsClient, t as PalbaseAnalyticsManagementNamespace, u as PalbaseAnalyticsProperties, v as PalbaseAnalyticsQueryNamespace, w as PalbaseAttestAndroidParams, x as PalbaseAttestAndroidResult, y as PalbaseAttestiOSParams, z as PalbaseAttestiOSResult, G as PalbaseAuthClient, I as PalbaseBatchOverrideOperation, J as PalbaseBatchSetOverridesResult, K as PalbaseBindDeviceParams, O as PalbaseBucketClient, Q as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as Ref, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, b7 as TxPlanBody, b8 as TxPlanError, b9 as TxPlanHandle, ba as TxPlanOpResult, bb as TxPlanRejection, bc as TxPlanResponse, bd as TxRefError, be as TxRow, bf as TxRows, bg as TxSelectOptions, bh as TxSetShape, bi as TxSetValue, bj as TxTable, bk as TxWhere, bl as TxWireExpr, bm as TxWireGuard, bn as TxWireOp, bo as TxWireRef, bp as TxWireValue, bq as Unauthorized, U as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-D2yR2RD1.js';
1
+ import { C as CacheClient, b as PalbaseDocsClient, c as PalbaseFlagsClient, L as Logger, d as PalbaseNotificationsClient, e as PalbaseRealtimeClient, D as DBClient, f as PalbaseStorageClient, A as AuthSpec, R as RateLimitConfig, H as HttpError } from './endpoint-BG-JVUPL.js';
2
+ export { g as AuthConfig, B as BadRequest, h as ClientInfo, i as Conflict, j as DBOps, E as ErrorDef, k as ErrorMap, l as ErrorThrowers, F as FileContext, m as Forbidden, n as HttpMethod, M as Materialized, o as Middleware, p as MiddlewareContext, q as MiddlewareHandler, N as NotFound, P as PBRequest, r as PalError, s as PalbaseAnalyticsClient, t as PalbaseAnalyticsManagementNamespace, u as PalbaseAnalyticsProperties, v as PalbaseAnalyticsQueryNamespace, w as PalbaseAttestAndroidParams, x as PalbaseAttestAndroidResult, y as PalbaseAttestiOSParams, z as PalbaseAttestiOSResult, G as PalbaseAuthClient, I as PalbaseBatchOverrideOperation, J as PalbaseBatchSetOverridesResult, K as PalbaseBindDeviceParams, O as PalbaseBucketClient, Q as PalbaseClearAllOverridesResult, S as PalbaseClearOverrideResult, T as PalbaseCohortQueryInput, V as PalbaseCohortResult, W as PalbaseCollectionRef, X as PalbaseCountQueryInput, Y as PalbaseCountResult, Z as PalbaseCreateLinkParams, _ as PalbaseDeviceInfo, $ as PalbaseDeviceTokenView, a0 as PalbaseDocumentRef, a1 as PalbaseDocumentSnapshot, a2 as PalbaseEmailClient, a3 as PalbaseEmailSendParams, a4 as PalbaseEmailSendResponse, a5 as PalbaseEventNamesResult, a6 as PalbaseEventsQueryInput, a7 as PalbaseEventsResult, a8 as PalbaseFileObject, a9 as PalbaseFlag, aa as PalbaseFlagContext, ab as PalbaseFlagSource, ac as PalbaseFlagValue, ad as PalbaseFlagVariant, ae as PalbaseFlagsServiceClient, af as PalbaseFunctionsClient, ag as PalbaseFunnelQueryInput, ah as PalbaseFunnelResult, ai as PalbaseIdentifyTraits, aj as PalbaseInboxClient, ak as PalbaseInboxListOptions, al as PalbaseInboxListResult, am as PalbaseInboxMessage, an as PalbaseInboxSendParams, ao as PalbaseInboxSendResponse, ap as PalbaseInitialLink, aq as PalbaseInvokeOptions, ar as PalbaseLink, as as PalbaseLinkAnalytics, at as PalbaseLinkDetails, au as PalbaseLinksClient, av as PalbaseListLinksOptions, aw as PalbaseListLinksResult, ax as PalbaseListOptions, ay as PalbaseMatchParams, az as PalbaseMultiChannelResponse, aA as PalbaseOverviewResult, aB as PalbasePreferences, aC as PalbasePreferencesClient, aD as PalbasePublicUrlResponse, aE as PalbasePushClient, aF as PalbasePushSendParams, aG as PalbasePushSendResponse, aH as PalbaseQrCodeOptions, aI as PalbaseQuerySnapshot, aJ as PalbaseRegisterDeviceParams, aK as PalbaseResult, aL as PalbaseRetentionQueryInput, aM as PalbaseRetentionResult, aN as PalbaseSession, aO as PalbaseSetOverrideResult, aP as PalbaseSetOverridesResult, aQ as PalbaseSignedUrlResponse, aR as PalbaseSmsClient, aS as PalbaseSmsSendParams, aT as PalbaseSmsSendResponse, aU as PalbaseTransformOptions, aV as PalbaseUpdateLinkParams, aW as PalbaseUploadOptions, aX as PalbaseUser, aY as PalbaseUserDetailResult, aZ as PalbaseUsersQueryInput, a_ as PalbaseUsersResult, a$ as PalbaseVerifyRequestSignatureParams, b0 as PalbaseWhereOperator, b1 as Ref, b2 as TooManyRequests, b3 as TxColumnExpr, b4 as TxInsertShape, b5 as TxInsertValue, b6 as TxNow, b7 as TxPlanBody, b8 as TxPlanError, b9 as TxPlanHandle, ba as TxPlanOpResult, bb as TxPlanRejection, bc as TxPlanResponse, bd as TxRefError, be as TxRow, bf as TxRows, bg as TxSelectOptions, bh as TxSetShape, bi as TxSetValue, bj as TxTable, bk as TxWhere, bl as TxWireExpr, bm as TxWireGuard, bn as TxWireOp, bo as TxWireRef, bp as TxWireValue, bq as Unauthorized, U as UserT, br as VerifiedDevice, bs as dec, bt as defineMiddleware, bu as inc, bv as now } from './endpoint-BG-JVUPL.js';
3
3
  import { AsyncLocalStorage } from 'node:async_hooks';
4
- import { E as EnvTypedDatabase, S as SchemaDef } from './index-CB8TARW4.js';
5
- export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, h as PalbaseExtension, i as PolicyBuilder, j as PolicyCommand, k as PolicyDef, l as PolicyMode, R as RawConstraintDef, m as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TxPlan, q as TxTables, r as TypedDB, s as TypedTable, t as TypedTx, u as bigint, v as boolean, w as defineSchema, x as enumType, y as integer, z as isPalbaseExtension, A as jsonb, B as makeTypedDB, D as numeric, F as policy, G as raw, H as text, J as timestamp, K as uuid } from './index-CB8TARW4.js';
4
+ import { E as EnvTypedDatabase, S as SchemaDef } from './index-QQ2byWrv.js';
5
+ export { C as ColumnBuilder, a as ColumnDef, b as ColumnMap, c as ColumnType, d as EXTENSION_DEPENDENCIES, e as EnvServiceDatabase, f as EnvTables, g as EnvTypedTable, I as InsertShape, O as OnDeleteAction, P as PALBASE_EXTENSIONS, h as PalbaseExtension, i as PolicyBuilder, j as PolicyCommand, k as PolicyDef, l as PolicyMode, R as RawConstraintDef, m as RowShape, n as SchemaInput, T as TableDef, o as TableInput, p as TxPlan, q as TxTables, r as TypedDB, s as TypedTable, t as TypedTx, u as bigint, v as boolean, w as defineSchema, x as enumType, y as integer, z as isPalbaseExtension, A as jsonb, B as makeTypedDB, D as numeric, F as policy, G as raw, H as text, J as timestamp, K as uuid } from './index-QQ2byWrv.js';
6
6
  import { EntitlementKey, LimitKey } from './purchases/keys.js';
7
7
  import { TableTypes, Tables } from './db/env.js';
8
8
  import { ZodTypeAny, z } from 'zod';
@@ -747,6 +747,92 @@ interface TwilioOptions {
747
747
  /** The union of every provider's author-facing options. `buildProvider` accepts
748
748
  * this so each provider's typed options pass without a cast. */
749
749
  type ProviderOptions = ApnsOptions | FcmOptions | SendgridOptions | SesOptions | SmtpOptions | AcsOptions | TwilioOptions;
750
+ /** The default locale a template row lands on when the author names none. Must
751
+ * match PalNotify's `model.DefaultLocale`. */
752
+ declare const DEFAULT_TEMPLATE_LOCALE: "en";
753
+ /** One locale's email content. */
754
+ interface EmailTemplateContent {
755
+ /** Subject line. Handlebars placeholders (`{{name}}`) are rendered at send. */
756
+ subject: string;
757
+ /** HTML body. */
758
+ html: string;
759
+ /** Plain-text body. Omit and the server derives one from `html` at render. */
760
+ text?: string;
761
+ /**
762
+ * Variables the sender MUST supply. Omit and they are DERIVED from the
763
+ * `{{placeholders}}` in this locale's content — see {@link extractVariables}.
764
+ * Supply explicitly to make a placeholder optional (leave it out of the list)
765
+ * or to require something a conditional references.
766
+ */
767
+ variables?: readonly string[];
768
+ }
769
+ /** An email template: base content, plus optional per-locale overrides. */
770
+ interface EmailTemplateOptions extends EmailTemplateContent {
771
+ /** Locale of the base content. Defaults to `"en"`. */
772
+ locale?: string;
773
+ /** Additional locales, keyed by BCP47 short tag (`tr`, `de`, …). */
774
+ locales?: Record<string, EmailTemplateContent>;
775
+ }
776
+ /** One locale's SMS content. */
777
+ interface SmsTemplateContent {
778
+ /** Message body. Handlebars placeholders are rendered at send. */
779
+ body: string;
780
+ /** Variables the sender must supply. Derived from `body` when omitted. */
781
+ variables?: readonly string[];
782
+ }
783
+ /** An SMS template: base content, plus optional per-locale overrides. */
784
+ interface SmsTemplateOptions extends SmsTemplateContent {
785
+ /** Locale of the base content. Defaults to `"en"`. */
786
+ locale?: string;
787
+ /** Additional locales, keyed by BCP47 short tag. */
788
+ locales?: Record<string, SmsTemplateContent>;
789
+ }
790
+ /** Author-facing templates block: slug → template. */
791
+ interface TemplatesInput {
792
+ email?: Record<string, EmailTemplateOptions>;
793
+ sms?: Record<string, SmsTemplateOptions>;
794
+ }
795
+ /** A compiled email-template row — one (slug, locale) pair, in the snake_case
796
+ * wire shape PalNotify's templates API takes. */
797
+ interface EmailTemplateDef {
798
+ slug: string;
799
+ locale: string;
800
+ subject: string;
801
+ html_body: string;
802
+ text_body?: string;
803
+ variables: string[];
804
+ }
805
+ /** A compiled SMS-template row — one (slug, locale) pair. */
806
+ interface SmsTemplateDef {
807
+ slug: string;
808
+ locale: string;
809
+ body: string;
810
+ variables: string[];
811
+ }
812
+ /** The compiled templates block: flat, per-channel row lists. Flat rows (rather
813
+ * than a nested locale map) are what the apply step iterates — one row is one
814
+ * upsert against the (slug, locale) unique key. */
815
+ interface TemplatesConfig {
816
+ email: EmailTemplateDef[];
817
+ sms: SmsTemplateDef[];
818
+ }
819
+ /**
820
+ * Pull the variable names out of Handlebars content.
821
+ *
822
+ * Only PLAIN mustaches count: `{{name}}` and `{{{name}}}`. Deliberately skipped:
823
+ * - block/section/partial/comment tokens (`{{#if}}`, `{{/if}}`, `{{else}}`,
824
+ * `{{> partial}}`, `{{! comment}}`) — structure, not data the sender passes;
825
+ * - helper calls (`{{formatDate at}}`) — the first token is a helper name;
826
+ * - `this` and `@index`-style frame references.
827
+ *
828
+ * A dotted path contributes its ROOT (`{{user.name}}` → `user`), because that is
829
+ * what the sender actually has to hand over.
830
+ *
831
+ * The list is what the server ENFORCES as required at render time, so keeping it
832
+ * to the unambiguous cases is the point: an over-eager derivation would turn an
833
+ * optional conditional into a mandatory argument and 400 real sends.
834
+ */
835
+ declare function extractVariables(...sources: (string | undefined)[]): string[];
750
836
  /** The author-facing input to `defineNotifications`. Every provider + every
751
837
  * channel is optional — declare only what you use. */
752
838
  interface NotificationsInput {
@@ -763,6 +849,8 @@ interface NotificationsInput {
763
849
  sms?: {
764
850
  twilio?: TwilioOptions;
765
851
  };
852
+ /** Email + SMS templates, keyed by slug. Applied on every deploy. */
853
+ templates?: TemplatesInput;
766
854
  }
767
855
  /** A compiled provider def. `enabled` is always present; the remaining keys are
768
856
  * the provider's non-secret fields (verbatim from the catalog). A disabled
@@ -778,6 +866,7 @@ interface NotificationsConfig {
778
866
  push: Record<string, ProviderDef>;
779
867
  email: Record<string, ProviderDef>;
780
868
  sms: Record<string, ProviderDef>;
869
+ templates: TemplatesConfig;
781
870
  }
782
871
  /**
783
872
  * Compile + validate one provider's author options into a {@link ProviderDef}.
@@ -1086,23 +1175,100 @@ type FlagOptions = {
1086
1175
  type: "boolean";
1087
1176
  default: boolean;
1088
1177
  variants?: never;
1178
+ conditions?: FlagCondition<boolean>[];
1089
1179
  description?: string;
1090
1180
  } | {
1091
1181
  type: "number";
1092
1182
  default: number;
1093
1183
  variants?: never;
1184
+ conditions?: FlagCondition<number>[];
1094
1185
  description?: string;
1095
1186
  } | {
1096
1187
  type: "string";
1097
1188
  default: string;
1098
1189
  variants?: string[];
1190
+ conditions?: FlagCondition<string>[];
1099
1191
  description?: string;
1100
1192
  } | {
1101
1193
  type: "json";
1102
1194
  default: FlagJsonObject;
1103
1195
  variants?: never;
1196
+ conditions?: FlagCondition<FlagJsonObject>[];
1104
1197
  description?: string;
1105
1198
  };
1199
+ /**
1200
+ * One targeting branch: the value this flag resolves to when `when` matches the
1201
+ * caller's client context. Branch ORDER is priority — the first match wins, and
1202
+ * a flag with no matching branch falls back to its `default`.
1203
+ *
1204
+ * `when` is a small expression over what the client declares about itself:
1205
+ *
1206
+ * ```
1207
+ * client.platform == 'ios' && client.app_version >= '2.0.0'
1208
+ * client.locale startsWith 'tr'
1209
+ * client.platform in ['ios', 'android']
1210
+ * ```
1211
+ *
1212
+ * Those are CLAIMS, not proof — the server treats them as attacker-controlled.
1213
+ * They select WHICH value a caller sees, never WHETHER they may see it, so a
1214
+ * condition must not be the thing standing between a user and something paid.
1215
+ */
1216
+ /**
1217
+ * The variables the server exposes. Mirrors `declaredVars` in
1218
+ * `modules/user-flags/internal/conditions/conditions.go`; the server rejects
1219
+ * anything it does not know, so the worst a stale copy here does is offer too
1220
+ * little.
1221
+ *
1222
+ * `client.*` is what the SDK reports about the caller. `percentile` and
1223
+ * `server.now` are DERIVED server-side and cannot be moved by a lying client,
1224
+ * which is what makes a rollout or a time window mean anything.
1225
+ */
1226
+ type StringVar = "client.platform" | "client.locale";
1227
+ type SemverVar = "client.app_version" | "client.os_version";
1228
+ type EqualityOp = "==" | "!=";
1229
+ /** Ordering only where order exists — a platform string has none. */
1230
+ type OrderedOp = EqualityOp | "<" | "<=" | ">" | ">=";
1231
+ type TextOp = EqualityOp | "startsWith" | "endsWith" | "contains";
1232
+ /** A single-quoted literal. Quoting is the mistake people make most. */
1233
+ type Quoted = `'${string}'`;
1234
+ type Comparison = `${StringVar} ${TextOp} ${Quoted}` | `${StringVar} in [${string}]` | `${SemverVar} ${OrderedOp} ${Quoted}` | `percentile ${OrderedOp} ${number}` | `server.now ${OrderedOp} ${Quoted}`;
1235
+ /**
1236
+ * One expression: a comparison, optionally chained with `&&` / `||`, or a
1237
+ * parenthesised group.
1238
+ *
1239
+ * ONE level, and the limit is TypeScript's, not a preference. Unrolling a second
1240
+ * level produced `TS2590: union type too complex`, and the failure mode there is
1241
+ * the worst possible one: the checker gives up and the type silently degrades to
1242
+ * `string`, so NOTHING is checked while the code still compiles. Measured, not
1243
+ * assumed — the two-level version accepted `client.app_verison` without
1244
+ * complaint.
1245
+ *
1246
+ * So the FIRST term is fully checked and the rest of a chain is not. That is
1247
+ * where the mistakes are: a rule is usually one comparison, and a typo in the
1248
+ * first one is the common case. A typo after an `&&` still reaches the server,
1249
+ * which parses the real grammar and rejects it.
1250
+ *
1251
+ * A group's contents go unchecked for the same reason.
1252
+ */
1253
+ type FlagConditionExpression = Comparison | `${Comparison} && ${string}` | `${Comparison} || ${string}` | `(${string})`;
1254
+ interface FlagCondition<V> {
1255
+ when: FlagConditionExpression;
1256
+ value: V;
1257
+ }
1258
+ /**
1259
+ * The COMPILED shape of a condition — the JSON actually emitted and parsed by
1260
+ * the Go apply step.
1261
+ *
1262
+ * `when` widens back to `string` here on purpose. The narrow type is an
1263
+ * authoring aid; once the expression has been trimmed and serialised it is just
1264
+ * text on the wire, and keeping the template-literal type would force a cast on
1265
+ * every string operation without checking anything the author had not already
1266
+ * been checked on.
1267
+ */
1268
+ interface CompiledFlagCondition<V> {
1269
+ when: string;
1270
+ value: V;
1271
+ }
1106
1272
  /**
1107
1273
  * The compiled, serializable flag definition — the EXACT shape emitted to JSON
1108
1274
  * and consumed by the Go apply step.
@@ -1117,6 +1283,8 @@ interface FlagDef {
1117
1283
  type: FlagType;
1118
1284
  default: FlagValue;
1119
1285
  variants: string[] | null;
1286
+ /** Ordered targeting branches, or `null` when the flag is unconditional. */
1287
+ conditions: CompiledFlagCondition<FlagValue>[] | null;
1120
1288
  description: string | null;
1121
1289
  }
1122
1290
  /** A flags config definition: the discriminant + a map of flag key →
@@ -1715,4 +1883,4 @@ declare const documents: {
1715
1883
  onDocumentDeleted(handler: HookHandler<DocumentDeletedEvent>): ResolvedHook<DocumentDeletedEvent>;
1716
1884
  };
1717
1885
 
1718
- export { type AcsOptions, type ApnsOptions, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, DBClient, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, EGRESS_CONFIG_KIND, EGRESS_TIMEOUT_DEFAULT_MS, EGRESS_TIMEOUT_MAX_MS, EGRESS_TIMEOUT_MIN_MS, type EgressConfig, type EgressInput, EntitlementKey, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagJsonObject, type FlagJsonValue, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, Job, type JobMeta, type JobOptions, LimitKey, type LimitState, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, On, OptionalUser, type OwnedTablesOf, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type ParamKind, type ParamMeta, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderName, type ProviderOptions, Purchases, type PurchasesManifest, type PurchasesService, Put, Query, QueryParams, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type RequestStore, RequireEntitlement, type ResolvedHook, type ResolvedJob, type ResolvedWebhook, Resource, type ResourceEnv, type RouteMeta, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type Seed, type SeedFor, type SeedJson, type SeedRowFor, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SignatureSpec, type SmtpOptions, Spend, type SpendMeta, type SpendOptions, Storage, type StorageConfig, type StorageInput, type StoreEnv, TEST_USERS_CONFIG_KIND, type TableGraph, TableTypes, Tables, type TestUserDef, type TestUserOptions, type TestUsersConfig, type TestUsersInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineEgress, defineError, defineFlags, defineNotifications, defineStorage, defineTestUsers, documents, entitlementFor, flag, getErrorRegistry, getJobConfig, getRoutes, getWebhookConfig, makeEnvDts, makePurchasesDts, parseFileSizeLimit, recordThrows, reservedSecretKey, spendFor, storage, testUser, validateUploadAgainstStorage };
1886
+ export { type AcsOptions, type ApnsOptions, Body, type BucketDef, type BucketOptions, Cache, CacheClient, Client, Controller, type ControllerOptions, DBClient, DEFAULT_TEMPLATE_LOCALE, Database, type DefinedError, type DefinedErrorWithData, Delete, type DocumentCreatedEvent, type DocumentDeletedEvent, type DocumentUpdatedEvent, Documents, EGRESS_CONFIG_KIND, EGRESS_TIMEOUT_DEFAULT_MS, EGRESS_TIMEOUT_MAX_MS, EGRESS_TIMEOUT_MIN_MS, type EgressConfig, type EgressInput, type EmailTemplateContent, type EmailTemplateDef, type EmailTemplateOptions, EntitlementKey, EnvTypedDatabase, FLAGS_CONFIG_KIND, type FcmOptions, type FileDeletedEvent, type FileUploadedEvent, type FlagDef, type FlagJsonObject, type FlagJsonValue, type FlagOptions, type FlagType, type FlagValue, Flags, type FlagsConfig, type FlagsInput, Get, Headers, type HookHandler, type HookMeta, HttpError, type HttpMethodUpper, Job, type JobMeta, type JobOptions, LimitKey, type LimitState, Log, Logger, NOTIFICATIONS_CONFIG_KIND, Notifications, type NotificationsConfig, type NotificationsInput, On, OptionalUser, type OwnedTablesOf, PROVIDER_CATALOG, PalbaseDocsClient, PalbaseFlagsClient, PalbaseNotificationsClient, PalbaseRealtimeClient, PalbaseStorageClient, Param, type ParamKind, type ParamMeta, type PasswordResetEvent, Patch, Post, type ProviderCatalogEntry, type ProviderDef, type ProviderName, type ProviderOptions, Purchases, type PurchasesManifest, type PurchasesService, Put, Query, QueryParams, RESERVED_SECRET_PREFIX, RateLimitConfig, Realtime, type RegisteredError, Req, RequestId, type RequestStore, RequireEntitlement, type ResolvedHook, type ResolvedJob, type ResolvedWebhook, Resource, type ResourceEnv, type RouteMeta, type RouteOptions, type RuntimeServices, STORAGE_CONFIG_KIND, SchemaDef, type Seed, type SeedFor, type SeedJson, type SeedRowFor, type SendgridOptions, type SesOptions, type SignInEvent, type SignOutEvent, type SignatureSpec, type SmsTemplateContent, type SmsTemplateDef, type SmsTemplateOptions, type SmtpOptions, Spend, type SpendMeta, type SpendOptions, Storage, type StorageConfig, type StorageInput, type StoreEnv, TEST_USERS_CONFIG_KIND, type TableGraph, TableTypes, Tables, type TemplatesConfig, type TemplatesInput, type TestUserDef, type TestUserOptions, type TestUsersConfig, type TestUsersInput, type ThrowDescriptor, TraceId, type TwilioOptions, Upload, type UploadConfig, UploadedObject, User, type UserCreatedEvent, Webhook, type WebhookEventHandler, type WebhookMeta, type WebhookOptions, type WebhookProvider, type WebhookRequest, __getRuntime, __registerResource, __requestALS, __runResourceBoot, __runWithRuntime, __setRuntime, __shutdownResources, auth, bucket, buildProvider, defineEgress, defineError, defineFlags, defineNotifications, defineStorage, defineTestUsers, documents, entitlementFor, extractVariables, flag, getErrorRegistry, getJobConfig, getRoutes, getWebhookConfig, makeEnvDts, makePurchasesDts, parseFileSizeLimit, recordThrows, reservedSecretKey, spendFor, storage, testUser, validateUploadAgainstStorage };