@dereekb/firebase 13.11.17 → 13.12.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.
Files changed (36) hide show
  1. package/eslint/index.cjs.js +7229 -1551
  2. package/eslint/index.esm.js +7203 -1552
  3. package/eslint/package.json +4 -2
  4. package/eslint/rollup.alias-internal.config.d.ts +1 -0
  5. package/eslint/src/lib/firebase-rules-text.d.ts +121 -0
  6. package/eslint/src/lib/firestore-rules-parser.d.ts +61 -0
  7. package/eslint/src/lib/index.d.ts +10 -0
  8. package/eslint/src/lib/plugin.d.ts +16 -0
  9. package/eslint/src/lib/predicate-evaluator.d.ts +47 -0
  10. package/eslint/src/lib/require-api-details-for-crud-function.rule.d.ts +83 -0
  11. package/eslint/src/lib/require-complete-crud-function-config-map.rule.d.ts +61 -0
  12. package/eslint/src/lib/require-dbx-model-companion-tags.rule.d.ts +47 -0
  13. package/eslint/src/lib/require-dbx-model-service-factory-tag.rule.d.ts +56 -0
  14. package/eslint/src/lib/require-firestore-constraint-type-parameter.rule.d.ts +45 -0
  15. package/eslint/src/lib/require-firestore-rule-for-service-model.rule.d.ts +115 -0
  16. package/eslint/src/lib/require-service-factory-for-dbx-model.rule.d.ts +80 -0
  17. package/eslint/src/lib/require-storagefile-policy-matches-rules.rule.d.ts +79 -0
  18. package/eslint/src/lib/storage-rules-parser.d.ts +38 -0
  19. package/index.cjs.js +53 -5
  20. package/index.esm.js +46 -6
  21. package/package.json +5 -5
  22. package/src/lib/common/auth/auth.d.ts +8 -0
  23. package/src/lib/common/auth/oidc/oidc.d.ts +7 -5
  24. package/src/lib/common/model/function.d.ts +12 -1
  25. package/src/lib/model/notification/notification.d.ts +6 -0
  26. package/src/lib/model/oidcmodel/oidcmodel.d.ts +1 -0
  27. package/src/lib/model/storagefile/storagefile.api.d.ts +113 -2
  28. package/src/lib/model/storagefile/storagefile.d.ts +2 -0
  29. package/src/lib/model/storagefile/storagefile.upload.d.ts +33 -1
  30. package/src/lib/model/system/system.d.ts +1 -0
  31. package/test/index.cjs.js +2 -4
  32. package/test/index.esm.js +2 -4
  33. package/test/package.json +6 -6
  34. package/eslint/src/lib/comments.d.ts +0 -112
  35. package/eslint/src/lib/dbx-tag-families.d.ts +0 -280
  36. package/eslint/src/lib/jsdoc-parser.d.ts +0 -116
