pyric 0.0.1 → 0.1.0-alpha.8
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/README.md +138 -2
- package/README.md.orig +54 -0
- package/dist/app/index.d.ts +81 -0
- package/dist/app/index.d.ts.map +1 -0
- package/dist/app/index.js +78 -0
- package/dist/app/index.js.map +1 -0
- package/dist/auth/index.d.ts +346 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +701 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/prod-backend.d.ts +39 -0
- package/dist/auth/prod-backend.d.ts.map +1 -0
- package/dist/auth/prod-backend.js +179 -0
- package/dist/auth/prod-backend.js.map +1 -0
- package/dist/auth/providers.d.ts +107 -0
- package/dist/auth/providers.d.ts.map +1 -0
- package/dist/auth/providers.js +138 -0
- package/dist/auth/providers.js.map +1 -0
- package/dist/auth/sandbox-backend.d.ts +769 -0
- package/dist/auth/sandbox-backend.d.ts.map +1 -0
- package/dist/auth/sandbox-backend.js +1598 -0
- package/dist/auth/sandbox-backend.js.map +1 -0
- package/dist/auth/target.d.ts +40 -0
- package/dist/auth/target.d.ts.map +1 -0
- package/dist/auth/target.js +28 -0
- package/dist/auth/target.js.map +1 -0
- package/dist/auth/types.d.ts +252 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +26 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/database/constraints/atoms.d.ts +29 -0
- package/dist/database/constraints/atoms.d.ts.map +1 -0
- package/dist/database/constraints/atoms.js +43 -0
- package/dist/database/constraints/atoms.js.map +1 -0
- package/dist/database/constraints/compose.d.ts +16 -0
- package/dist/database/constraints/compose.d.ts.map +1 -0
- package/dist/database/constraints/compose.js +15 -0
- package/dist/database/constraints/compose.js.map +1 -0
- package/dist/database/constraints/data.d.ts +30 -0
- package/dist/database/constraints/data.d.ts.map +1 -0
- package/dist/database/constraints/data.js +46 -0
- package/dist/database/constraints/data.js.map +1 -0
- package/dist/database/constraints/document.d.ts +42 -0
- package/dist/database/constraints/document.d.ts.map +1 -0
- package/dist/database/constraints/document.js +86 -0
- package/dist/database/constraints/document.js.map +1 -0
- package/dist/database/constraints/game.d.ts +30 -0
- package/dist/database/constraints/game.d.ts.map +1 -0
- package/dist/database/constraints/game.js +49 -0
- package/dist/database/constraints/game.js.map +1 -0
- package/dist/database/constraints/index.d.ts +12 -0
- package/dist/database/constraints/index.d.ts.map +1 -0
- package/dist/database/constraints/index.js +9 -0
- package/dist/database/constraints/index.js.map +1 -0
- package/dist/database/constraints/policies.d.ts +16 -0
- package/dist/database/constraints/policies.d.ts.map +1 -0
- package/dist/database/constraints/policies.js +17 -0
- package/dist/database/constraints/policies.js.map +1 -0
- package/dist/database/constraints/ruleset.d.ts +5 -0
- package/dist/database/constraints/ruleset.d.ts.map +1 -0
- package/dist/database/constraints/ruleset.js +132 -0
- package/dist/database/constraints/ruleset.js.map +1 -0
- package/dist/database/constraints/schema.d.ts +17 -0
- package/dist/database/constraints/schema.d.ts.map +1 -0
- package/dist/database/constraints/schema.js +74 -0
- package/dist/database/constraints/schema.js.map +1 -0
- package/dist/database/constraints/types.d.ts +22 -0
- package/dist/database/constraints/types.d.ts.map +1 -0
- package/dist/database/constraints/types.js +2 -0
- package/dist/database/constraints/types.js.map +1 -0
- package/dist/database/crawl/handler.d.ts +7 -0
- package/dist/database/crawl/handler.d.ts.map +1 -0
- package/dist/database/crawl/handler.js +91 -0
- package/dist/database/crawl/handler.js.map +1 -0
- package/dist/database/crawl/semaphore.d.ts +9 -0
- package/dist/database/crawl/semaphore.d.ts.map +1 -0
- package/dist/database/crawl/semaphore.js +27 -0
- package/dist/database/crawl/semaphore.js.map +1 -0
- package/dist/database/crawl/spec.d.ts +33 -0
- package/dist/database/crawl/spec.d.ts.map +1 -0
- package/dist/database/crawl/spec.js +12 -0
- package/dist/database/crawl/spec.js.map +1 -0
- package/dist/database/data/handler.d.ts +9 -0
- package/dist/database/data/handler.d.ts.map +1 -0
- package/dist/database/data/handler.js +96 -0
- package/dist/database/data/handler.js.map +1 -0
- package/dist/database/data/spec.d.ts +77 -0
- package/dist/database/data/spec.d.ts.map +1 -0
- package/dist/database/data/spec.js +17 -0
- package/dist/database/data/spec.js.map +1 -0
- package/dist/database/data/validated.d.ts +8 -0
- package/dist/database/data/validated.d.ts.map +1 -0
- package/dist/database/data/validated.js +99 -0
- package/dist/database/data/validated.js.map +1 -0
- package/dist/database/grammar/RtdbExpr.ohm +98 -0
- package/dist/database/grammar/RtdbExpr.ohm.generated.d.ts +2 -0
- package/dist/database/grammar/RtdbExpr.ohm.generated.d.ts.map +1 -0
- package/dist/database/grammar/RtdbExpr.ohm.generated.js +103 -0
- package/dist/database/grammar/RtdbExpr.ohm.generated.js.map +1 -0
- package/dist/database/grammar/RtdbExprParser.d.ts +5 -0
- package/dist/database/grammar/RtdbExprParser.d.ts.map +1 -0
- package/dist/database/grammar/RtdbExprParser.js +53 -0
- package/dist/database/grammar/RtdbExprParser.js.map +1 -0
- package/dist/database/grammar/linter.d.ts +3 -0
- package/dist/database/grammar/linter.d.ts.map +1 -0
- package/dist/database/grammar/linter.js +66 -0
- package/dist/database/grammar/linter.js.map +1 -0
- package/dist/database/grammar/simulator.d.ts +31 -0
- package/dist/database/grammar/simulator.d.ts.map +1 -0
- package/dist/database/grammar/simulator.js +255 -0
- package/dist/database/grammar/simulator.js.map +1 -0
- package/dist/database/grammar/validator.d.ts +3 -0
- package/dist/database/grammar/validator.d.ts.map +1 -0
- package/dist/database/grammar/validator.js +84 -0
- package/dist/database/grammar/validator.js.map +1 -0
- package/dist/database/host.d.ts +50 -0
- package/dist/database/host.d.ts.map +1 -0
- package/dist/database/host.js +41 -0
- package/dist/database/host.js.map +1 -0
- package/dist/database/index.d.ts +40 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +47 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/initialize-from-app.d.ts +28 -0
- package/dist/database/initialize-from-app.d.ts.map +1 -0
- package/dist/database/initialize-from-app.js +23 -0
- package/dist/database/initialize-from-app.js.map +1 -0
- package/dist/database/ir/handler.d.ts +6 -0
- package/dist/database/ir/handler.d.ts.map +1 -0
- package/dist/database/ir/handler.js +52 -0
- package/dist/database/ir/handler.js.map +1 -0
- package/dist/database/ir/spec.d.ts +25 -0
- package/dist/database/ir/spec.d.ts.map +1 -0
- package/dist/database/ir/spec.js +11 -0
- package/dist/database/ir/spec.js.map +1 -0
- package/dist/database/mapper.d.ts +9 -0
- package/dist/database/mapper.d.ts.map +1 -0
- package/dist/database/mapper.js +115 -0
- package/dist/database/mapper.js.map +1 -0
- package/dist/database/modular.d.ts +604 -0
- package/dist/database/modular.d.ts.map +1 -0
- package/dist/database/modular.js +1226 -0
- package/dist/database/modular.js.map +1 -0
- package/dist/database/replay.d.ts +33 -0
- package/dist/database/replay.d.ts.map +1 -0
- package/dist/database/replay.js +124 -0
- package/dist/database/replay.js.map +1 -0
- package/dist/database/resolver.d.ts +4 -0
- package/dist/database/resolver.d.ts.map +1 -0
- package/dist/database/resolver.js +66 -0
- package/dist/database/resolver.js.map +1 -0
- package/dist/database/sandbox/backend.d.ts +403 -0
- package/dist/database/sandbox/backend.d.ts.map +1 -0
- package/dist/database/sandbox/backend.js +1467 -0
- package/dist/database/sandbox/backend.js.map +1 -0
- package/dist/database/sandbox/data-tree.d.ts +123 -0
- package/dist/database/sandbox/data-tree.d.ts.map +1 -0
- package/dist/database/sandbox/data-tree.js +310 -0
- package/dist/database/sandbox/data-tree.js.map +1 -0
- package/dist/database/sandbox/normalize.d.ts +77 -0
- package/dist/database/sandbox/normalize.d.ts.map +1 -0
- package/dist/database/sandbox/normalize.js +165 -0
- package/dist/database/sandbox/normalize.js.map +1 -0
- package/dist/database/sandbox/push-id.d.ts +32 -0
- package/dist/database/sandbox/push-id.d.ts.map +1 -0
- package/dist/database/sandbox/push-id.js +82 -0
- package/dist/database/sandbox/push-id.js.map +1 -0
- package/dist/database/sandbox/query.d.ts +175 -0
- package/dist/database/sandbox/query.d.ts.map +1 -0
- package/dist/database/sandbox/query.js +269 -0
- package/dist/database/sandbox/query.js.map +1 -0
- package/dist/database/sandbox/rules-eval.d.ts +69 -0
- package/dist/database/sandbox/rules-eval.d.ts.map +1 -0
- package/dist/database/sandbox/rules-eval.js +124 -0
- package/dist/database/sandbox/rules-eval.js.map +1 -0
- package/dist/database/sandbox/sentinels.d.ts +71 -0
- package/dist/database/sandbox/sentinels.d.ts.map +1 -0
- package/dist/database/sandbox/sentinels.js +92 -0
- package/dist/database/sandbox/sentinels.js.map +1 -0
- package/dist/database/simulation/handler.d.ts +6 -0
- package/dist/database/simulation/handler.d.ts.map +1 -0
- package/dist/database/simulation/handler.js +236 -0
- package/dist/database/simulation/handler.js.map +1 -0
- package/dist/database/simulation/spec.d.ts +69 -0
- package/dist/database/simulation/spec.d.ts.map +1 -0
- package/dist/database/simulation/spec.js +25 -0
- package/dist/database/simulation/spec.js.map +1 -0
- package/dist/database/tools.d.ts +22 -0
- package/dist/database/tools.d.ts.map +1 -0
- package/dist/database/tools.js +272 -0
- package/dist/database/tools.js.map +1 -0
- package/dist/database/types.d.ts +210 -0
- package/dist/database/types.d.ts.map +1 -0
- package/dist/database/types.js +26 -0
- package/dist/database/types.js.map +1 -0
- package/dist/database/write/handler.d.ts +7 -0
- package/dist/database/write/handler.d.ts.map +1 -0
- package/dist/database/write/handler.js +42 -0
- package/dist/database/write/handler.js.map +1 -0
- package/dist/database/write/spec.d.ts +18 -0
- package/dist/database/write/spec.d.ts.map +1 -0
- package/dist/database/write/spec.js +7 -0
- package/dist/database/write/spec.js.map +1 -0
- package/dist/firestore/index.d.ts +533 -0
- package/dist/firestore/index.d.ts.map +1 -0
- package/dist/firestore/index.js +1536 -0
- package/dist/firestore/index.js.map +1 -0
- package/dist/firestore/tools.d.ts +67 -0
- package/dist/firestore/tools.d.ts.map +1 -0
- package/dist/firestore/tools.js +318 -0
- package/dist/firestore/tools.js.map +1 -0
- package/dist/firestore-values/index.d.ts +63 -0
- package/dist/firestore-values/index.d.ts.map +1 -0
- package/dist/firestore-values/index.js +148 -0
- package/dist/firestore-values/index.js.map +1 -0
- package/dist/project-scope.d.ts +5 -0
- package/dist/project-scope.d.ts.map +1 -0
- package/dist/project-scope.js +2 -0
- package/dist/project-scope.js.map +1 -0
- package/dist/rules/extract.d.ts +28 -0
- package/dist/rules/extract.d.ts.map +1 -0
- package/dist/rules/extract.js +25 -0
- package/dist/rules/extract.js.map +1 -0
- package/dist/rules/generators/assembler.d.ts +19 -0
- package/dist/rules/generators/assembler.d.ts.map +1 -0
- package/dist/rules/generators/assembler.js +292 -0
- package/dist/rules/generators/assembler.js.map +1 -0
- package/dist/rules/generators/expressions.d.ts +52 -0
- package/dist/rules/generators/expressions.d.ts.map +1 -0
- package/dist/rules/generators/expressions.js +117 -0
- package/dist/rules/generators/expressions.js.map +1 -0
- package/dist/rules/generators/grid.d.ts +22 -0
- package/dist/rules/generators/grid.d.ts.map +1 -0
- package/dist/rules/generators/grid.js +52 -0
- package/dist/rules/generators/grid.js.map +1 -0
- package/dist/rules/grammar/FirestoreAST.d.ts +129 -0
- package/dist/rules/grammar/FirestoreAST.d.ts.map +1 -0
- package/dist/rules/grammar/FirestoreAST.js +3 -0
- package/dist/rules/grammar/FirestoreAST.js.map +1 -0
- package/dist/rules/grammar/FirestoreAssembler.d.ts +5 -0
- package/dist/rules/grammar/FirestoreAssembler.d.ts.map +1 -0
- package/dist/rules/grammar/FirestoreAssembler.js +158 -0
- package/dist/rules/grammar/FirestoreAssembler.js.map +1 -0
- package/dist/rules/grammar/FirestoreParser.d.ts +46 -0
- package/dist/rules/grammar/FirestoreParser.d.ts.map +1 -0
- package/dist/rules/grammar/FirestoreParser.js +409 -0
- package/dist/rules/grammar/FirestoreParser.js.map +1 -0
- package/dist/rules/grammar/FirestoreRules.ohm +229 -0
- package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts +2 -0
- package/dist/rules/grammar/FirestoreRules.ohm.generated.d.ts.map +1 -0
- package/dist/rules/grammar/FirestoreRules.ohm.generated.js +234 -0
- package/dist/rules/grammar/FirestoreRules.ohm.generated.js.map +1 -0
- package/dist/rules/grammar/FirestoreValidator.d.ts +10 -0
- package/dist/rules/grammar/FirestoreValidator.d.ts.map +1 -0
- package/dist/rules/grammar/FirestoreValidator.js +482 -0
- package/dist/rules/grammar/FirestoreValidator.js.map +1 -0
- package/dist/rules/index.d.ts +67 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +80 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/indexes/extract/annotation-collect.d.ts +42 -0
- package/dist/rules/indexes/extract/annotation-collect.d.ts.map +1 -0
- package/dist/rules/indexes/extract/annotation-collect.js +69 -0
- package/dist/rules/indexes/extract/annotation-collect.js.map +1 -0
- package/dist/rules/indexes/extract/annotations.d.ts +50 -0
- package/dist/rules/indexes/extract/annotations.d.ts.map +1 -0
- package/dist/rules/indexes/extract/annotations.js +144 -0
- package/dist/rules/indexes/extract/annotations.js.map +1 -0
- package/dist/rules/indexes/extract/ast.d.ts +54 -0
- package/dist/rules/indexes/extract/ast.d.ts.map +1 -0
- package/dist/rules/indexes/extract/ast.js +119 -0
- package/dist/rules/indexes/extract/ast.js.map +1 -0
- package/dist/rules/indexes/extract/classify.d.ts +41 -0
- package/dist/rules/indexes/extract/classify.d.ts.map +1 -0
- package/dist/rules/indexes/extract/classify.js +138 -0
- package/dist/rules/indexes/extract/classify.js.map +1 -0
- package/dist/rules/indexes/extract/composite.d.ts +38 -0
- package/dist/rules/indexes/extract/composite.d.ts.map +1 -0
- package/dist/rules/indexes/extract/composite.js +85 -0
- package/dist/rules/indexes/extract/composite.js.map +1 -0
- package/dist/rules/indexes/extract/dataflow.d.ts +45 -0
- package/dist/rules/indexes/extract/dataflow.d.ts.map +1 -0
- package/dist/rules/indexes/extract/dataflow.js +200 -0
- package/dist/rules/indexes/extract/dataflow.js.map +1 -0
- package/dist/rules/indexes/extract/enumerate.d.ts +41 -0
- package/dist/rules/indexes/extract/enumerate.d.ts.map +1 -0
- package/dist/rules/indexes/extract/enumerate.js +163 -0
- package/dist/rules/indexes/extract/enumerate.js.map +1 -0
- package/dist/rules/indexes/extract/extractor.d.ts +3 -0
- package/dist/rules/indexes/extract/extractor.d.ts.map +1 -0
- package/dist/rules/indexes/extract/extractor.js +274 -0
- package/dist/rules/indexes/extract/extractor.js.map +1 -0
- package/dist/rules/indexes/extract/types.d.ts +211 -0
- package/dist/rules/indexes/extract/types.d.ts.map +1 -0
- package/dist/rules/indexes/extract/types.js +14 -0
- package/dist/rules/indexes/extract/types.js.map +1 -0
- package/dist/rules/indexes/extractHandler.d.ts +16 -0
- package/dist/rules/indexes/extractHandler.d.ts.map +1 -0
- package/dist/rules/indexes/extractHandler.js +100 -0
- package/dist/rules/indexes/extractHandler.js.map +1 -0
- package/dist/rules/indexes/extractTool.d.ts +15 -0
- package/dist/rules/indexes/extractTool.d.ts.map +1 -0
- package/dist/rules/indexes/extractTool.js +55 -0
- package/dist/rules/indexes/extractTool.js.map +1 -0
- package/dist/rules/indexes/types.d.ts +71 -0
- package/dist/rules/indexes/types.d.ts.map +1 -0
- package/dist/rules/indexes/types.js +15 -0
- package/dist/rules/indexes/types.js.map +1 -0
- package/dist/rules/inspect/handler.d.ts +6 -0
- package/dist/rules/inspect/handler.d.ts.map +1 -0
- package/dist/rules/inspect/handler.js +144 -0
- package/dist/rules/inspect/handler.js.map +1 -0
- package/dist/rules/inspect/spec.d.ts +37 -0
- package/dist/rules/inspect/spec.d.ts.map +1 -0
- package/dist/rules/inspect/spec.js +2 -0
- package/dist/rules/inspect/spec.js.map +1 -0
- package/dist/rules/inspect/tools.d.ts +21 -0
- package/dist/rules/inspect/tools.d.ts.map +1 -0
- package/dist/rules/inspect/tools.js +21 -0
- package/dist/rules/inspect/tools.js.map +1 -0
- package/dist/rules/linter/ast-utils.d.ts +97 -0
- package/dist/rules/linter/ast-utils.d.ts.map +1 -0
- package/dist/rules/linter/ast-utils.js +491 -0
- package/dist/rules/linter/ast-utils.js.map +1 -0
- package/dist/rules/linter/hallucinations.d.ts +34 -0
- package/dist/rules/linter/hallucinations.d.ts.map +1 -0
- package/dist/rules/linter/hallucinations.js +334 -0
- package/dist/rules/linter/hallucinations.js.map +1 -0
- package/dist/rules/linter/linter.d.ts +84 -0
- package/dist/rules/linter/linter.d.ts.map +1 -0
- package/dist/rules/linter/linter.js +784 -0
- package/dist/rules/linter/linter.js.map +1 -0
- package/dist/rules/modules/resolver-browser.d.ts +41 -0
- package/dist/rules/modules/resolver-browser.d.ts.map +1 -0
- package/dist/rules/modules/resolver-browser.js +63 -0
- package/dist/rules/modules/resolver-browser.js.map +1 -0
- package/dist/rules/modules/resolver-core.d.ts +51 -0
- package/dist/rules/modules/resolver-core.d.ts.map +1 -0
- package/dist/rules/modules/resolver-core.js +338 -0
- package/dist/rules/modules/resolver-core.js.map +1 -0
- package/dist/rules/modules/resolver.d.ts +17 -0
- package/dist/rules/modules/resolver.d.ts.map +1 -0
- package/dist/rules/modules/resolver.js +49 -0
- package/dist/rules/modules/resolver.js.map +1 -0
- package/dist/rules/modules/stdlib/atomic.rules +52 -0
- package/dist/rules/modules/stdlib/atomic.test.json +152 -0
- package/dist/rules/modules/stdlib/auth.rules +7 -0
- package/dist/rules/modules/stdlib/auth.test.json +53 -0
- package/dist/rules/modules/stdlib/content.rules +50 -0
- package/dist/rules/modules/stdlib/content.test.json +238 -0
- package/dist/rules/modules/stdlib/counters.rules +41 -0
- package/dist/rules/modules/stdlib/counters.test.json +254 -0
- package/dist/rules/modules/stdlib/geometry.rules +43 -0
- package/dist/rules/modules/stdlib/geometry.test.json +200 -0
- package/dist/rules/modules/stdlib/joining.rules +49 -0
- package/dist/rules/modules/stdlib/joining.test.json +287 -0
- package/dist/rules/modules/stdlib/lifecycle.rules +51 -0
- package/dist/rules/modules/stdlib/lifecycle.test.json +288 -0
- package/dist/rules/modules/stdlib/lobby.rules +44 -0
- package/dist/rules/modules/stdlib/lobby.test.json +32 -0
- package/dist/rules/modules/stdlib/membership.rules +40 -0
- package/dist/rules/modules/stdlib/membership.test.json +107 -0
- package/dist/rules/modules/stdlib/spaces.rules +46 -0
- package/dist/rules/modules/stdlib/spaces.test.json +392 -0
- package/dist/rules/modules/stdlib/state.rules +28 -0
- package/dist/rules/modules/stdlib/state.test.json +55 -0
- package/dist/rules/modules/stdlib/timing.rules +20 -0
- package/dist/rules/modules/stdlib/timing.test.json +106 -0
- package/dist/rules/modules/stdlib/transitions.rules +34 -0
- package/dist/rules/modules/stdlib/transitions.test.json +86 -0
- package/dist/rules/modules/stdlib/turns.rules +27 -0
- package/dist/rules/modules/stdlib/turns.test.json +64 -0
- package/dist/rules/modules/stdlib/validation.rules +31 -0
- package/dist/rules/modules/stdlib/validation.test.json +184 -0
- package/dist/rules/modules/stdlib-content.d.ts +11 -0
- package/dist/rules/modules/stdlib-content.d.ts.map +1 -0
- package/dist/rules/modules/stdlib-content.js +590 -0
- package/dist/rules/modules/stdlib-content.js.map +1 -0
- package/dist/rules/node.d.ts +17 -0
- package/dist/rules/node.d.ts.map +1 -0
- package/dist/rules/node.js +21 -0
- package/dist/rules/node.js.map +1 -0
- package/dist/rules/rtdb.d.ts +28 -0
- package/dist/rules/rtdb.d.ts.map +1 -0
- package/dist/rules/rtdb.js +15 -0
- package/dist/rules/rtdb.js.map +1 -0
- package/dist/rules/simulator/evaluator.d.ts +179 -0
- package/dist/rules/simulator/evaluator.d.ts.map +1 -0
- package/dist/rules/simulator/evaluator.js +1221 -0
- package/dist/rules/simulator/evaluator.js.map +1 -0
- package/dist/rules/simulator/expression/eval-errors.d.ts +86 -0
- package/dist/rules/simulator/expression/eval-errors.d.ts.map +1 -0
- package/dist/rules/simulator/expression/eval-errors.js +68 -0
- package/dist/rules/simulator/expression/eval-errors.js.map +1 -0
- package/dist/rules/simulator/expression/evaluator.d.ts +43 -0
- package/dist/rules/simulator/expression/evaluator.d.ts.map +1 -0
- package/dist/rules/simulator/expression/evaluator.js +298 -0
- package/dist/rules/simulator/expression/evaluator.js.map +1 -0
- package/dist/rules/simulator/expression/lexer.d.ts +36 -0
- package/dist/rules/simulator/expression/lexer.d.ts.map +1 -0
- package/dist/rules/simulator/expression/lexer.js +318 -0
- package/dist/rules/simulator/expression/lexer.js.map +1 -0
- package/dist/rules/simulator/expression/parser.d.ts +39 -0
- package/dist/rules/simulator/expression/parser.d.ts.map +1 -0
- package/dist/rules/simulator/expression/parser.js +329 -0
- package/dist/rules/simulator/expression/parser.js.map +1 -0
- package/dist/rules/simulator/expression/types.d.ts +137 -0
- package/dist/rules/simulator/expression/types.d.ts.map +1 -0
- package/dist/rules/simulator/expression/types.js +90 -0
- package/dist/rules/simulator/expression/types.js.map +1 -0
- package/dist/rules/simulator/expression/walk-data.d.ts +52 -0
- package/dist/rules/simulator/expression/walk-data.d.ts.map +1 -0
- package/dist/rules/simulator/expression/walk-data.js +167 -0
- package/dist/rules/simulator/expression/walk-data.js.map +1 -0
- package/dist/rules/simulator/firestore-set.d.ts +25 -0
- package/dist/rules/simulator/firestore-set.d.ts.map +1 -0
- package/dist/rules/simulator/firestore-set.js +89 -0
- package/dist/rules/simulator/firestore-set.js.map +1 -0
- package/dist/rules/simulator/handler.d.ts +36 -0
- package/dist/rules/simulator/handler.d.ts.map +1 -0
- package/dist/rules/simulator/handler.js +583 -0
- package/dist/rules/simulator/handler.js.map +1 -0
- package/dist/rules/simulator/mapdiff.d.ts +29 -0
- package/dist/rules/simulator/mapdiff.d.ts.map +1 -0
- package/dist/rules/simulator/mapdiff.js +72 -0
- package/dist/rules/simulator/mapdiff.js.map +1 -0
- package/dist/rules/simulator/project-after-state.d.ts +33 -0
- package/dist/rules/simulator/project-after-state.d.ts.map +1 -0
- package/dist/rules/simulator/project-after-state.js +88 -0
- package/dist/rules/simulator/project-after-state.js.map +1 -0
- package/dist/rules/simulator/query-proof.d.ts +80 -0
- package/dist/rules/simulator/query-proof.d.ts.map +1 -0
- package/dist/rules/simulator/query-proof.js +142 -0
- package/dist/rules/simulator/query-proof.js.map +1 -0
- package/dist/rules/simulator/value-equality.d.ts +8 -0
- package/dist/rules/simulator/value-equality.d.ts.map +1 -0
- package/dist/rules/simulator/value-equality.js +40 -0
- package/dist/rules/simulator/value-equality.js.map +1 -0
- package/dist/rules/simulator/wrappers/base.d.ts +129 -0
- package/dist/rules/simulator/wrappers/base.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/base.js +90 -0
- package/dist/rules/simulator/wrappers/base.js.map +1 -0
- package/dist/rules/simulator/wrappers/bytes.d.ts +45 -0
- package/dist/rules/simulator/wrappers/bytes.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/bytes.js +130 -0
- package/dist/rules/simulator/wrappers/bytes.js.map +1 -0
- package/dist/rules/simulator/wrappers/duration.d.ts +76 -0
- package/dist/rules/simulator/wrappers/duration.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/duration.js +176 -0
- package/dist/rules/simulator/wrappers/duration.js.map +1 -0
- package/dist/rules/simulator/wrappers/float.d.ts +52 -0
- package/dist/rules/simulator/wrappers/float.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/float.js +88 -0
- package/dist/rules/simulator/wrappers/float.js.map +1 -0
- package/dist/rules/simulator/wrappers/latlng.d.ts +40 -0
- package/dist/rules/simulator/wrappers/latlng.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/latlng.js +100 -0
- package/dist/rules/simulator/wrappers/latlng.js.map +1 -0
- package/dist/rules/simulator/wrappers/path.d.ts +75 -0
- package/dist/rules/simulator/wrappers/path.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/path.js +158 -0
- package/dist/rules/simulator/wrappers/path.js.map +1 -0
- package/dist/rules/simulator/wrappers/reference.d.ts +82 -0
- package/dist/rules/simulator/wrappers/reference.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/reference.js +145 -0
- package/dist/rules/simulator/wrappers/reference.js.map +1 -0
- package/dist/rules/simulator/wrappers/timestamp.d.ts +86 -0
- package/dist/rules/simulator/wrappers/timestamp.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/timestamp.js +207 -0
- package/dist/rules/simulator/wrappers/timestamp.js.map +1 -0
- package/dist/rules/simulator/wrappers/vector.d.ts +43 -0
- package/dist/rules/simulator/wrappers/vector.d.ts.map +1 -0
- package/dist/rules/simulator/wrappers/vector.js +80 -0
- package/dist/rules/simulator/wrappers/vector.js.map +1 -0
- package/dist/rules/simulator-tools-impl.d.ts +64 -0
- package/dist/rules/simulator-tools-impl.d.ts.map +1 -0
- package/dist/rules/simulator-tools-impl.js +462 -0
- package/dist/rules/simulator-tools-impl.js.map +1 -0
- package/dist/rules/simulator.d.ts +20 -0
- package/dist/rules/simulator.d.ts.map +1 -0
- package/dist/rules/simulator.js +24 -0
- package/dist/rules/simulator.js.map +1 -0
- package/dist/rules/stdlib-modules.d.ts +73 -0
- package/dist/rules/stdlib-modules.d.ts.map +1 -0
- package/dist/rules/stdlib-modules.js +849 -0
- package/dist/rules/stdlib-modules.js.map +1 -0
- package/dist/rules/stdlib-tools.d.ts +19 -0
- package/dist/rules/stdlib-tools.d.ts.map +1 -0
- package/dist/rules/stdlib-tools.js +164 -0
- package/dist/rules/stdlib-tools.js.map +1 -0
- package/dist/rules/test/handler.d.ts +9 -0
- package/dist/rules/test/handler.d.ts.map +1 -0
- package/dist/rules/test/handler.js +124 -0
- package/dist/rules/test/handler.js.map +1 -0
- package/dist/rules/test/spec.d.ts +517 -0
- package/dist/rules/test/spec.d.ts.map +1 -0
- package/dist/rules/test/spec.js +227 -0
- package/dist/rules/test/spec.js.map +1 -0
- package/dist/rules/tools.d.ts +41 -0
- package/dist/rules/tools.d.ts.map +1 -0
- package/dist/rules/tools.js +124 -0
- package/dist/rules/tools.js.map +1 -0
- package/dist/rules/write/handler.d.ts +6 -0
- package/dist/rules/write/handler.d.ts.map +1 -0
- package/dist/rules/write/handler.js +126 -0
- package/dist/rules/write/handler.js.map +1 -0
- package/dist/rules/write/spec.d.ts +28 -0
- package/dist/rules/write/spec.d.ts.map +1 -0
- package/dist/rules/write/spec.js +2 -0
- package/dist/rules/write/spec.js.map +1 -0
- package/dist/sandbox/admin-compat.d.ts +20 -0
- package/dist/sandbox/admin-compat.d.ts.map +1 -0
- package/dist/sandbox/admin-compat.js +19 -0
- package/dist/sandbox/admin-compat.js.map +1 -0
- package/dist/sandbox/admin-firestore/error-translation.d.ts +86 -0
- package/dist/sandbox/admin-firestore/error-translation.d.ts.map +1 -0
- package/dist/sandbox/admin-firestore/error-translation.js +204 -0
- package/dist/sandbox/admin-firestore/error-translation.js.map +1 -0
- package/dist/sandbox/admin-firestore/index.d.ts +169 -0
- package/dist/sandbox/admin-firestore/index.d.ts.map +1 -0
- package/dist/sandbox/admin-firestore/index.js +456 -0
- package/dist/sandbox/admin-firestore/index.js.map +1 -0
- package/dist/sandbox/admin-firestore/remote.d.ts +97 -0
- package/dist/sandbox/admin-firestore/remote.d.ts.map +1 -0
- package/dist/sandbox/admin-firestore/remote.js +735 -0
- package/dist/sandbox/admin-firestore/remote.js.map +1 -0
- package/dist/sandbox/branches/index.d.ts +141 -0
- package/dist/sandbox/branches/index.d.ts.map +1 -0
- package/dist/sandbox/branches/index.js +327 -0
- package/dist/sandbox/branches/index.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/batch.d.ts +34 -0
- package/dist/sandbox/firestore/admin-compat/batch.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/batch.js +73 -0
- package/dist/sandbox/firestore/admin-compat/batch.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/doc-ref.d.ts +38 -0
- package/dist/sandbox/firestore/admin-compat/doc-ref.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/doc-ref.js +154 -0
- package/dist/sandbox/firestore/admin-compat/doc-ref.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/firestore.d.ts +45 -0
- package/dist/sandbox/firestore/admin-compat/firestore.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/firestore.js +114 -0
- package/dist/sandbox/firestore/admin-compat/firestore.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/index.d.ts +45 -0
- package/dist/sandbox/firestore/admin-compat/index.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/index.js +27 -0
- package/dist/sandbox/firestore/admin-compat/index.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/paths.d.ts +37 -0
- package/dist/sandbox/firestore/admin-compat/paths.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/paths.js +49 -0
- package/dist/sandbox/firestore/admin-compat/paths.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/query.d.ts +261 -0
- package/dist/sandbox/firestore/admin-compat/query.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/query.js +704 -0
- package/dist/sandbox/firestore/admin-compat/query.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/read-translation.d.ts +8 -0
- package/dist/sandbox/firestore/admin-compat/read-translation.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/read-translation.js +59 -0
- package/dist/sandbox/firestore/admin-compat/read-translation.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/snapshots.d.ts +39 -0
- package/dist/sandbox/firestore/admin-compat/snapshots.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/snapshots.js +50 -0
- package/dist/sandbox/firestore/admin-compat/snapshots.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/transaction.d.ts +35 -0
- package/dist/sandbox/firestore/admin-compat/transaction.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/transaction.js +88 -0
- package/dist/sandbox/firestore/admin-compat/transaction.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/types.d.ts +297 -0
- package/dist/sandbox/firestore/admin-compat/types.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/types.js +127 -0
- package/dist/sandbox/firestore/admin-compat/types.js.map +1 -0
- package/dist/sandbox/firestore/admin-compat/value-order.d.ts +49 -0
- package/dist/sandbox/firestore/admin-compat/value-order.d.ts.map +1 -0
- package/dist/sandbox/firestore/admin-compat/value-order.js +172 -0
- package/dist/sandbox/firestore/admin-compat/value-order.js.map +1 -0
- package/dist/sandbox/firestore/auto-id.d.ts +26 -0
- package/dist/sandbox/firestore/auto-id.d.ts.map +1 -0
- package/dist/sandbox/firestore/auto-id.js +36 -0
- package/dist/sandbox/firestore/auto-id.js.map +1 -0
- package/dist/sandbox/firestore/converters/bytes-geopoint.d.ts +48 -0
- package/dist/sandbox/firestore/converters/bytes-geopoint.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/bytes-geopoint.js +85 -0
- package/dist/sandbox/firestore/converters/bytes-geopoint.js.map +1 -0
- package/dist/sandbox/firestore/converters/fieldvalue.d.ts +69 -0
- package/dist/sandbox/firestore/converters/fieldvalue.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/fieldvalue.js +166 -0
- package/dist/sandbox/firestore/converters/fieldvalue.js.map +1 -0
- package/dist/sandbox/firestore/converters/reference.d.ts +31 -0
- package/dist/sandbox/firestore/converters/reference.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/reference.js +51 -0
- package/dist/sandbox/firestore/converters/reference.js.map +1 -0
- package/dist/sandbox/firestore/converters/timestamp.d.ts +32 -0
- package/dist/sandbox/firestore/converters/timestamp.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/timestamp.js +63 -0
- package/dist/sandbox/firestore/converters/timestamp.js.map +1 -0
- package/dist/sandbox/firestore/converters/user-timestamp.d.ts +46 -0
- package/dist/sandbox/firestore/converters/user-timestamp.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/user-timestamp.js +65 -0
- package/dist/sandbox/firestore/converters/user-timestamp.js.map +1 -0
- package/dist/sandbox/firestore/converters/vector.d.ts +24 -0
- package/dist/sandbox/firestore/converters/vector.d.ts.map +1 -0
- package/dist/sandbox/firestore/converters/vector.js +53 -0
- package/dist/sandbox/firestore/converters/vector.js.map +1 -0
- package/dist/sandbox/firestore/errors.d.ts +82 -0
- package/dist/sandbox/firestore/errors.d.ts.map +1 -0
- package/dist/sandbox/firestore/errors.js +54 -0
- package/dist/sandbox/firestore/errors.js.map +1 -0
- package/dist/sandbox/firestore/event-log.d.ts +99 -0
- package/dist/sandbox/firestore/event-log.d.ts.map +1 -0
- package/dist/sandbox/firestore/event-log.js +67 -0
- package/dist/sandbox/firestore/event-log.js.map +1 -0
- package/dist/sandbox/firestore/field-merge.d.ts +64 -0
- package/dist/sandbox/firestore/field-merge.d.ts.map +1 -0
- package/dist/sandbox/firestore/field-merge.js +221 -0
- package/dist/sandbox/firestore/field-merge.js.map +1 -0
- package/dist/sandbox/firestore/list-query-proof.d.ts +77 -0
- package/dist/sandbox/firestore/list-query-proof.d.ts.map +1 -0
- package/dist/sandbox/firestore/list-query-proof.js +170 -0
- package/dist/sandbox/firestore/list-query-proof.js.map +1 -0
- package/dist/sandbox/firestore/local-environment.d.ts +806 -0
- package/dist/sandbox/firestore/local-environment.d.ts.map +1 -0
- package/dist/sandbox/firestore/local-environment.js +3028 -0
- package/dist/sandbox/firestore/local-environment.js.map +1 -0
- package/dist/sandbox/firestore/local-state.d.ts +196 -0
- package/dist/sandbox/firestore/local-state.d.ts.map +1 -0
- package/dist/sandbox/firestore/local-state.js +413 -0
- package/dist/sandbox/firestore/local-state.js.map +1 -0
- package/dist/sandbox/firestore/overlay-backing.d.ts +44 -0
- package/dist/sandbox/firestore/overlay-backing.d.ts.map +1 -0
- package/dist/sandbox/firestore/overlay-backing.js +82 -0
- package/dist/sandbox/firestore/overlay-backing.js.map +1 -0
- package/dist/sandbox/firestore/sentinel-capture.d.ts +30 -0
- package/dist/sandbox/firestore/sentinel-capture.d.ts.map +1 -0
- package/dist/sandbox/firestore/sentinel-capture.js +61 -0
- package/dist/sandbox/firestore/sentinel-capture.js.map +1 -0
- package/dist/sandbox/firestore/snapshot-listeners.d.ts +284 -0
- package/dist/sandbox/firestore/snapshot-listeners.d.ts.map +1 -0
- package/dist/sandbox/firestore/snapshot-listeners.js +194 -0
- package/dist/sandbox/firestore/snapshot-listeners.js.map +1 -0
- package/dist/sandbox/firestore/topk.d.ts +12 -0
- package/dist/sandbox/firestore/topk.d.ts.map +1 -0
- package/dist/sandbox/firestore/topk.js +42 -0
- package/dist/sandbox/firestore/topk.js.map +1 -0
- package/dist/sandbox/firestore/transaction-merge.d.ts +55 -0
- package/dist/sandbox/firestore/transaction-merge.d.ts.map +1 -0
- package/dist/sandbox/firestore/transaction-merge.js +107 -0
- package/dist/sandbox/firestore/transaction-merge.js.map +1 -0
- package/dist/sandbox/firestore/transaction-types.d.ts +152 -0
- package/dist/sandbox/firestore/transaction-types.d.ts.map +1 -0
- package/dist/sandbox/firestore/transaction-types.js +10 -0
- package/dist/sandbox/firestore/transaction-types.js.map +1 -0
- package/dist/sandbox/firestore/transaction.d.ts +79 -0
- package/dist/sandbox/firestore/transaction.d.ts.map +1 -0
- package/dist/sandbox/firestore/transaction.js +95 -0
- package/dist/sandbox/firestore/transaction.js.map +1 -0
- package/dist/sandbox/firestore/value-equality.d.ts +2 -0
- package/dist/sandbox/firestore/value-equality.d.ts.map +1 -0
- package/dist/sandbox/firestore/value-equality.js +35 -0
- package/dist/sandbox/firestore/value-equality.js.map +1 -0
- package/dist/sandbox/firestore/value-resolver.d.ts +172 -0
- package/dist/sandbox/firestore/value-resolver.d.ts.map +1 -0
- package/dist/sandbox/firestore/value-resolver.js +221 -0
- package/dist/sandbox/firestore/value-resolver.js.map +1 -0
- package/dist/sandbox/firestore/wire-encoder.d.ts +14 -0
- package/dist/sandbox/firestore/wire-encoder.d.ts.map +1 -0
- package/dist/sandbox/firestore/wire-encoder.js +130 -0
- package/dist/sandbox/firestore/wire-encoder.js.map +1 -0
- package/dist/sandbox/index.d.ts +50 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +63 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/internal/index.d.ts +36 -0
- package/dist/sandbox/internal/index.d.ts.map +1 -0
- package/dist/sandbox/internal/index.js +72 -0
- package/dist/sandbox/internal/index.js.map +1 -0
- package/dist/sandbox/internal/sandbox-impl.d.ts +343 -0
- package/dist/sandbox/internal/sandbox-impl.d.ts.map +1 -0
- package/dist/sandbox/internal/sandbox-impl.js +718 -0
- package/dist/sandbox/internal/sandbox-impl.js.map +1 -0
- package/dist/sandbox/persistence/backends.d.ts +37 -0
- package/dist/sandbox/persistence/backends.d.ts.map +1 -0
- package/dist/sandbox/persistence/backends.js +202 -0
- package/dist/sandbox/persistence/backends.js.map +1 -0
- package/dist/sandbox/persistence/chunk-format.d.ts +58 -0
- package/dist/sandbox/persistence/chunk-format.d.ts.map +1 -0
- package/dist/sandbox/persistence/chunk-format.js +163 -0
- package/dist/sandbox/persistence/chunk-format.js.map +1 -0
- package/dist/sandbox/persistence/controller.d.ts +39 -0
- package/dist/sandbox/persistence/controller.d.ts.map +1 -0
- package/dist/sandbox/persistence/controller.js +605 -0
- package/dist/sandbox/persistence/controller.js.map +1 -0
- package/dist/sandbox/persistence/index.d.ts +13 -0
- package/dist/sandbox/persistence/index.d.ts.map +1 -0
- package/dist/sandbox/persistence/index.js +5 -0
- package/dist/sandbox/persistence/index.js.map +1 -0
- package/dist/sandbox/persistence/serialize.d.ts +53 -0
- package/dist/sandbox/persistence/serialize.d.ts.map +1 -0
- package/dist/sandbox/persistence/serialize.js +98 -0
- package/dist/sandbox/persistence/serialize.js.map +1 -0
- package/dist/sandbox/persistence/types.d.ts +118 -0
- package/dist/sandbox/persistence/types.d.ts.map +1 -0
- package/dist/sandbox/persistence/types.js +15 -0
- package/dist/sandbox/persistence/types.js.map +1 -0
- package/dist/sandbox/remote.d.ts +118 -0
- package/dist/sandbox/remote.d.ts.map +1 -0
- package/dist/sandbox/remote.js +60 -0
- package/dist/sandbox/remote.js.map +1 -0
- package/dist/sandbox/replay/index.d.ts +106 -0
- package/dist/sandbox/replay/index.d.ts.map +1 -0
- package/dist/sandbox/replay/index.js +246 -0
- package/dist/sandbox/replay/index.js.map +1 -0
- package/dist/sandbox/sandbox-context.d.ts +40 -0
- package/dist/sandbox/sandbox-context.d.ts.map +1 -0
- package/dist/sandbox/sandbox-context.js +72 -0
- package/dist/sandbox/sandbox-context.js.map +1 -0
- package/dist/sandbox/tab-sync/index.d.ts +120 -0
- package/dist/sandbox/tab-sync/index.d.ts.map +1 -0
- package/dist/sandbox/tab-sync/index.js +272 -0
- package/dist/sandbox/tab-sync/index.js.map +1 -0
- package/dist/sandbox/types.d.ts +1235 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +46 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/storage/admin/api.d.ts +206 -0
- package/dist/storage/admin/api.d.ts.map +1 -0
- package/dist/storage/admin/api.js +349 -0
- package/dist/storage/admin/api.js.map +1 -0
- package/dist/storage/admin/handler.d.ts +29 -0
- package/dist/storage/admin/handler.d.ts.map +1 -0
- package/dist/storage/admin/handler.js +82 -0
- package/dist/storage/admin/handler.js.map +1 -0
- package/dist/storage/admin/spec.d.ts +64 -0
- package/dist/storage/admin/spec.d.ts.map +1 -0
- package/dist/storage/admin/spec.js +8 -0
- package/dist/storage/admin/spec.js.map +1 -0
- package/dist/storage/admin/tools.d.ts +23 -0
- package/dist/storage/admin/tools.d.ts.map +1 -0
- package/dist/storage/admin/tools.js +90 -0
- package/dist/storage/admin/tools.js.map +1 -0
- package/dist/storage/download.d.ts +27 -0
- package/dist/storage/download.d.ts.map +1 -0
- package/dist/storage/download.js +136 -0
- package/dist/storage/download.js.map +1 -0
- package/dist/storage/enforce.d.ts +26 -0
- package/dist/storage/enforce.d.ts.map +1 -0
- package/dist/storage/enforce.js +16 -0
- package/dist/storage/enforce.js.map +1 -0
- package/dist/storage/errors.d.ts +46 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +62 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/index.d.ts +49 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +60 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/internal.d.ts +18 -0
- package/dist/storage/internal.d.ts.map +1 -0
- package/dist/storage/internal.js +18 -0
- package/dist/storage/internal.js.map +1 -0
- package/dist/storage/list.d.ts +17 -0
- package/dist/storage/list.d.ts.map +1 -0
- package/dist/storage/list.js +91 -0
- package/dist/storage/list.js.map +1 -0
- package/dist/storage/metadata.d.ts +86 -0
- package/dist/storage/metadata.d.ts.map +1 -0
- package/dist/storage/metadata.js +167 -0
- package/dist/storage/metadata.js.map +1 -0
- package/dist/storage/persistence.d.ts +134 -0
- package/dist/storage/persistence.d.ts.map +1 -0
- package/dist/storage/persistence.js +132 -0
- package/dist/storage/persistence.js.map +1 -0
- package/dist/storage/reference.d.ts +63 -0
- package/dist/storage/reference.d.ts.map +1 -0
- package/dist/storage/reference.js +156 -0
- package/dist/storage/reference.js.map +1 -0
- package/dist/storage/rules.d.ts +176 -0
- package/dist/storage/rules.d.ts.map +1 -0
- package/dist/storage/rules.js +621 -0
- package/dist/storage/rules.js.map +1 -0
- package/dist/storage/service.d.ts +139 -0
- package/dist/storage/service.d.ts.map +1 -0
- package/dist/storage/service.js +241 -0
- package/dist/storage/service.js.map +1 -0
- package/dist/storage/upload.d.ts +43 -0
- package/dist/storage/upload.d.ts.map +1 -0
- package/dist/storage/upload.js +235 -0
- package/dist/storage/upload.js.map +1 -0
- package/package.json +110 -3
|
@@ -0,0 +1,784 @@
|
|
|
1
|
+
import { parseToASTOrError } from '../grammar/FirestoreParser.js';
|
|
2
|
+
import { maxChainDepth, deepestChain, countExpressionNodes, expressionFingerprint, extractFirstExpression, buildCallGraph, maxCallDepth, countGetCalls, countFunctionCallSites, functionContainsGet, referencesRequestTime, collectAllFunctions, collectAllRules, } from './ast-utils.js';
|
|
3
|
+
import { checkSyntaxHints, checkHallucinations } from './hallucinations.js';
|
|
4
|
+
// ═══ Thresholds (from production verification) ═══
|
|
5
|
+
const THRESHOLDS = {
|
|
6
|
+
SOURCE_SIZE: 256 * 1024, // 256 KB — exact, verified
|
|
7
|
+
CHAIN_DEPTH_ERROR: 95, // warn before the hard limit
|
|
8
|
+
CHAIN_DEPTH_WARN: 85,
|
|
9
|
+
CHAIN_DEPTH_LIMIT: 98, // exact compile limit, verified
|
|
10
|
+
LET_LIMIT: 11, // exact, verified (12 fails)
|
|
11
|
+
// Runtime budget is call-count-dependent and non-deterministic
|
|
12
|
+
RUNTIME_BUDGET: {
|
|
13
|
+
low: { calls: 2, warn: 100, error: 120 },
|
|
14
|
+
mid: { calls: 4, warn: 60, error: 90 },
|
|
15
|
+
high: { calls: Infinity, warn: 40, error: 60 },
|
|
16
|
+
},
|
|
17
|
+
CALL_DEPTH_WARN: 6,
|
|
18
|
+
CALL_DEPTH_ERROR: 10,
|
|
19
|
+
GET_COUNT_WARN: 5,
|
|
20
|
+
GET_COUNT_ERROR: 10, // documented by Google
|
|
21
|
+
};
|
|
22
|
+
// ═══ Lint Rules ═══
|
|
23
|
+
function checkSourceSize(source, warnings) {
|
|
24
|
+
if (source.length > THRESHOLDS.SOURCE_SIZE) {
|
|
25
|
+
warnings.push({
|
|
26
|
+
rule: 'SOURCE_SIZE',
|
|
27
|
+
severity: 'error',
|
|
28
|
+
message: `Rules source is ${(source.length / 1024).toFixed(0)} KB, exceeding the 256 KB limit.`,
|
|
29
|
+
fix: 'Reduce string literals, remove comments, or split into smaller match blocks.',
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function checkLetBindings(functions, warnings) {
|
|
34
|
+
for (const fn of functions) {
|
|
35
|
+
if (fn.lets.length > THRESHOLDS.LET_LIMIT) {
|
|
36
|
+
warnings.push({
|
|
37
|
+
rule: 'LET_LIMIT',
|
|
38
|
+
severity: 'error',
|
|
39
|
+
message: `Function '${fn.name}' has ${fn.lets.length} let bindings. Limit is ${THRESHOLDS.LET_LIMIT}.`,
|
|
40
|
+
location: { functionName: fn.name },
|
|
41
|
+
fix: 'Inline some let expressions into the return statement, or split the function.',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function checkChainDepth(functions, warnings) {
|
|
47
|
+
for (const fn of functions) {
|
|
48
|
+
const chain = deepestChain(fn.body);
|
|
49
|
+
// Also check let binding values for deep chains
|
|
50
|
+
for (const binding of fn.lets) {
|
|
51
|
+
const letChain = deepestChain(binding.value);
|
|
52
|
+
if (letChain.depth > chain.depth) {
|
|
53
|
+
chain.depth = letChain.depth;
|
|
54
|
+
chain.op = letChain.op;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (chain.depth >= THRESHOLDS.CHAIN_DEPTH_LIMIT) {
|
|
58
|
+
warnings.push({
|
|
59
|
+
rule: 'CHAIN_DEPTH',
|
|
60
|
+
severity: 'error',
|
|
61
|
+
message: `Function '${fn.name}' has a ${chain.op} chain of depth ${chain.depth}. Limit is ${THRESHOLDS.CHAIN_DEPTH_LIMIT}.`,
|
|
62
|
+
location: { functionName: fn.name },
|
|
63
|
+
fix: `Split into nested groups: 'a && b && c && d' → '(a && b) && (c && d)' to halve chain depth.`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (chain.depth >= THRESHOLDS.CHAIN_DEPTH_ERROR) {
|
|
67
|
+
warnings.push({
|
|
68
|
+
rule: 'CHAIN_DEPTH',
|
|
69
|
+
severity: 'error',
|
|
70
|
+
message: `Function '${fn.name}' has a ${chain.op} chain of depth ${chain.depth}. Limit is ${THRESHOLDS.CHAIN_DEPTH_LIMIT}. Approaching failure.`,
|
|
71
|
+
location: { functionName: fn.name },
|
|
72
|
+
fix: `Split the chain into nested groups to reduce depth.`,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else if (chain.depth >= THRESHOLDS.CHAIN_DEPTH_WARN) {
|
|
76
|
+
warnings.push({
|
|
77
|
+
rule: 'CHAIN_DEPTH',
|
|
78
|
+
severity: 'warning',
|
|
79
|
+
message: `Function '${fn.name}' has a ${chain.op} chain of depth ${chain.depth}. Limit is ${THRESHOLDS.CHAIN_DEPTH_LIMIT}.`,
|
|
80
|
+
location: { functionName: fn.name },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function checkSharedGates(rules, warnings) {
|
|
86
|
+
// Group allow update rules by match path
|
|
87
|
+
const byPath = new Map();
|
|
88
|
+
for (let i = 0; i < rules.length; i++) {
|
|
89
|
+
const r = rules[i];
|
|
90
|
+
// Only check update rules (most susceptible to budget issues)
|
|
91
|
+
if (!r.rule.operations.some(op => op === 'update' || op === 'write'))
|
|
92
|
+
continue;
|
|
93
|
+
const gate = expressionFingerprint(extractFirstExpression(r.rule.condition));
|
|
94
|
+
const path = r.path;
|
|
95
|
+
if (!byPath.has(path))
|
|
96
|
+
byPath.set(path, []);
|
|
97
|
+
byPath.get(path).push({ index: i, gate, ops: r.rule.operations });
|
|
98
|
+
}
|
|
99
|
+
for (const [path, entries] of byPath) {
|
|
100
|
+
const gateGroups = new Map();
|
|
101
|
+
for (const e of entries) {
|
|
102
|
+
if (!gateGroups.has(e.gate))
|
|
103
|
+
gateGroups.set(e.gate, []);
|
|
104
|
+
gateGroups.get(e.gate).push(e.index);
|
|
105
|
+
}
|
|
106
|
+
for (const [gate, indices] of gateGroups) {
|
|
107
|
+
if (indices.length >= 2) {
|
|
108
|
+
warnings.push({
|
|
109
|
+
rule: 'SHARED_GATE',
|
|
110
|
+
severity: 'warning',
|
|
111
|
+
message: `${indices.length} allow rules in '${path}' share the same gate expression. This may cause cross-rule budget exhaustion. Rules: ${indices.join(', ')}.`,
|
|
112
|
+
location: { matchPath: path },
|
|
113
|
+
fix: 'Assign unique moveType or discriminator values so each rule has a unique first expression.',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Count function calls and total expressions for a SINGLE rule's condition,
|
|
121
|
+
* following function calls transitively. Skips already-visited functions
|
|
122
|
+
* to avoid double-counting shared helpers (like cfg()).
|
|
123
|
+
*/
|
|
124
|
+
function estimateRuleBudget(condition, fnMap) {
|
|
125
|
+
let totalExprs = countExpressionNodes(condition);
|
|
126
|
+
const visited = new Set();
|
|
127
|
+
function walkForCalls(expr) {
|
|
128
|
+
if (expr.type === 'functionCall' && fnMap.has(expr.name) && !visited.has(expr.name)) {
|
|
129
|
+
visited.add(expr.name);
|
|
130
|
+
const fn = fnMap.get(expr.name);
|
|
131
|
+
totalExprs += countExpressionNodes(fn.body);
|
|
132
|
+
for (const b of fn.lets)
|
|
133
|
+
totalExprs += countExpressionNodes(b.value);
|
|
134
|
+
walkForCalls(fn.body);
|
|
135
|
+
for (const b of fn.lets)
|
|
136
|
+
walkForCalls(b.value);
|
|
137
|
+
}
|
|
138
|
+
// Walk children to find nested function calls
|
|
139
|
+
switch (expr.type) {
|
|
140
|
+
case 'binaryOp':
|
|
141
|
+
walkForCalls(expr.left);
|
|
142
|
+
walkForCalls(expr.right);
|
|
143
|
+
break;
|
|
144
|
+
case 'unaryOp':
|
|
145
|
+
walkForCalls(expr.operand);
|
|
146
|
+
break;
|
|
147
|
+
case 'methodCall':
|
|
148
|
+
walkForCalls(expr.object);
|
|
149
|
+
expr.args.forEach(walkForCalls);
|
|
150
|
+
break;
|
|
151
|
+
case 'memberAccess':
|
|
152
|
+
walkForCalls(expr.object);
|
|
153
|
+
break;
|
|
154
|
+
case 'bracketAccess':
|
|
155
|
+
walkForCalls(expr.object);
|
|
156
|
+
walkForCalls(expr.index);
|
|
157
|
+
break;
|
|
158
|
+
case 'ternary':
|
|
159
|
+
walkForCalls(expr.condition);
|
|
160
|
+
walkForCalls(expr.consequent);
|
|
161
|
+
walkForCalls(expr.alternate);
|
|
162
|
+
break;
|
|
163
|
+
case 'inExpr':
|
|
164
|
+
walkForCalls(expr.element);
|
|
165
|
+
walkForCalls(expr.collection);
|
|
166
|
+
break;
|
|
167
|
+
case 'isExpr':
|
|
168
|
+
walkForCalls(expr.value);
|
|
169
|
+
break;
|
|
170
|
+
case 'listLiteral':
|
|
171
|
+
expr.elements.forEach(walkForCalls);
|
|
172
|
+
break;
|
|
173
|
+
case 'mapLiteral':
|
|
174
|
+
expr.entries.forEach(e => { walkForCalls(e.key); walkForCalls(e.value); });
|
|
175
|
+
break;
|
|
176
|
+
case 'functionCall':
|
|
177
|
+
expr.args.forEach(walkForCalls);
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
walkForCalls(condition);
|
|
182
|
+
return { totalExprs, callCount: visited.size };
|
|
183
|
+
}
|
|
184
|
+
function checkExpressionBudget(rules, allFunctions, warnings) {
|
|
185
|
+
const fnMap = new Map();
|
|
186
|
+
for (const fn of allFunctions)
|
|
187
|
+
fnMap.set(fn.name, fn);
|
|
188
|
+
for (let i = 0; i < rules.length; i++) {
|
|
189
|
+
const { totalExprs, callCount } = estimateRuleBudget(rules[i].rule.condition, fnMap);
|
|
190
|
+
// The runtime budget depends on function call count.
|
|
191
|
+
// With unique gates (SHARED_GATE check handles this separately),
|
|
192
|
+
// only this rule's expressions are evaluated. The budget model
|
|
193
|
+
// accounts for per-call overhead making the available budget
|
|
194
|
+
// decrease with more calls.
|
|
195
|
+
//
|
|
196
|
+
// However, the total node count is a WORST-CASE estimate (assumes
|
|
197
|
+
// all branches evaluate). Firestore short-circuits && and ||.
|
|
198
|
+
// For rules with many OR branches where only 1 matches, the actual
|
|
199
|
+
// evaluated count is much lower than the tree size.
|
|
200
|
+
//
|
|
201
|
+
// To avoid false positives on rules with large but well-gated trees
|
|
202
|
+
// (like chess check detection with 16 OR branches), we use a
|
|
203
|
+
// conservative multiplier: if the rule has many OR branches at the
|
|
204
|
+
// top level, discount the estimate.
|
|
205
|
+
const topLevelOrs = maxChainDepth(rules[i].rule.condition, '||');
|
|
206
|
+
const discountFactor = topLevelOrs > 5 ? 0.3 : topLevelOrs > 2 ? 0.5 : 1.0;
|
|
207
|
+
const adjustedExprs = Math.round(totalExprs * discountFactor);
|
|
208
|
+
const budget = callCount <= THRESHOLDS.RUNTIME_BUDGET.low.calls
|
|
209
|
+
? THRESHOLDS.RUNTIME_BUDGET.low
|
|
210
|
+
: callCount <= THRESHOLDS.RUNTIME_BUDGET.mid.calls
|
|
211
|
+
? THRESHOLDS.RUNTIME_BUDGET.mid
|
|
212
|
+
: THRESHOLDS.RUNTIME_BUDGET.high;
|
|
213
|
+
// Expression budget is always a WARNING, never an error, because:
|
|
214
|
+
// 1. We count the full tree but Firestore short-circuits && and ||
|
|
215
|
+
// 2. The runtime budget is non-deterministic (has a flaky zone)
|
|
216
|
+
// 3. The actual evaluated expressions depend on data at runtime
|
|
217
|
+
// Hard structural errors (chain depth, let limit) catch compilation failures.
|
|
218
|
+
// This check catches POTENTIAL runtime issues as advisory warnings.
|
|
219
|
+
if (adjustedExprs >= budget.warn) {
|
|
220
|
+
warnings.push({
|
|
221
|
+
rule: 'EXPRESSION_BUDGET',
|
|
222
|
+
severity: 'warning',
|
|
223
|
+
message: `Rule #${i} has ~${totalExprs} expression nodes across ${callCount} function calls. Runtime budget is non-deterministic; actual evaluation depends on short-circuit behavior.`,
|
|
224
|
+
location: { ruleIndex: i },
|
|
225
|
+
fix: 'If this rule fails at runtime (403), reduce function calls or expression count.',
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function checkCallDepth(rules, allFunctions, warnings) {
|
|
231
|
+
const callGraph = buildCallGraph(allFunctions);
|
|
232
|
+
const fnMap = new Map();
|
|
233
|
+
for (const fn of allFunctions)
|
|
234
|
+
fnMap.set(fn.name, fn);
|
|
235
|
+
for (let i = 0; i < rules.length; i++) {
|
|
236
|
+
let maxDepth = 0;
|
|
237
|
+
const findDepth = (expr) => {
|
|
238
|
+
if (expr.type === 'functionCall' && fnMap.has(expr.name)) {
|
|
239
|
+
const depth = maxCallDepth(expr.name, callGraph);
|
|
240
|
+
if (depth > maxDepth)
|
|
241
|
+
maxDepth = depth;
|
|
242
|
+
}
|
|
243
|
+
switch (expr.type) {
|
|
244
|
+
case 'binaryOp':
|
|
245
|
+
findDepth(expr.left);
|
|
246
|
+
findDepth(expr.right);
|
|
247
|
+
break;
|
|
248
|
+
case 'unaryOp':
|
|
249
|
+
findDepth(expr.operand);
|
|
250
|
+
break;
|
|
251
|
+
case 'methodCall':
|
|
252
|
+
findDepth(expr.object);
|
|
253
|
+
expr.args.forEach(findDepth);
|
|
254
|
+
break;
|
|
255
|
+
case 'memberAccess':
|
|
256
|
+
findDepth(expr.object);
|
|
257
|
+
break;
|
|
258
|
+
case 'bracketAccess':
|
|
259
|
+
findDepth(expr.object);
|
|
260
|
+
findDepth(expr.index);
|
|
261
|
+
break;
|
|
262
|
+
case 'ternary':
|
|
263
|
+
findDepth(expr.condition);
|
|
264
|
+
findDepth(expr.consequent);
|
|
265
|
+
findDepth(expr.alternate);
|
|
266
|
+
break;
|
|
267
|
+
case 'inExpr':
|
|
268
|
+
findDepth(expr.element);
|
|
269
|
+
findDepth(expr.collection);
|
|
270
|
+
break;
|
|
271
|
+
case 'functionCall':
|
|
272
|
+
expr.args.forEach(findDepth);
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
findDepth(rules[i].rule.condition);
|
|
277
|
+
if (maxDepth >= THRESHOLDS.CALL_DEPTH_ERROR) {
|
|
278
|
+
warnings.push({
|
|
279
|
+
rule: 'CALL_DEPTH',
|
|
280
|
+
severity: 'error',
|
|
281
|
+
message: `Rule #${i} has a function call chain of depth ${maxDepth}. May exceed call budget.`,
|
|
282
|
+
location: { ruleIndex: i },
|
|
283
|
+
fix: 'Inline intermediate functions to reduce call depth.',
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
else if (maxDepth >= THRESHOLDS.CALL_DEPTH_WARN) {
|
|
287
|
+
warnings.push({
|
|
288
|
+
rule: 'CALL_DEPTH',
|
|
289
|
+
severity: 'warning',
|
|
290
|
+
message: `Rule #${i} has a function call chain of depth ${maxDepth}.`,
|
|
291
|
+
location: { ruleIndex: i },
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
function checkGetCount(rules, allFunctions, warnings) {
|
|
297
|
+
const fnMap = new Map();
|
|
298
|
+
for (const fn of allFunctions)
|
|
299
|
+
fnMap.set(fn.name, fn);
|
|
300
|
+
for (let i = 0; i < rules.length; i++) {
|
|
301
|
+
const count = countGetCalls(rules[i].rule.condition, fnMap);
|
|
302
|
+
if (count >= THRESHOLDS.GET_COUNT_ERROR) {
|
|
303
|
+
warnings.push({
|
|
304
|
+
rule: 'GET_COUNT',
|
|
305
|
+
severity: 'error',
|
|
306
|
+
message: `Rule #${i} may invoke ${count} get()/exists() calls. Limit is ${THRESHOLDS.GET_COUNT_ERROR}.`,
|
|
307
|
+
location: { ruleIndex: i },
|
|
308
|
+
fix: 'Cache get() results via a config() wrapper function. Same-path calls are cached by Firestore.',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
else if (count >= THRESHOLDS.GET_COUNT_WARN) {
|
|
312
|
+
warnings.push({
|
|
313
|
+
rule: 'GET_COUNT',
|
|
314
|
+
severity: 'warning',
|
|
315
|
+
message: `Rule #${i} invokes ${count} get()/exists() calls. Limit is ${THRESHOLDS.GET_COUNT_ERROR}.`,
|
|
316
|
+
location: { ruleIndex: i },
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function checkGetDuplication(rules, allFunctions, warnings) {
|
|
322
|
+
const fnMap = new Map();
|
|
323
|
+
for (const fn of allFunctions)
|
|
324
|
+
fnMap.set(fn.name, fn);
|
|
325
|
+
const fnNames = new Set(allFunctions.map(f => f.name));
|
|
326
|
+
for (let i = 0; i < rules.length; i++) {
|
|
327
|
+
const callCounts = countFunctionCallSites(rules[i].rule.condition, fnNames);
|
|
328
|
+
for (const [fnName, count] of callCounts) {
|
|
329
|
+
if (count >= 2 && functionContainsGet(fnName, fnMap)) {
|
|
330
|
+
warnings.push({
|
|
331
|
+
rule: 'GET_DUPLICATION',
|
|
332
|
+
severity: 'warning',
|
|
333
|
+
message: `Function '${fnName}' (contains get/exists) is called ${count} times in rule #${i}. Cache the result with a let binding in a wrapper function to reduce get() calls from ${count} to 1.`,
|
|
334
|
+
location: { ruleIndex: i },
|
|
335
|
+
fix: `Create a wrapper: function verifyAll(ret) { let c = ${fnName}(); return verify1(ret, c) && verify2(ret, c) && ...; }`,
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* REQUEST_TIME_NOT_PINNED — couples the static linter to the per-test data
|
|
343
|
+
* (REBUILD_PLAN.md Item 0.F deferred follow-up). When a rule transitively
|
|
344
|
+
* reads `request.time`, the rule's verdict depends on wallclock unless the
|
|
345
|
+
* test pins `requestTime`. Pre-fix, date-gated rules failed
|
|
346
|
+
* non-deterministically across CI runs and agents either gave up or
|
|
347
|
+
* hardcoded today's date.
|
|
348
|
+
*
|
|
349
|
+
* Emits one warning per affected (rule, test case) pair so the agent gets
|
|
350
|
+
* a precise checklist. Only fires when the caller passes a test suite —
|
|
351
|
+
* source-only `lintFirestoreRules(source)` calls are unaffected.
|
|
352
|
+
*/
|
|
353
|
+
function checkRequestTimePinned(rules, allFunctions, testCases, warnings) {
|
|
354
|
+
const fnMap = new Map();
|
|
355
|
+
for (const fn of allFunctions)
|
|
356
|
+
fnMap.set(fn.name, fn);
|
|
357
|
+
// Find which rule indices reference request.time. Per-rule rather than
|
|
358
|
+
// per-source so a test case targeting an unrelated match block isn't
|
|
359
|
+
// wrongly flagged.
|
|
360
|
+
const timeGatedRules = new Set();
|
|
361
|
+
for (let i = 0; i < rules.length; i++) {
|
|
362
|
+
if (referencesRequestTime(rules[i].rule.condition, fnMap)) {
|
|
363
|
+
timeGatedRules.add(i);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
if (timeGatedRules.size === 0)
|
|
367
|
+
return;
|
|
368
|
+
// Cheap match-path resolution: a test case at "users/alice" matches a
|
|
369
|
+
// rule whose match path is "users/{id}". Full path matching is the
|
|
370
|
+
// simulator/handler's job — here we just need a "could this rule fire
|
|
371
|
+
// for this test case?" estimate. Match by segment-count + literal-match.
|
|
372
|
+
function pathMatches(rulePath, tcPath) {
|
|
373
|
+
const ruleSegs = rulePath.split('/').filter(Boolean);
|
|
374
|
+
const tcSegs = tcPath.split('/').filter(Boolean);
|
|
375
|
+
if (ruleSegs.length !== tcSegs.length)
|
|
376
|
+
return false;
|
|
377
|
+
for (let i = 0; i < ruleSegs.length; i++) {
|
|
378
|
+
const rs = ruleSegs[i];
|
|
379
|
+
// Wildcard or recursive wildcard matches any segment.
|
|
380
|
+
if (rs.startsWith('{') && rs.endsWith('}'))
|
|
381
|
+
continue;
|
|
382
|
+
if (rs !== tcSegs[i])
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
for (const tc of testCases) {
|
|
388
|
+
if (tc.requestTime)
|
|
389
|
+
continue; // pinned — fine
|
|
390
|
+
for (const ruleIdx of timeGatedRules) {
|
|
391
|
+
if (!pathMatches(rules[ruleIdx].path, tc.path))
|
|
392
|
+
continue;
|
|
393
|
+
warnings.push({
|
|
394
|
+
rule: 'REQUEST_TIME_NOT_PINNED',
|
|
395
|
+
severity: 'warning',
|
|
396
|
+
message: `Test case "${tc.description}" targets rule #${ruleIdx} (path '${rules[ruleIdx].path}') which reads request.time, but does not set requestTime. Result is non-deterministic across runs.`,
|
|
397
|
+
location: { ruleIndex: ruleIdx, matchPath: rules[ruleIdx].path, testCaseDescription: tc.description },
|
|
398
|
+
fix: 'Set requestTime on this TestCase to an ISO-8601 timestamp so the rule evaluates deterministically.',
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* PERMISSIVE_RULE — `allow ... if true` (or any condition that statically
|
|
405
|
+
* resolves to the boolean literal `true`) disables security for the
|
|
406
|
+
* matched paths. Empirically the most common agent failure mode: when a
|
|
407
|
+
* targeted rule denies a write the agent doesn't understand, the easy
|
|
408
|
+
* escape is to write the predicate true. That ships an open collection.
|
|
409
|
+
*
|
|
410
|
+
* Severity is `error` so `deployRules` refuses to swap the ruleset — the
|
|
411
|
+
* agent has to fix the actual denial instead of widening the gate.
|
|
412
|
+
*
|
|
413
|
+
* Detection is deliberately conservative: we only fold `&&`/`||` over
|
|
414
|
+
* boolean literals and recognize the literal `true`. We do NOT try to
|
|
415
|
+
* prove `1 == 1` or follow function calls. A few false negatives are
|
|
416
|
+
* acceptable; a single false positive on a legitimate rule would break
|
|
417
|
+
* deploys.
|
|
418
|
+
*/
|
|
419
|
+
function evalConstBool(expr) {
|
|
420
|
+
if (expr.type === 'literal' && typeof expr.value === 'boolean')
|
|
421
|
+
return expr.value;
|
|
422
|
+
if (expr.type === 'binaryOp') {
|
|
423
|
+
const left = evalConstBool(expr.left);
|
|
424
|
+
const right = evalConstBool(expr.right);
|
|
425
|
+
if (expr.op === '&&') {
|
|
426
|
+
if (left === false || right === false)
|
|
427
|
+
return false;
|
|
428
|
+
if (left === true && right === true)
|
|
429
|
+
return true;
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
if (expr.op === '||') {
|
|
433
|
+
if (left === true || right === true)
|
|
434
|
+
return true;
|
|
435
|
+
if (left === false && right === false)
|
|
436
|
+
return false;
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
if (expr.type === 'unaryOp' && expr.op === '!') {
|
|
441
|
+
const inner = evalConstBool(expr.operand);
|
|
442
|
+
return inner === null ? null : !inner;
|
|
443
|
+
}
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
const WRITE_OPS = new Set([
|
|
447
|
+
'write', 'create', 'update', 'delete',
|
|
448
|
+
]);
|
|
449
|
+
function checkPermissiveRules(rules, warnings) {
|
|
450
|
+
for (let i = 0; i < rules.length; i++) {
|
|
451
|
+
const r = rules[i];
|
|
452
|
+
if (evalConstBool(r.rule.condition) !== true)
|
|
453
|
+
continue;
|
|
454
|
+
// `allow read: if true` is a legitimate "public read" pattern (e.g.
|
|
455
|
+
// a shared config doc). Only flag when the rule grants any write
|
|
456
|
+
// capability — that's where `if true` actually disables security.
|
|
457
|
+
const grantsWrite = r.rule.operations.some((op) => WRITE_OPS.has(op));
|
|
458
|
+
if (!grantsWrite)
|
|
459
|
+
continue;
|
|
460
|
+
const ops = r.rule.operations.join(', ');
|
|
461
|
+
warnings.push({
|
|
462
|
+
rule: 'PERMISSIVE_RULE',
|
|
463
|
+
// Severity: warning, not error. Rationale: `allow write: if true`
|
|
464
|
+
// is the canonical dev/sandbox/quickstart pattern; classifying it
|
|
465
|
+
// as a hard error caused `sandbox.setRules(...)` to silently no-op
|
|
466
|
+
// and the scaffolded `pyric init` quickstart to break in confusing
|
|
467
|
+
// ways. The diagnostic itself stays — production deploy gates
|
|
468
|
+
// (`pyric deploy rules`) can re-run lint at a stricter level and
|
|
469
|
+
// refuse on warning-too. The dev-loop sandbox stays permissive.
|
|
470
|
+
severity: 'warning',
|
|
471
|
+
message: `allow ${ops} at ${r.path} resolves to a constant true predicate — `
|
|
472
|
+
+ `this disables write security for the matched paths. If you reached `
|
|
473
|
+
+ `for \`if true\` to escape a denial you don't understand, narrow `
|
|
474
|
+
+ `the predicate to the specific request shape instead (auth identity, `
|
|
475
|
+
+ `affected fields via diff, status transitions).`,
|
|
476
|
+
location: { ruleIndex: i, matchPath: r.path },
|
|
477
|
+
fix: 'Replace the always-true predicate with a request-shape check (e.g. request.auth != null && request.resource.data.ownerId == request.auth.uid).',
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* RECURSIVE_WILDCARD_OPEN — `match /{x=**} { allow read, write: if true }`
|
|
483
|
+
* is the most permissive ruleset Firebase will accept. Distinct from
|
|
484
|
+
* PERMISSIVE_RULE so the agent gets a specifically named diagnostic; the
|
|
485
|
+
* recursive-wildcard form is what the playground trace ended up at after
|
|
486
|
+
* the agent gave up debugging.
|
|
487
|
+
*
|
|
488
|
+
* Fires only when the path uses the recursive form AND the predicate
|
|
489
|
+
* folds to constant true — a recursive wildcard with a real predicate
|
|
490
|
+
* (e.g. `if request.auth.uid == userId`) is a legitimate pattern.
|
|
491
|
+
*/
|
|
492
|
+
function checkRecursiveWildcardOpen(match, warnings) {
|
|
493
|
+
const hasRecursive = match.path.segments.some((s) => s.type === 'recursive');
|
|
494
|
+
if (hasRecursive) {
|
|
495
|
+
for (let i = 0; i < match.allows.length; i++) {
|
|
496
|
+
if (evalConstBool(match.allows[i].condition) === true) {
|
|
497
|
+
warnings.push({
|
|
498
|
+
rule: 'RECURSIVE_WILDCARD_OPEN',
|
|
499
|
+
severity: 'error',
|
|
500
|
+
message: `Recursive wildcard match (${match.path.raw}) with an always-true `
|
|
501
|
+
+ `predicate exposes every document under this prefix. This is the `
|
|
502
|
+
+ `Firebase open-rules anti-pattern — never ship it.`,
|
|
503
|
+
location: { ruleIndex: i, matchPath: match.path.raw },
|
|
504
|
+
fix: 'Either narrow the match path to specific collections, or replace `if true` with a real predicate (auth identity, ownership, role).',
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
for (const child of match.children)
|
|
510
|
+
checkRecursiveWildcardOpen(child, warnings);
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* RULES_WEAKENED — when a previous ruleset is supplied, flag every
|
|
514
|
+
* security predicate that the new ruleset has *removed*. Catches the
|
|
515
|
+
* agent failure mode where a denial is silently escaped by deleting the
|
|
516
|
+
* predicate (or whole rule, or whole match block) rather than fixing
|
|
517
|
+
* the request.
|
|
518
|
+
*
|
|
519
|
+
* Severity is `warning` (not `error`) — there are legitimate reasons to
|
|
520
|
+
* remove a predicate (refactor, dedupe), so this is advisory and does
|
|
521
|
+
* not block deploys. The agent has to decide whether the removal is
|
|
522
|
+
* intentional.
|
|
523
|
+
*
|
|
524
|
+
* Conjunct extraction: walk the predicate tree splitting on top-level
|
|
525
|
+
* `&&` only. We do NOT descend into `||` branches — splitting an OR
|
|
526
|
+
* would change semantics, so we treat the entire OR sub-tree as one
|
|
527
|
+
* conjunct. Each conjunct is normalized to a canonical string and
|
|
528
|
+
* compared as a set. Removed conjuncts → warnings; added/changed
|
|
529
|
+
* conjuncts → silence (refinement is fine).
|
|
530
|
+
*/
|
|
531
|
+
/** Normalize a path segment for cross-ruleset comparison. Wildcards
|
|
532
|
+
* compare equal regardless of their binding name. */
|
|
533
|
+
function normalizePathSegment(seg) {
|
|
534
|
+
if (seg.type === 'literal')
|
|
535
|
+
return seg.value ?? '';
|
|
536
|
+
if (seg.type === 'wildcard')
|
|
537
|
+
return '{*}';
|
|
538
|
+
if (seg.type === 'recursive')
|
|
539
|
+
return '{**}';
|
|
540
|
+
return '';
|
|
541
|
+
}
|
|
542
|
+
/** Build the full normalized path from root to this match block by
|
|
543
|
+
* joining every ancestor's segments with '/'. */
|
|
544
|
+
function buildMatchPathChain(segments) {
|
|
545
|
+
return segments.map(normalizePathSegment).join('/');
|
|
546
|
+
}
|
|
547
|
+
/** Walk the AST and yield every match block with its full normalized
|
|
548
|
+
* path (concatenated from root). The leaf `MatchBlock.path.raw` only
|
|
549
|
+
* reflects the local segment, which collides across siblings. */
|
|
550
|
+
function collectMatchBlocksWithPaths(match, parentPath) {
|
|
551
|
+
const localPath = buildMatchPathChain(match.path.segments);
|
|
552
|
+
const fullPath = parentPath ? `${parentPath}/${localPath}` : localPath;
|
|
553
|
+
const out = [
|
|
554
|
+
{ block: match, normalizedPath: fullPath },
|
|
555
|
+
];
|
|
556
|
+
for (const child of match.children) {
|
|
557
|
+
out.push(...collectMatchBlocksWithPaths(child, fullPath));
|
|
558
|
+
}
|
|
559
|
+
return out;
|
|
560
|
+
}
|
|
561
|
+
/** Deterministic serializer producing the same string for structurally
|
|
562
|
+
* identical expressions. No surrounding whitespace; no parens (the
|
|
563
|
+
* structure of nested binaryOp nodes already encodes precedence). */
|
|
564
|
+
function serializeExpression(expr) {
|
|
565
|
+
switch (expr.type) {
|
|
566
|
+
case 'literal':
|
|
567
|
+
return expr.raw;
|
|
568
|
+
case 'identifier':
|
|
569
|
+
return expr.name;
|
|
570
|
+
case 'memberAccess':
|
|
571
|
+
return `${serializeExpression(expr.object)}.${expr.property}`;
|
|
572
|
+
case 'methodCall':
|
|
573
|
+
return `${serializeExpression(expr.object)}.${expr.method}(${expr.args.map(serializeExpression).join(',')})`;
|
|
574
|
+
case 'bracketAccess':
|
|
575
|
+
return `${serializeExpression(expr.object)}[${serializeExpression(expr.index)}]`;
|
|
576
|
+
case 'sliceAccess':
|
|
577
|
+
return `${serializeExpression(expr.object)}[${serializeExpression(expr.start)}:${serializeExpression(expr.end)}]`;
|
|
578
|
+
case 'binaryOp':
|
|
579
|
+
return `(${serializeExpression(expr.left)}${expr.op}${serializeExpression(expr.right)})`;
|
|
580
|
+
case 'unaryOp':
|
|
581
|
+
return `(${expr.op}${serializeExpression(expr.operand)})`;
|
|
582
|
+
case 'ternary':
|
|
583
|
+
return `(${serializeExpression(expr.condition)}?${serializeExpression(expr.consequent)}:${serializeExpression(expr.alternate)})`;
|
|
584
|
+
case 'inExpr':
|
|
585
|
+
return `(${serializeExpression(expr.element)} in ${serializeExpression(expr.collection)})`;
|
|
586
|
+
case 'isExpr':
|
|
587
|
+
return `(${serializeExpression(expr.value)} is ${expr.typeName})`;
|
|
588
|
+
case 'listLiteral':
|
|
589
|
+
return `[${expr.elements.map(serializeExpression).join(',')}]`;
|
|
590
|
+
case 'mapLiteral':
|
|
591
|
+
return `{${expr.entries.map((e) => `${serializeExpression(e.key)}:${serializeExpression(e.value)}`).join(',')}}`;
|
|
592
|
+
case 'pathLiteral':
|
|
593
|
+
return expr.raw;
|
|
594
|
+
case 'functionCall':
|
|
595
|
+
return `${expr.name}(${expr.args.map(serializeExpression).join(',')})`;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/** Split a predicate into its top-level conjuncts (split only on `&&`).
|
|
599
|
+
* An `||` sub-tree is preserved as a single conjunct so we don't
|
|
600
|
+
* change semantics by treating one of its branches as removable. */
|
|
601
|
+
function extractConjuncts(expr) {
|
|
602
|
+
if (expr.type === 'binaryOp' && expr.op === '&&') {
|
|
603
|
+
return [...extractConjuncts(expr.left), ...extractConjuncts(expr.right)];
|
|
604
|
+
}
|
|
605
|
+
return [expr];
|
|
606
|
+
}
|
|
607
|
+
function checkRulesWeakened(currentMatch, previousMatch, warnings) {
|
|
608
|
+
const currentBlocks = collectMatchBlocksWithPaths(currentMatch, '');
|
|
609
|
+
const previousBlocks = collectMatchBlocksWithPaths(previousMatch, '');
|
|
610
|
+
const currentByPath = new Map();
|
|
611
|
+
for (const { block, normalizedPath } of currentBlocks) {
|
|
612
|
+
// If duplicate paths exist (rare but possible with sibling literal
|
|
613
|
+
// matches reused), keep the first — comparing the first occurrence
|
|
614
|
+
// is sufficient for "did this path lose predicates?"
|
|
615
|
+
if (!currentByPath.has(normalizedPath))
|
|
616
|
+
currentByPath.set(normalizedPath, block);
|
|
617
|
+
}
|
|
618
|
+
for (const { block: prevBlock, normalizedPath } of previousBlocks) {
|
|
619
|
+
const curBlock = currentByPath.get(normalizedPath);
|
|
620
|
+
if (!curBlock) {
|
|
621
|
+
// Whole match block disappeared. Only emit when the previous
|
|
622
|
+
// block actually had allow rules — a parent shell with no allows
|
|
623
|
+
// disappearing tells the agent nothing.
|
|
624
|
+
if (prevBlock.allows.length > 0) {
|
|
625
|
+
warnings.push({
|
|
626
|
+
rule: 'RULES_WEAKENED',
|
|
627
|
+
severity: 'warning',
|
|
628
|
+
message: `Match block removed: ${normalizedPath}`,
|
|
629
|
+
location: { matchPath: normalizedPath },
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
// For each previous allow rule, find the corresponding current
|
|
635
|
+
// allow rule by op-set equality.
|
|
636
|
+
for (const prevAllow of prevBlock.allows) {
|
|
637
|
+
const opsKey = [...prevAllow.operations].sort().join(',');
|
|
638
|
+
const curAllow = curBlock.allows.find((a) => [...a.operations].sort().join(',') === opsKey);
|
|
639
|
+
const opsLabel = prevAllow.operations.join(', ');
|
|
640
|
+
if (!curAllow) {
|
|
641
|
+
warnings.push({
|
|
642
|
+
rule: 'RULES_WEAKENED',
|
|
643
|
+
severity: 'warning',
|
|
644
|
+
message: `Allow rule removed: ${normalizedPath} allow ${opsLabel}`,
|
|
645
|
+
location: { matchPath: normalizedPath },
|
|
646
|
+
});
|
|
647
|
+
continue;
|
|
648
|
+
}
|
|
649
|
+
// Diff the conjunct sets.
|
|
650
|
+
const prevConjuncts = extractConjuncts(prevAllow.condition).map(serializeExpression);
|
|
651
|
+
const curConjuncts = new Set(extractConjuncts(curAllow.condition).map(serializeExpression));
|
|
652
|
+
for (const pc of prevConjuncts) {
|
|
653
|
+
if (!curConjuncts.has(pc)) {
|
|
654
|
+
warnings.push({
|
|
655
|
+
rule: 'RULES_WEAKENED',
|
|
656
|
+
severity: 'warning',
|
|
657
|
+
message: `Predicate removed from ${normalizedPath} allow ${opsLabel}: ${pc}`,
|
|
658
|
+
location: { matchPath: normalizedPath },
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Lint Firestore security rules.
|
|
667
|
+
*
|
|
668
|
+
* Contract: if the source doesn't parse, `parseError` is populated and
|
|
669
|
+
* budget checks are skipped — `warnings` will be empty (or contain only
|
|
670
|
+
* source-size which doesn't depend on parsing) and `metrics` fields other
|
|
671
|
+
* than `sourceSize` are zeroed. Callers must check `parseError` first.
|
|
672
|
+
*
|
|
673
|
+
* Pass `options.testCases` to activate test-suite-coupled checks (e.g.
|
|
674
|
+
* REQUEST_TIME_NOT_PINNED). When omitted, the linter behaves exactly as
|
|
675
|
+
* it did before — back-compat with all existing callers.
|
|
676
|
+
*/
|
|
677
|
+
export function lintFirestoreRules(source, options = {}) {
|
|
678
|
+
const warnings = [];
|
|
679
|
+
// Pre-parse syntax hints — run on raw source so they fire even when the
|
|
680
|
+
// rules fail to parse. Surface JS-isms (===, ?., ??, backtick strings)
|
|
681
|
+
// that would otherwise produce opaque parse errors.
|
|
682
|
+
warnings.push(...checkSyntaxHints(source));
|
|
683
|
+
// Rule 1: Source size — runs even on unparseable source so a 300KB blob
|
|
684
|
+
// of garbage still surfaces the size error.
|
|
685
|
+
checkSourceSize(source, warnings);
|
|
686
|
+
// Parse AST. On failure, return early with a structured parseError;
|
|
687
|
+
// budget checks intentionally do not run on partial ASTs.
|
|
688
|
+
const parsed = parseToASTOrError(source);
|
|
689
|
+
if (!parsed.ok) {
|
|
690
|
+
return {
|
|
691
|
+
warnings,
|
|
692
|
+
metrics: {
|
|
693
|
+
sourceSize: source.length, functionCount: 0, allowRuleCount: 0,
|
|
694
|
+
maxChainDepth: 0, maxChainOp: '', maxLetBindings: 0, maxLetBindingsFunction: '',
|
|
695
|
+
maxCallDepth: 0, maxEstimatedExpressions: 0, getCallCount: 0,
|
|
696
|
+
},
|
|
697
|
+
parseError: parsed.error,
|
|
698
|
+
};
|
|
699
|
+
}
|
|
700
|
+
const ast = parsed.ast;
|
|
701
|
+
// Collect all functions and rules from the AST
|
|
702
|
+
const allFunctions = collectAllFunctions(ast.service.match);
|
|
703
|
+
const allRules = collectAllRules(ast.service.match);
|
|
704
|
+
// Rule 2: Chain depth
|
|
705
|
+
checkChainDepth(allFunctions, warnings);
|
|
706
|
+
// Rule 3: Let bindings
|
|
707
|
+
checkLetBindings(allFunctions, warnings);
|
|
708
|
+
// Rule 4: Shared gates
|
|
709
|
+
checkSharedGates(allRules, warnings);
|
|
710
|
+
// Rule 5: Expression budget
|
|
711
|
+
checkExpressionBudget(allRules, allFunctions, warnings);
|
|
712
|
+
// Rule 6: Call depth
|
|
713
|
+
checkCallDepth(allRules, allFunctions, warnings);
|
|
714
|
+
// Rule 7: Get count
|
|
715
|
+
checkGetCount(allRules, allFunctions, warnings);
|
|
716
|
+
// Rule 8: Get duplication (same get()-containing function called multiple times)
|
|
717
|
+
checkGetDuplication(allRules, allFunctions, warnings);
|
|
718
|
+
// Rule 9: Hallucinations — JS-style code that parses but fails at runtime
|
|
719
|
+
warnings.push(...checkHallucinations(ast));
|
|
720
|
+
// Rule 9.5: Always-true predicates and recursive-wildcard open rules.
|
|
721
|
+
// Severity: error so deployRules refuses to swap. The agent's #1
|
|
722
|
+
// failure mode in the playground was escaping denials with `if true`.
|
|
723
|
+
checkPermissiveRules(allRules, warnings);
|
|
724
|
+
checkRecursiveWildcardOpen(ast.service.match, warnings);
|
|
725
|
+
// Rule 10: request.time without pinned TestCase.requestTime
|
|
726
|
+
// (Item 0.F deferred follow-up). Only fires when caller passes a test suite.
|
|
727
|
+
if (options.testCases && options.testCases.length > 0) {
|
|
728
|
+
checkRequestTimePinned(allRules, allFunctions, options.testCases, warnings);
|
|
729
|
+
}
|
|
730
|
+
// Rule 11: RULES_WEAKENED — diff against the previously deployed
|
|
731
|
+
// ruleset to catch silently-removed security predicates. Only runs
|
|
732
|
+
// when the caller supplies `previousSource` AND it parses cleanly.
|
|
733
|
+
// A malformed previous ruleset is silently skipped — the current
|
|
734
|
+
// ruleset is still valid and we don't want to fail open.
|
|
735
|
+
if (options.previousSource) {
|
|
736
|
+
const prev = parseToASTOrError(options.previousSource);
|
|
737
|
+
if (prev.ok) {
|
|
738
|
+
checkRulesWeakened(ast.service.match, prev.ast.service.match, warnings);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
// Compute metrics
|
|
742
|
+
let maxChain = { depth: 0, op: '' };
|
|
743
|
+
let maxLets = { count: 0, fn: '' };
|
|
744
|
+
for (const fn of allFunctions) {
|
|
745
|
+
const chain = deepestChain(fn.body);
|
|
746
|
+
if (chain.depth > maxChain.depth)
|
|
747
|
+
maxChain = { depth: chain.depth, op: chain.op };
|
|
748
|
+
if (fn.lets.length > maxLets.count)
|
|
749
|
+
maxLets = { count: fn.lets.length, fn: fn.name };
|
|
750
|
+
}
|
|
751
|
+
const callGraph = buildCallGraph(allFunctions);
|
|
752
|
+
let maxDepth = 0;
|
|
753
|
+
for (const fn of allFunctions) {
|
|
754
|
+
const d = maxCallDepth(fn.name, callGraph);
|
|
755
|
+
if (d > maxDepth)
|
|
756
|
+
maxDepth = d;
|
|
757
|
+
}
|
|
758
|
+
const fnMap = new Map();
|
|
759
|
+
for (const fn of allFunctions)
|
|
760
|
+
fnMap.set(fn.name, fn);
|
|
761
|
+
let maxExprs = 0;
|
|
762
|
+
let maxGets = 0;
|
|
763
|
+
for (const r of allRules) {
|
|
764
|
+
const gets = countGetCalls(r.rule.condition, fnMap);
|
|
765
|
+
if (gets > maxGets)
|
|
766
|
+
maxGets = gets;
|
|
767
|
+
}
|
|
768
|
+
return {
|
|
769
|
+
warnings,
|
|
770
|
+
metrics: {
|
|
771
|
+
sourceSize: source.length,
|
|
772
|
+
functionCount: allFunctions.length,
|
|
773
|
+
allowRuleCount: allRules.length,
|
|
774
|
+
maxChainDepth: maxChain.depth,
|
|
775
|
+
maxChainOp: maxChain.op,
|
|
776
|
+
maxLetBindings: maxLets.count,
|
|
777
|
+
maxLetBindingsFunction: maxLets.fn,
|
|
778
|
+
maxCallDepth: maxDepth,
|
|
779
|
+
maxEstimatedExpressions: maxExprs,
|
|
780
|
+
getCallCount: maxGets,
|
|
781
|
+
},
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
//# sourceMappingURL=linter.js.map
|