import { JsonObject, PlanFeatureGrant, PlanThreshold, Subscriber, SubscriberKind, ThresholdWindow, UsageWindow } from './types.js'; export declare function deterministicUuid(parts: string[]): Promise; export declare function parseJsonArray(value: string, fallback?: T[]): T[]; export declare function parseJsonObject(value: string, fallback: T): T; export declare function stringifyJson(value: unknown): string; export declare function normalizeFeatureGrants(grants: Array): PlanFeatureGrant[]; /** * Coerce inputs from the legacy tenant-only API into a {@link Subscriber}. * * Existing callers that pass only `tenantId` (with optional `subscriberKind` / * `subscriberExternalId` fields, e.g. on `RecordUsageOptions`) get normalized * into the discriminated union exactly once at the boundary. This is the only * place that contains "if kind is omitted, default to tenant" logic — every * other site works with a typed `Subscriber`. * * Throws when: * - `subscriberKind === 'external'` is requested without a non-empty * `subscriberExternalId` (the XOR invariant is the whole point), or * - the input carries a non-empty `subscriberExternalId` but the kind resolves * to `'tenant'` (silent re-scoping would write buyer-scoped usage as tenant * usage, which then disappears from external summaries). */ export declare function normalizeSubscriber(input: { tenantId: string; subscriberKind?: SubscriberKind | null; subscriberExternalId?: string | null; }): Subscriber; /** * Project a {@link Subscriber} back onto column values for persistence or query * filters. Counterpart to {@link normalizeSubscriber}. */ export declare function subscriberToColumns(subscriber: Subscriber): { tenantId: string; subscriberKind: SubscriberKind; subscriberExternalId: string; }; /** * Enforce the subscriber XOR invariant on a row's columns. Used by both the * model constructors (catches construction-time mistakes) and the * `validateBeforeSave` override (catches mutations applied via the * generated PUT/PATCH update path that bypass the constructor). * * Defensive about types because both call sites can receive JSON or untyped * fixture data via the generated REST/CLI surface — `null` arriving in place * of `''` would otherwise slip past an `=== ''` check, land in the * `(tenant_id, subscriber_kind, subscriber_external_id)` conflict key, and * (on Postgres) not collide with other NULLs while `findCurrentForSubscriber` * keeps querying by a string external id. * * @param modelName - Prepended to error messages so callers can tell whether * the failure originated in `TenantSubscription` or `TenantUsageMetric`. */ export declare function assertSubscriberInvariant(modelName: string, fields: { subscriberKind: unknown; subscriberExternalId: unknown; }): void; export declare function getWindowForThreshold(thresholdWindow: ThresholdWindow, now?: Date): UsageWindow; export declare function getWindowKey(window: UsageWindow): string; export declare function isValidThreshold(threshold: PlanThreshold): boolean; //# sourceMappingURL=utils.d.ts.map