@@ -1,11 +1,13 @@
1
1
  {
2
2
  "name": "@dereekb/firebase/eslint",
3
- "version": "13.11.17",
3
+ "version": "13.12.0",
4
4
  "peerDependencies": {
5
+ "@marcbachmann/cel-js": "^7.6.1",
5
6
  "@typescript-eslint/utils": "8.59.3"
6
7
  },
7
8
  "devDependencies": {
8
- "@dereekb/util": "13.11.17",
9
+ "@dereekb/util": "13.12.0",
10
+ "@marcbachmann/cel-js": "^7.6.1",
9
11
  "@typescript-eslint/parser": "8.59.3",
10
12
  "eslint": "10.4.0"
11
13
  },
@@ -0,0 +1 @@
1
+ export default function applyInternalAliases(config: any, _options: any): Promise<any>;
@@ -0,0 +1,121 @@
1
+ import type { Maybe } from '@dereekb/util';
2
+ /**
3
+ * One brace-delimited block extracted by {@link extractTopLevelBlocks}: a `match`, a
4
+ * `function`, a `service`, or any other `<header> { ... }` shape in a Firebase rules
5
+ * source. Offsets are relative to the body that was scanned.
6
+ */
7
+ export interface RawBlock {
8
+ readonly header: string;
9
+ readonly body: string;
10
+ readonly headerStart: number;
11
+ readonly bodyStart: number;
12
+ }
13
+ /**
14
+ * Strips `//`-style line comments from a Firebase rules source string so the brace
15
+ * walker doesn't trip on braces / semicolons embedded in comments.
16
+ *
17
+ * @param source - Raw rules source.
18
+ * @returns The source with line comments replaced by equal-length whitespace (so offsets are preserved).
19
+ */
20
+ export declare function stripLineComments(source: string): string;
21
+ /**
22
+ * Masks `{name}` and `{name=**}` path-variable braces with private-use characters so the
23
+ * brace walker never confuses them with block braces. Same-length substitution preserves
24
+ * offsets. Catch-all deny patterns retain a recognizable shape because the inner text
25
+ * (e.g. `allPaths=**`) is untouched.
26
+ *
27
+ * @param source - The (comment-stripped) source.
28
+ * @returns The source with path-variable braces masked.
29
+ */
30
+ export declare function maskPathVariables(source: string): string;
31
+ /**
32
+ * Reverses {@link maskPathVariables} so header / path text reported to callers shows the
33
+ * original `{name}` form.
34
+ *
35
+ * @param text - Text containing masked path variables.
36
+ * @returns The text with `{name}` braces restored.
37
+ */
38
+ export declare function unmaskPathVariables(text: string): string;
39
+ /**
40
+ * Resolves the 1-based line and 1-based column of a character offset in the source string.
41
+ *
42
+ * @param source - The original source.
43
+ * @param index - Zero-based character offset.
44
+ * @returns The line/column pair.
45
+ */
46
+ export declare function indexToLineColumn(source: string, index: number): {
47
+ line: number;
48
+ column: number;
49
+ };
50
+ /**
51
+ * Finds the matching closing brace for the opening brace at `openIndex` in `source`,
52
+ * respecting nesting. Returns the index of the closing brace, or -1 when unbalanced.
53
+ * `source` must be the masked version so path-variable braces don't pollute the count.
54
+ *
55
+ * @param source - The masked source string.
56
+ * @param openIndex - Index of an opening brace.
57
+ * @returns Index of the matching closing brace, or -1.
58
+ */
59
+ export declare function findMatchingBrace(source: string, openIndex: number): number;
60
+ /**
61
+ * Walks backward from `openIndex` to find where this block's header starts: just past the
62
+ * previous `;` or `}` (now always a true block-sibling close, since path-variable braces
63
+ * are masked), then forward through whitespace to the first significant char.
64
+ *
65
+ * @param body - The masked source slice being scanned.
66
+ * @param cursor - The search start position (right after the previous sibling's `}`).
67
+ * @param openIndex - Index of this block's opening brace.
68
+ * @returns Start index of the header.
69
+ */
70
+ export declare function findHeaderStart(body: string, cursor: number, openIndex: number): number;
71
+ /**
72
+ * Extracts top-level brace-delimited blocks inside `body` (path-variable-masked). Each
73
+ * block carries its header text (with masking still applied — callers unmask when
74
+ * reporting) and the inner body. Function definitions, match blocks, and `service` /
75
+ * bucket-root wrappers are all returned as raw blocks.
76
+ *
77
+ * @param body - The masked source slice to scan.
78
+ * @returns The list of top-level child blocks.
79
+ */
80
+ export declare function extractTopLevelBlocks(body: string): RawBlock[];
81
+ /**
82
+ * Pulls the match-path segment out of a `match /<segment> { ... }` header. The segment is
83
+ * unmasked before being returned so callers see original `{name}` braces.
84
+ *
85
+ * @param header - The (still-masked) header text.
86
+ * @returns The path segment with the leading `/`, or null when the header is not a match.
87
+ */
88
+ export declare function matchHeaderPath(header: string): Maybe<string>;
89
+ /**
90
+ * Pulls the function name out of a `function <name>() { ... }` header.
91
+ *
92
+ * @param header - The header text.
93
+ * @returns The function name, or null when the header is not a function definition.
94
+ */
95
+ export declare function functionHeaderName(header: string): Maybe<string>;
96
+ /**
97
+ * Pulls the `return <expression>` body out of a function definition's inner block. The
98
+ * body may span multiple lines (CEL expressions wrap freely across newlines); we capture
99
+ * everything from after `return ` to the closing `}`-relative end of `body`, then strip
100
+ * an optional trailing `;` and surrounding whitespace.
101
+ *
102
+ * @param body - The inner body of a function block (already line-comment-stripped).
103
+ * @returns The expression text after `return`, or null when no `return` is present.
104
+ */
105
+ export declare function functionReturnExpression(body: string): Maybe<string>;
106
+ /**
107
+ * Joins a child match segment onto a parent path so nested matches resolve to absolute paths.
108
+ *
109
+ * @param parentPath - The accumulated parent path (e.g. `/uploads/u/{uid}`).
110
+ * @param childSegment - The child match's segment (e.g. `/avatar.img`).
111
+ * @returns The combined path.
112
+ */
113
+ export declare function joinMatchPath(parentPath: string, childSegment: string): string;
114
+ /**
115
+ * Returns true when the unmasked segment is the catch-all `{var=**}` wildcard that means
116
+ * "any path" (used for deny rules like `match /{allPaths=**} { allow read, write: if false; }`).
117
+ *
118
+ * @param segment - The unmasked match segment to test.
119
+ * @returns True for catch-all wildcards.
120
+ */
121
+ export declare function isCatchAllSegment(segment: string): boolean;
@@ -0,0 +1,61 @@
1
+ import type { Maybe } from '@dereekb/util';
2
+ /**
3
+ * One `match /<segment>` block in `firestore.rules`. Nested matches appear as `children`.
4
+ * `collectionName` is the first bare-identifier segment of the match path (e.g. `pr`,
5
+ * `gbe`, `sys`); it is `null` only when the match path is purely a `{path=**}` wildcard
6
+ * with no following collection segment.
7
+ */
8
+ export interface ParsedFirestoreMatchBlock {
9
+ /**
10
+ * Raw unmasked path segment from `match /<segment>` (e.g. `/pr/{profile}`,
11
+ * `/{path=**}/gbe/{guestbookEntry}`, `/sys/hellosubscheckhqcompany`).
12
+ */
13
+ readonly pathSegment: string;
14
+ /**
15
+ * First bare-identifier collection token in the path, or `null` when none. Used to pair
16
+ * a model identity's `collectionName` (e.g. `gb`, `gbe`) against a rules block.
17
+ */
18
+ readonly collectionName: Maybe<string>;
19
+ /**
20
+ * True when the match path starts with `/{path=**}/` — a collection-group rule that
21
+ * matches the collection at any depth.
22
+ */
23
+ readonly isCollectionGroup: boolean;
24
+ /**
25
+ * Children nested inside this block's body, in source order.
26
+ */
27
+ readonly children: readonly ParsedFirestoreMatchBlock[];
28
+ /**
29
+ * Raw allow directive names declared on this block (e.g. `get`, `list`, `read`, `write`,
30
+ * `create`, `update`, `delete`). Empty when the block declares no `allow` statements at
31
+ * its own scope (children may still declare their own).
32
+ */
33
+ readonly allowDirectives: readonly string[];
34
+ readonly sourceLine: number;
35
+ readonly sourceColumn: number;
36
+ }
37
+ /**
38
+ * Parses a `firestore.rules` source string and returns the tree of `match` blocks rooted
39
+ * at the implicit `match /databases/{database}/documents` envelope. Each block's
40
+ * `collectionName` is the first bare-identifier segment of its match path; nested
41
+ * subcollection matches appear as `children`.
42
+ *
43
+ * @param source - The raw rules source text.
44
+ * @returns The list of top-level match blocks in source order.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * const blocks = parseFirestoreRules(`
49
+ * service cloud.firestore {
50
+ * match /databases/{database}/documents {
51
+ * match /gb/{guestbook} {
52
+ * match /gbe/{guestbookEntry} { allow get: if false; }
53
+ * }
54
+ * }
55
+ * }
56
+ * `);
57
+ * // blocks[0].collectionName === 'gb'
58
+ * // blocks[0].children[0].collectionName === 'gbe'
59
+ * ```
60
+ */
61
+ export declare function parseFirestoreRules(source: string): ParsedFirestoreMatchBlock[];
@@ -2,5 +2,15 @@ export { FIREBASE_REQUIRE_TAGGED_FIRESTORE_CONSTRAINTS_RULE, type FirebaseRequir
2
2
  export { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE, type FirebaseRequireDbxModelFirebaseIndexQuerySuffixRuleOptions, type FirebaseRequireDbxModelFirebaseIndexQuerySuffixRuleDefinition } from './require-dbx-model-firebase-index-query-suffix.rule';
3
3
  export { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE, type FirebaseRequireDbxModelFirebaseIndexCompanionTagsRuleOptions, type FirebaseRequireDbxModelFirebaseIndexCompanionTagsRuleDefinition } from './require-dbx-model-firebase-index-companion-tags.rule';
4
4
  export { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_VALID_DISPATCHER_RULE, type FirebaseRequireDbxModelFirebaseIndexValidDispatcherRuleOptions, type FirebaseRequireDbxModelFirebaseIndexValidDispatcherRuleDefinition } from './require-dbx-model-firebase-index-valid-dispatcher.rule';
5
+ export { FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE, type FirebaseRequireFirestoreConstraintTypeParameterRuleOptions, type FirebaseRequireFirestoreConstraintTypeParameterRuleDefinition } from './require-firestore-constraint-type-parameter.rule';
6
+ export { FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE, DEFAULT_CRUD_VERB_NAMES, MODEL_FIREBASE_CRUD_FUNCTION_CONFIG_MAP_TYPE_NAME, type FirebaseRequireCompleteCrudFunctionConfigMapRuleOptions, type FirebaseRequireCompleteCrudFunctionConfigMapRuleDefinition } from './require-complete-crud-function-config-map.rule';
7
+ export { FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE, DEFAULT_CRUD_FUNCTION_TYPE_VERBS, DEFAULT_API_DETAILS_FACTORY_NAME, type FirebaseRequireApiDetailsForCrudFunctionRuleOptions, type FirebaseRequireApiDetailsForCrudFunctionRuleDefinition } from './require-api-details-for-crud-function.rule';
8
+ export { FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE, DEFAULT_STORAGE_FILE_UPLOAD_POLICY_TYPE_NAME, DEFAULT_STORAGE_RULES_FILENAME, type FirebaseRequireStorageFilePolicyMatchesRulesRuleOptions, type FirebaseRequireStorageFilePolicyMatchesRulesRuleDefinition } from './require-storagefile-policy-matches-rules.rule';
9
+ export { FIREBASE_REQUIRE_FIRESTORE_RULE_FOR_SERVICE_MODEL_RULE, DEFAULT_FIRESTORE_RULES_FILENAME, DEFAULT_REGISTRY_FACTORY_CALL_NAME, DEFAULT_IDENTITY_FACTORY_NAME, DEFAULT_MODEL_SEARCH_ROOTS, type FirebaseRequireFirestoreRuleForServiceModelRuleOptions, type FirebaseRequireFirestoreRuleForServiceModelRuleDefinition, type VirtualModelIdentity } from './require-firestore-rule-for-service-model.rule';
10
+ export { FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE, FIREBASE_MODEL_SERVICE_FACTORY_NAME, FIREBASE_MODEL_SERVICE_FACTORY_MODULE, DBX_MODEL_SERVICE_FACTORY_TAG, type FirebaseRequireDbxModelServiceFactoryTagRuleOptions, type FirebaseRequireDbxModelServiceFactoryTagRuleDefinition } from './require-dbx-model-service-factory-tag.rule';
11
+ export { FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE, DEFAULT_FACTORY_SEARCH_ROOTS, DEFAULT_MODEL_MARKER_TAG, DEFAULT_FACTORY_TAG, type FirebaseRequireServiceFactoryForDbxModelRuleOptions, type FirebaseRequireServiceFactoryForDbxModelRuleDefinition } from './require-service-factory-for-dbx-model.rule';
12
+ export { FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE, type FirebaseRequireDbxModelCompanionTagsRuleOptions, type FirebaseRequireDbxModelCompanionTagsRuleDefinition } from './require-dbx-model-companion-tags.rule';
13
+ export { parseStorageRules, MIRRORS_POLICY_KEY_MARKER_REGEX, type ParsedRuleBranch, type ParsedStorageRulesBlock } from './storage-rules-parser';
14
+ export { parseFirestoreRules, type ParsedFirestoreMatchBlock } from './firestore-rules-parser';
5
15
  export { FIREBASE_ESLINT_PLUGIN, firebaseESLintPlugin, type FirebaseEslintPlugin } from './plugin';
6
16
  export { DBX_MODEL_FIREBASE_INDEX_MARKER, DEFAULT_CONSTRAINT_FACTORY_NAMES, DEFAULT_INDEX_AFFECTING_CONSTRAINT_NAMES, DEFAULT_PAGINATION_CONSTRAINT_NAMES, FIREBASE_MODULE, QUERY_SUFFIX } from './util';
@@ -2,6 +2,14 @@ import { FIREBASE_REQUIRE_TAGGED_FIRESTORE_CONSTRAINTS_RULE } from './require-ta
2
2
  import { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE } from './require-dbx-model-firebase-index-query-suffix.rule';
3
3
  import { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE } from './require-dbx-model-firebase-index-companion-tags.rule';
4
4
  import { FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_VALID_DISPATCHER_RULE } from './require-dbx-model-firebase-index-valid-dispatcher.rule';
5
+ import { FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE } from './require-firestore-constraint-type-parameter.rule';
6
+ import { FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE } from './require-complete-crud-function-config-map.rule';
7
+ import { FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE } from './require-api-details-for-crud-function.rule';
8
+ import { FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE } from './require-storagefile-policy-matches-rules.rule';
9
+ import { FIREBASE_REQUIRE_FIRESTORE_RULE_FOR_SERVICE_MODEL_RULE } from './require-firestore-rule-for-service-model.rule';
10
+ import { FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE } from './require-dbx-model-service-factory-tag.rule';
11
+ import { FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE } from './require-service-factory-for-dbx-model.rule';
12
+ import { FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE } from './require-dbx-model-companion-tags.rule';
5
13
  /**
6
14
  * ESLint plugin interface for `@dereekb/firebase` rules.
7
15
  */
@@ -11,6 +19,14 @@ export interface FirebaseEslintPlugin {
11
19
  readonly 'require-dbx-model-firebase-index-query-suffix': typeof FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_QUERY_SUFFIX_RULE;
12
20
  readonly 'require-dbx-model-firebase-index-companion-tags': typeof FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_COMPANION_TAGS_RULE;
13
21
  readonly 'require-dbx-model-firebase-index-valid-dispatcher': typeof FIREBASE_REQUIRE_DBX_MODEL_FIREBASE_INDEX_VALID_DISPATCHER_RULE;
22
+ readonly 'require-firestore-constraint-type-parameter': typeof FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE;
23
+ readonly 'require-complete-crud-function-config-map': typeof FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE;
24
+ readonly 'require-api-details-for-crud-function': typeof FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE;
25
+ readonly 'require-storagefile-policy-matches-rules': typeof FIREBASE_REQUIRE_STORAGEFILE_POLICY_MATCHES_RULES_RULE;
26
+ readonly 'require-firestore-rule-for-service-model': typeof FIREBASE_REQUIRE_FIRESTORE_RULE_FOR_SERVICE_MODEL_RULE;
27
+ readonly 'require-dbx-model-service-factory-tag': typeof FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE;
28
+ readonly 'require-service-factory-for-dbx-model': typeof FIREBASE_REQUIRE_SERVICE_FACTORY_FOR_DBX_MODEL_RULE;
29
+ readonly 'require-dbx-model-companion-tags': typeof FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE;
14
30
  };
15
31
  }
16
32
  /**
@@ -0,0 +1,47 @@
1
+ /**
2
+ * One disjunct of an `allow write: if ...` predicate after helper-function expansion
3
+ * and DNF conversion. Always carries a numeric byte cap plus at least one MIME constraint.
4
+ */
5
+ export interface PredicateBranch {
6
+ readonly maxFileSizeBytes: number;
7
+ readonly allowedMimeLiterals: readonly string[];
8
+ readonly allowedMimeRegexes: readonly string[];
9
+ }
10
+ /**
11
+ * Result of evaluating a CEL `allow write` predicate. When the predicate cannot be reduced
12
+ * to at least one resource-constraining branch, {@link PredicateEvaluation.branches} is
13
+ * empty and `unsupported` carries a human-readable reason.
14
+ */
15
+ export interface PredicateEvaluation {
16
+ readonly branches: readonly PredicateBranch[];
17
+ readonly unsupported?: string;
18
+ }
19
+ /**
20
+ * Map of helper-function names → return-expression text. Entries are sourced from the
21
+ * surrounding `storage.rules` scope (function definitions reachable from the `match` block).
22
+ */
23
+ export interface HelperFunctionTable {
24
+ readonly definitions: ReadonlyMap<string, string>;
25
+ }
26
+ /**
27
+ * Evaluates a CEL `allow write` predicate into the list of `(size, MIME)` branches the
28
+ * `require-storagefile-policy-matches-rules` lint rule cross-checks against the TypeScript
29
+ * upload-policy registry.
30
+ *
31
+ * Pipeline: parse with `@marcbachmann/cel-js`, inline zero-arg helper calls at the AST
32
+ * level, expand to disjunctive normal form, then for each DNF clause harvest:
33
+ *
34
+ * - `request.resource.size < N` size caps,
35
+ * - `request.resource.contentType == '...'` literal MIMEs,
36
+ * - `request.resource.contentType.matches('...')` MIME regexes,
37
+ * - `request.resource.contentType in [...]` MIME-list literals.
38
+ *
39
+ * A clause becomes a {@link PredicateBranch} only when it has ≥1 size cap AND ≥1 MIME
40
+ * constraint. Auth-only clauses (e.g. `request.auth.token.a == 1`) are silently dropped —
41
+ * they don't restrict uploads from the storage perspective.
42
+ *
43
+ * @param predicate - The raw predicate text (everything between `if` and `;` in the rules file).
44
+ * @param helpers - Helper-function bodies in scope at the `match` block.
45
+ * @returns Reduced branches, plus an `unsupported` reason when reduction yields zero branches or the predicate fails to parse.
46
+ */
47
+ export declare function evaluatePredicate(predicate: string, helpers: HelperFunctionTable): PredicateEvaluation;
@@ -0,0 +1,83 @@
1
+ import { type AstNode } from './util';
2
+ /**
3
+ * Default CRUD verb names that combine with the `ModelFunction` suffix to form a type-name
4
+ * pattern this rule treats as a CRUD function declaration (e.g. `OnCallCreateModelFunction`,
5
+ * `DemoUpdateModelFunction`).
6
+ *
7
+ * Mirrors the verbs supported by `ModelFirebaseCrudFunctionConfigMap` — see
8
+ * `packages/firebase/src/lib/client/function/model.function.factory.ts`.
9
+ */
10
+ export declare const DEFAULT_CRUD_FUNCTION_TYPE_VERBS: readonly string[];
11
+ /**
12
+ * Default factory function name that wraps CRUD function declarations and attaches the
13
+ * `_apiDetails` metadata (`inputType`, `outputType`, `mcp.visibility`, `analytics`) consumed
14
+ * by the MCP manifest builder. Defined in `packages/firebase-server/src/lib/nest/model/api.details.ts`.
15
+ */
16
+ export declare const DEFAULT_API_DETAILS_FACTORY_NAME: string;
17
+ /**
18
+ * Options for the require-api-details-for-crud-function rule.
19
+ */
20
+ export interface FirebaseRequireApiDetailsForCrudFunctionRuleOptions {
21
+ /**
22
+ * Verb fragments that pair with the `ModelFunction` suffix to identify a CRUD function
23
+ * type annotation. Defaults to {@link DEFAULT_CRUD_FUNCTION_TYPE_VERBS}.
24
+ */
25
+ readonly typeVerbs?: readonly string[];
26
+ /**
27
+ * Factory function name expected on the initializer. Defaults to {@link DEFAULT_API_DETAILS_FACTORY_NAME}.
28
+ */
29
+ readonly factoryName?: string;
30
+ /**
31
+ * Declarator names to exempt from the rule. Mainly an escape hatch for tests.
32
+ */
33
+ readonly ignoreNames?: readonly string[];
34
+ }
35
+ /**
36
+ * ESLint rule definition for require-api-details-for-crud-function.
37
+ */
38
+ export interface FirebaseRequireApiDetailsForCrudFunctionRuleDefinition {
39
+ readonly meta: {
40
+ readonly type: 'problem';
41
+ readonly fixable: undefined;
42
+ readonly docs: {
43
+ readonly description: string;
44
+ readonly recommended: boolean;
45
+ };
46
+ readonly messages: Readonly<Record<string, string>>;
47
+ readonly schema: readonly object[];
48
+ };
49
+ create(context: {
50
+ options: FirebaseRequireApiDetailsForCrudFunctionRuleOptions[];
51
+ report: (descriptor: {
52
+ node: AstNode;
53
+ messageId: string;
54
+ data?: Record<string, string>;
55
+ }) => void;
56
+ }): Record<string, (node: AstNode) => void>;
57
+ }
58
+ /**
59
+ * ESLint rule that requires every CRUD function declaration — a variable typed as
60
+ * `On(?:Call)?<Verb>ModelFunction` (or any app-side alias ending with the same `<Verb>ModelFunction`
61
+ * suffix) — to be initialized with a call to `withApiDetails(...)`.
62
+ *
63
+ * Handlers that skip the wrapper compile fine but do not attach the `_apiDetails` metadata
64
+ * (`inputType`, `mcp.visibility`, `analytics`) that downstream tooling — especially the MCP
65
+ * manifest builder in `packages/firebase-server-mcp` — reads. The handler then silently fails
66
+ * to appear in the generated MCP server even though the runtime wires it up.
67
+ *
68
+ * The rule is purely syntactic: it inspects the declarator's TS type annotation and the
69
+ * initializer's `CallExpression` callee name. Type assertions (`as`, `<T>`) on the initializer
70
+ * are unwrapped before the check.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * // OK — wrapped, surfaces to MCP
75
+ * export const fooCreate: FooCreateModelFunction<X> = withApiDetails({
76
+ * inputType, fn: async (req) => ({})
77
+ * });
78
+ *
79
+ * // WARN — missingApiDetails, never reaches MCP
80
+ * export const fooDelete: FooDeleteModelFunction<X> = async (req) => {};
81
+ * ```
82
+ */
83
+ export declare const FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE: FirebaseRequireApiDetailsForCrudFunctionRuleDefinition;
@@ -0,0 +1,61 @@
1
+ import { type AstNode } from './util';
2
+ /**
3
+ * Type-reference name that triggers this rule. Variables whose declared type is
4
+ * `ModelFirebaseCrudFunctionConfigMap<ConfigType, Identity>` will have their
5
+ * initializer validated against the structure of `ConfigType`.
6
+ */
7
+ export declare const MODEL_FIREBASE_CRUD_FUNCTION_CONFIG_MAP_TYPE_NAME = "ModelFirebaseCrudFunctionConfigMap";
8
+ /**
9
+ * CRUD verb names supported by `ModelFirebaseCrudFunctionConfigMap`. Mirrors the
10
+ * `create | read | update | delete | query` verbs in the type definition at
11
+ * `packages/firebase/src/lib/client/function/model.function.factory.ts`.
12
+ */
13
+ export declare const DEFAULT_CRUD_VERB_NAMES: readonly string[];
14
+ /**
15
+ * Options for the require-complete-crud-function-config-map rule.
16
+ */
17
+ export interface FirebaseRequireCompleteCrudFunctionConfigMapRuleOptions {
18
+ readonly typeName?: string;
19
+ readonly verbNames?: readonly string[];
20
+ }
21
+ /**
22
+ * ESLint rule definition for require-complete-crud-function-config-map.
23
+ */
24
+ export interface FirebaseRequireCompleteCrudFunctionConfigMapRuleDefinition {
25
+ readonly meta: {
26
+ readonly type: 'problem';
27
+ readonly fixable: undefined;
28
+ readonly docs: {
29
+ readonly description: string;
30
+ readonly recommended: boolean;
31
+ };
32
+ readonly messages: Readonly<Record<string, string>>;
33
+ readonly schema: readonly object[];
34
+ };
35
+ create(context: {
36
+ options: FirebaseRequireCompleteCrudFunctionConfigMapRuleOptions[];
37
+ report: (descriptor: {
38
+ node: AstNode;
39
+ messageId: string;
40
+ data?: Record<string, string>;
41
+ }) => void;
42
+ }): Record<string, (node: AstNode) => void>;
43
+ }
44
+ /**
45
+ * ESLint rule that verifies every `ModelFirebaseCrudFunctionConfigMap<ConfigType, ...>`
46
+ * variable initializer is structurally complete against its companion `ConfigType`
47
+ * defined in the same file.
48
+ *
49
+ * The rule walks the type alias for `ConfigType` (e.g., `NotificationBoxModelCrudFunctionsConfig`),
50
+ * builds the expected set of model keys, verbs, and specifiers, and then compares it
51
+ * against the object-literal initializer of the variable. Each mismatch — missing model
52
+ * key, missing verb, missing specifier, disabled-but-present key, etc. — is reported as
53
+ * an error so the const stays in sync with its companion type even when the TypeScript
54
+ * mapped-type enforcement decays in larger codebases.
55
+ *
56
+ * Same-file resolution only: the companion type must be declared in the same source
57
+ * file as the const (matching the convention in `notification.api.ts`, `oidcmodel.api.ts`,
58
+ * `storagefile.api.ts`). When the type cannot be located, the rule reports
59
+ * `configTypeNotFound`.
60
+ */
61
+ export declare const FIREBASE_REQUIRE_COMPLETE_CRUD_FUNCTION_CONFIG_MAP_RULE: FirebaseRequireCompleteCrudFunctionConfigMapRuleDefinition;
@@ -0,0 +1,47 @@
1
+ interface AstNode {
2
+ readonly type: string;
3
+ [key: string]: any;
4
+ }
5
+ /**
6
+ * Options for the require-dbx-model-companion-tags rule.
7
+ */
8
+ export interface FirebaseRequireDbxModelCompanionTagsRuleOptions {
9
+ readonly allowedEncodings?: readonly string[];
10
+ readonly knownCompanions?: readonly string[];
11
+ readonly requireBareMarker?: boolean;
12
+ readonly requireRead?: boolean;
13
+ }
14
+ /**
15
+ * ESLint rule definition for require-dbx-model-companion-tags.
16
+ */
17
+ export interface FirebaseRequireDbxModelCompanionTagsRuleDefinition {
18
+ readonly meta: {
19
+ readonly type: 'suggestion';
20
+ readonly fixable: 'code';
21
+ readonly docs: {
22
+ readonly description: string;
23
+ readonly recommended: boolean;
24
+ };
25
+ readonly messages: Readonly<Record<string, string>>;
26
+ readonly schema: readonly object[];
27
+ };
28
+ create(context: {
29
+ options: FirebaseRequireDbxModelCompanionTagsRuleOptions[];
30
+ report: (descriptor: {
31
+ loc?: AstNode;
32
+ messageId: string;
33
+ data?: Record<string, string>;
34
+ }) => void;
35
+ sourceCode: AstNode;
36
+ }): Record<string, (node: AstNode) => void>;
37
+ }
38
+ /**
39
+ * ESLint rule enforcing `@dbxModel` / `@dbxModelSubObject` / `@dbxModelOrganizationalGroupRoot`
40
+ * companion tags. Mirrors the scanner schema at
41
+ * `packages/dbx-cli/src/lib/mcp-scan/scan/extract-models/find-interfaces.ts`.
42
+ *
43
+ * Does NOT enforce a Slug / Category / Tags shape because the scanner does
44
+ * not consume those for this family.
45
+ */
46
+ export declare const FIREBASE_REQUIRE_DBX_MODEL_COMPANION_TAGS_RULE: FirebaseRequireDbxModelCompanionTagsRuleDefinition;
47
+ export {};
@@ -0,0 +1,56 @@
1
+ import { type AstNode } from './util';
2
+ /**
3
+ * Module that exports {@link FIREBASE_MODEL_SERVICE_FACTORY_NAME} — `@dereekb/firebase`.
4
+ */
5
+ export declare const FIREBASE_MODEL_SERVICE_FACTORY_MODULE = "@dereekb/firebase";
6
+ /**
7
+ * Imported name of the model-service factory whose calls trigger this rule.
8
+ */
9
+ export declare const FIREBASE_MODEL_SERVICE_FACTORY_NAME = "firebaseModelServiceFactory";
10
+ /**
11
+ * JSDoc tag that declares which Firestore model a `firebaseModelServiceFactory(...)` export
12
+ * implements. Value is the canonical `FirestoreModelIdentity.modelType` string
13
+ * (e.g. `guestbook`, `guestbookEntry`).
14
+ */
15
+ export declare const DBX_MODEL_SERVICE_FACTORY_TAG = "dbxModelServiceFactory";
16
+ /**
17
+ * Options for the require-dbx-model-service-factory-tag rule.
18
+ */
19
+ export interface FirebaseRequireDbxModelServiceFactoryTagRuleOptions {
20
+ readonly factoryName?: string;
21
+ readonly allowedImportSources?: readonly string[];
22
+ readonly tagName?: string;
23
+ }
24
+ /**
25
+ * ESLint rule definition for require-dbx-model-service-factory-tag.
26
+ */
27
+ export interface FirebaseRequireDbxModelServiceFactoryTagRuleDefinition {
28
+ readonly meta: {
29
+ readonly type: 'problem';
30
+ readonly fixable: undefined;
31
+ readonly docs: {
32
+ readonly description: string;
33
+ readonly recommended: boolean;
34
+ };
35
+ readonly messages: Readonly<Record<string, string>>;
36
+ readonly schema: readonly object[];
37
+ };
38
+ create(context: {
39
+ options: FirebaseRequireDbxModelServiceFactoryTagRuleOptions[];
40
+ report: (descriptor: {
41
+ node: AstNode;
42
+ messageId: string;
43
+ data?: Record<string, string>;
44
+ }) => void;
45
+ sourceCode: AstNode;
46
+ }): Record<string, (node: AstNode) => void>;
47
+ }
48
+ /**
49
+ * ESLint rule that requires every `firebaseModelServiceFactory(...)` export to carry a
50
+ * leading `@dbxModelServiceFactory <modelType>` JSDoc tag.
51
+ *
52
+ * The tag declares which Firestore model the factory implements, enabling the
53
+ * dbx-components-mcp model catalog to join factory metadata onto model entries and powering
54
+ * the orphan-model lint rule.
55
+ */
56
+ export declare const FIREBASE_REQUIRE_DBX_MODEL_SERVICE_FACTORY_TAG_RULE: FirebaseRequireDbxModelServiceFactoryTagRuleDefinition;
@@ -0,0 +1,45 @@
1
+ import { type AstNode } from './util';
2
+ /**
3
+ * Options for the require-firestore-constraint-type-parameter rule.
4
+ */
5
+ export interface FirebaseRequireFirestoreConstraintTypeParameterRuleOptions {
6
+ readonly constraintNames?: readonly string[];
7
+ readonly additionalConstraintNames?: readonly string[];
8
+ readonly allowedImportSources?: readonly string[];
9
+ }
10
+ /**
11
+ * ESLint rule definition for require-firestore-constraint-type-parameter.
12
+ */
13
+ export interface FirebaseRequireFirestoreConstraintTypeParameterRuleDefinition {
14
+ readonly meta: {
15
+ readonly type: 'suggestion';
16
+ readonly fixable: undefined;
17
+ readonly docs: {
18
+ readonly description: string;
19
+ readonly recommended: boolean;
20
+ };
21
+ readonly messages: Readonly<Record<string, string>>;
22
+ readonly schema: readonly object[];
23
+ };
24
+ create(context: {
25
+ options: FirebaseRequireFirestoreConstraintTypeParameterRuleOptions[];
26
+ report: (descriptor: {
27
+ node: AstNode;
28
+ messageId: string;
29
+ data?: Record<string, string>;
30
+ }) => void;
31
+ }): Record<string, (node: AstNode) => void>;
32
+ }
33
+ /**
34
+ * ESLint rule that warns when an `@dereekb/firebase` field-path-narrowing constraint factory
35
+ * (`where`, `orderBy`) is called without a generic type argument. Without `<Model>`, the
36
+ * overload falls back to a plain `FieldPathOrStringPath`, so field-name typos and renamed
37
+ * fields silently compile.
38
+ *
39
+ * The expected form is `where<Model>('field', '==', value)` / `orderBy<Model>('field')` so
40
+ * the field path is constrained to `StringKeyPropertyKeys<Model>`.
41
+ *
42
+ * Not auto-fixable: the rule cannot safely infer the correct model type from the surrounding
43
+ * function signature in an ESLint autofix.
44
+ */
45
+ export declare const FIREBASE_REQUIRE_FIRESTORE_CONSTRAINT_TYPE_PARAMETER_RULE: FirebaseRequireFirestoreConstraintTypeParameterRuleDefinition;