import type { Maybe } from '@dereekb/util'; import { type AstNode } from './util'; import { type ParserServicesLike } from './storagefile-import-resolver'; /** * Default type name the rule looks for on top-level declarators. Variables whose type * annotation resolves to this identifier are treated as upload policies and validated * against `storage.rules`. */ export declare const DEFAULT_STORAGE_FILE_UPLOAD_POLICY_TYPE_NAME: string; /** * Default file name searched relative to the lint root when `storageRulesPath` is omitted. */ export declare const DEFAULT_STORAGE_RULES_FILENAME: string; /** * Options for the require-storagefile-policy-matches-rules rule. */ export interface FirebaseRequireStorageFilePolicyMatchesRulesRuleOptions { /** * Path to the `storage.rules` file. Resolved against the ESLint `cwd` when relative. * Defaults to `/storage.rules`. */ readonly storageRulesPath?: string; /** * Inline `storage.rules` source used in tests; bypasses filesystem reads when set. */ readonly virtualStorageRules?: string; /** * Type-annotation identifier the rule treats as the upload-policy marker. Defaults to * {@link DEFAULT_STORAGE_FILE_UPLOAD_POLICY_TYPE_NAME}. */ readonly policyTypeName?: string; /** * Policies whose `buildUploadPath` is legitimately dynamic (e.g. injects a runtime timestamp) * and cannot be statically folded. Each entry matches a policy's `purpose` key or its * declarator name; matching policies are skipped instead of reporting `unresolvablePolicyPath`. */ readonly allowUnresolvablePolicies?: readonly string[]; } /** * ESLint rule definition for require-storagefile-policy-matches-rules. */ export interface FirebaseRequireStorageFilePolicyMatchesRulesRuleDefinition { readonly meta: { readonly type: 'problem'; readonly fixable: undefined; readonly docs: { readonly description: string; readonly recommended: boolean; }; readonly messages: Readonly>; readonly schema: readonly object[]; }; create(context: RuleContext): Record void>; } interface RuleContext { readonly options: FirebaseRequireStorageFilePolicyMatchesRulesRuleOptions[]; readonly cwd?: string; readonly sourceCode?: { readonly parserServices?: Maybe; }; readonly parserServices?: Maybe; readonly report: (descriptor: { node: AstNode; messageId: string; data?: Record; }) => void; } /** * ESLint rule that cross-checks every `StorageFilePurposeUploadPolicy`-typed declaration in * a `*-firebase` component against the workspace's `storage.rules`. The policy's * `buildUploadPath` builder is statically folded to a concrete path template (an ordered list * of literal / wildcard segments) and paired with the `storage.rules` `allow write` match * block at the same path. On the paired block the `request.resource.size` cap and * `request.resource.contentType` predicate must be at least as permissive as the policy's * `maxFileSizeBytes` and `allowedMimeTypes`. * * Pairing is derived from the resolved path — not a marker comment — so the linker proves the * policy's actual upload path lands in the rules block rather than trusting an unchecked * assertion. When the builder cannot be folded (unknown const, unmodeled call, runtime value) * the rule reports `unresolvablePolicyPath` and never guesses; genuinely dynamic builders opt * out via `allowUnresolvablePolicies`. * * Reports on the TS side so drift surfaces in the normal lint pipeline; mismatches almost * always originate from editing one side and forgetting the other. * * @example * ```ts * // OK — storage.rules has `match /uploads/u/{uid}/avatar.img` with matching constraints * export const USER_AVATAR_UPLOAD_POLICY: StorageFilePurposeUploadPolicy = { * purpose: USER_AVATAR_PURPOSE, * allowedMimeTypes: ['image/jpeg', 'image/png'], * maxFileSizeBytes: 16 * 1024 * 1024, * buildUploadPath: ({ uid }) => userAvatarUploadsFilePath(uid), * requiresFilenameInput: false * }; * ``` */ export declare const FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE: FirebaseRequireStorageFilePolicyMatchesRulesRuleDefinition; export {};