@ttt-productions/repo-guards 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/guard.d.ts +2 -2
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/modules/backend/audit.d.ts +2 -2
- package/dist/modules/backend/audit.d.ts.map +1 -1
- package/dist/modules/backend/audit.js +68 -19
- package/dist/modules/backend/audit.js.map +1 -1
- package/dist/modules/backend/auth.d.ts +2 -2
- package/dist/modules/backend/auth.d.ts.map +1 -1
- package/dist/modules/backend/auth.js +123 -32
- package/dist/modules/backend/auth.js.map +1 -1
- package/dist/modules/backend/failure-handling.d.ts +1 -1
- package/dist/modules/backend/failure-handling.d.ts.map +1 -1
- package/dist/modules/backend/failure-handling.js +91 -23
- package/dist/modules/backend/failure-handling.js.map +1 -1
- package/dist/modules/backend/functions-build.d.ts +10 -6
- package/dist/modules/backend/functions-build.d.ts.map +1 -1
- package/dist/modules/backend/functions-build.js +214 -68
- package/dist/modules/backend/functions-build.js.map +1 -1
- package/dist/modules/backend/{index.d.ts → guards.d.ts} +2 -3
- package/dist/modules/backend/guards.d.ts.map +1 -0
- package/dist/modules/backend/{index.js → guards.js} +1 -1
- package/dist/modules/backend/guards.js.map +1 -0
- package/dist/modules/backend/monitoring.d.ts +2 -2
- package/dist/modules/backend/monitoring.d.ts.map +1 -1
- package/dist/modules/backend/monitoring.js +119 -31
- package/dist/modules/backend/monitoring.js.map +1 -1
- package/dist/modules/backend/shared.d.ts.map +1 -1
- package/dist/modules/backend/shared.js.map +1 -1
- package/dist/modules/core-definitions/contracts.d.ts +2 -2
- package/dist/modules/core-definitions/contracts.d.ts.map +1 -1
- package/dist/modules/core-definitions/contracts.js +32 -8
- package/dist/modules/core-definitions/contracts.js.map +1 -1
- package/dist/modules/core-definitions/document-id-segment.d.ts +4 -1
- package/dist/modules/core-definitions/document-id-segment.d.ts.map +1 -1
- package/dist/modules/core-definitions/document-id-segment.js +106 -18
- package/dist/modules/core-definitions/document-id-segment.js.map +1 -1
- package/dist/modules/core-definitions/{index.d.ts → guards.d.ts} +2 -3
- package/dist/modules/core-definitions/guards.d.ts.map +1 -0
- package/dist/modules/core-definitions/{index.js → guards.js} +5 -5
- package/dist/modules/core-definitions/guards.js.map +1 -0
- package/dist/modules/core-definitions/redeclaration.d.ts +1 -1
- package/dist/modules/core-definitions/redeclaration.d.ts.map +1 -1
- package/dist/modules/core-definitions/redeclaration.js +53 -14
- package/dist/modules/core-definitions/redeclaration.js.map +1 -1
- package/dist/modules/core-definitions/schema-length-literal.d.ts +1 -1
- package/dist/modules/core-definitions/schema-length-literal.d.ts.map +1 -1
- package/dist/modules/core-definitions/schema-length-literal.js +25 -6
- package/dist/modules/core-definitions/schema-length-literal.js.map +1 -1
- package/dist/modules/core-definitions/shared.d.ts +1 -1
- package/dist/modules/core-definitions/shared.d.ts.map +1 -1
- package/dist/modules/core-definitions/shared.js +20 -5
- package/dist/modules/core-definitions/shared.js.map +1 -1
- package/dist/modules/core-definitions/singleton-bucket-audience.d.ts +2 -2
- package/dist/modules/core-definitions/singleton-bucket-audience.d.ts.map +1 -1
- package/dist/modules/core-definitions/singleton-bucket-audience.js +12 -3
- package/dist/modules/core-definitions/singleton-bucket-audience.js.map +1 -1
- package/dist/modules/core-definitions/text-field-declarations.d.ts +1 -1
- package/dist/modules/core-definitions/text-field-declarations.d.ts.map +1 -1
- package/dist/modules/core-definitions/text-field-declarations.js +81 -22
- package/dist/modules/core-definitions/text-field-declarations.js.map +1 -1
- package/dist/modules/firestore/analyzer.d.ts +1 -1
- package/dist/modules/firestore/analyzer.d.ts.map +1 -1
- package/dist/modules/firestore/analyzer.js +370 -115
- package/dist/modules/firestore/analyzer.js.map +1 -1
- package/dist/modules/firestore/client-guards.d.ts +2 -2
- package/dist/modules/firestore/client-guards.d.ts.map +1 -1
- package/dist/modules/firestore/client-guards.js +21 -5
- package/dist/modules/firestore/client-guards.js.map +1 -1
- package/dist/modules/firestore/guard.d.ts +4 -4
- package/dist/modules/firestore/guard.d.ts.map +1 -1
- package/dist/modules/firestore/guard.js +33 -11
- package/dist/modules/firestore/guard.js.map +1 -1
- package/dist/modules/firestore/{index.d.ts → guards.d.ts} +2 -5
- package/dist/modules/firestore/guards.d.ts.map +1 -0
- package/dist/modules/firestore/{index.js → guards.js} +3 -5
- package/dist/modules/firestore/guards.js.map +1 -0
- package/dist/modules/firestore/index-guard.d.ts +1 -1
- package/dist/modules/firestore/index-guard.d.ts.map +1 -1
- package/dist/modules/firestore/index-guard.js +35 -9
- package/dist/modules/firestore/index-guard.js.map +1 -1
- package/dist/modules/firestore/path-guards.d.ts +2 -2
- package/dist/modules/firestore/path-guards.d.ts.map +1 -1
- package/dist/modules/firestore/path-guards.js +35 -10
- package/dist/modules/firestore/path-guards.js.map +1 -1
- package/dist/modules/firestore/rules-claim-guard.d.ts +1 -1
- package/dist/modules/firestore/rules-claim-guard.d.ts.map +1 -1
- package/dist/modules/firestore/rules-claim-guard.js +42 -9
- package/dist/modules/firestore/rules-claim-guard.js.map +1 -1
- package/dist/modules/firestore/rules-mirror-guard.d.ts +1 -1
- package/dist/modules/firestore/rules-mirror-guard.d.ts.map +1 -1
- package/dist/modules/firestore/rules-mirror-guard.js +123 -26
- package/dist/modules/firestore/rules-mirror-guard.js.map +1 -1
- package/dist/modules/firestore/rules-syntax.d.ts.map +1 -1
- package/dist/modules/firestore/rules-syntax.js +12 -2
- package/dist/modules/firestore/rules-syntax.js.map +1 -1
- package/dist/modules/firestore/rules-tokens.d.ts.map +1 -1
- package/dist/modules/firestore/rules-tokens.js.map +1 -1
- package/dist/modules/firestore/server-guards.d.ts +2 -2
- package/dist/modules/firestore/server-guards.d.ts.map +1 -1
- package/dist/modules/firestore/server-guards.js +35 -9
- package/dist/modules/firestore/server-guards.js.map +1 -1
- package/dist/modules/firestore/storage-guards.d.ts +1 -1
- package/dist/modules/firestore/storage-guards.d.ts.map +1 -1
- package/dist/modules/firestore/storage-guards.js +41 -12
- package/dist/modules/firestore/storage-guards.js.map +1 -1
- package/dist/modules/firestore/support.d.ts +1 -1
- package/dist/modules/firestore/support.d.ts.map +1 -1
- package/dist/modules/firestore/support.js.map +1 -1
- package/dist/modules/firestore/test-paths.d.ts.map +1 -1
- package/dist/modules/firestore/test-paths.js +11 -3
- package/dist/modules/firestore/test-paths.js.map +1 -1
- package/dist/modules/frontend-actions/auth.d.ts +2 -2
- package/dist/modules/frontend-actions/auth.d.ts.map +1 -1
- package/dist/modules/frontend-actions/auth.js +84 -22
- package/dist/modules/frontend-actions/auth.js.map +1 -1
- package/dist/modules/frontend-actions/callables.d.ts +1 -1
- package/dist/modules/frontend-actions/callables.d.ts.map +1 -1
- package/dist/modules/frontend-actions/callables.js +103 -28
- package/dist/modules/frontend-actions/callables.js.map +1 -1
- package/dist/modules/frontend-actions/client.d.ts +2 -2
- package/dist/modules/frontend-actions/client.d.ts.map +1 -1
- package/dist/modules/frontend-actions/client.js +102 -25
- package/dist/modules/frontend-actions/client.js.map +1 -1
- package/dist/modules/frontend-actions/declarations.d.ts.map +1 -1
- package/dist/modules/frontend-actions/declarations.js +52 -12
- package/dist/modules/frontend-actions/declarations.js.map +1 -1
- package/dist/modules/frontend-actions/{index.d.ts → guards.d.ts} +2 -2
- package/dist/modules/frontend-actions/guards.d.ts.map +1 -0
- package/dist/modules/frontend-actions/{index.js → guards.js} +1 -1
- package/dist/modules/frontend-actions/guards.js.map +1 -0
- package/dist/modules/frontend-actions/text.d.ts.map +1 -1
- package/dist/modules/frontend-actions/text.js.map +1 -1
- package/dist/modules/frontend-reads/cache.d.ts +1 -1
- package/dist/modules/frontend-reads/cache.d.ts.map +1 -1
- package/dist/modules/frontend-reads/cache.js +131 -34
- package/dist/modules/frontend-reads/cache.js.map +1 -1
- package/dist/modules/frontend-reads/{index.d.ts → guards.d.ts} +2 -2
- package/dist/modules/frontend-reads/guards.d.ts.map +1 -0
- package/dist/modules/frontend-reads/{index.js → guards.js} +1 -1
- package/dist/modules/frontend-reads/guards.js.map +1 -0
- package/dist/modules/frontend-reads/query-keys.d.ts +1 -1
- package/dist/modules/frontend-reads/query-keys.d.ts.map +1 -1
- package/dist/modules/frontend-reads/query-keys.js +65 -15
- package/dist/modules/frontend-reads/query-keys.js.map +1 -1
- package/dist/modules/frontend-reads/read-failures.d.ts +2 -2
- package/dist/modules/frontend-reads/read-failures.d.ts.map +1 -1
- package/dist/modules/frontend-reads/read-failures.js +170 -46
- package/dist/modules/frontend-reads/read-failures.js.map +1 -1
- package/dist/modules/frontend-reads/shared.d.ts +1 -1
- package/dist/modules/frontend-reads/shared.d.ts.map +1 -1
- package/dist/modules/frontend-reads/shared.js +23 -8
- package/dist/modules/frontend-reads/shared.js.map +1 -1
- package/dist/modules/import-paths/analyzer.d.ts +57 -1
- package/dist/modules/import-paths/analyzer.d.ts.map +1 -1
- package/dist/modules/import-paths/analyzer.js +384 -27
- package/dist/modules/import-paths/analyzer.js.map +1 -1
- package/dist/modules/import-paths/application-data.d.ts +9 -0
- package/dist/modules/import-paths/application-data.d.ts.map +1 -0
- package/dist/modules/import-paths/application-data.js +98 -0
- package/dist/modules/import-paths/application-data.js.map +1 -0
- package/dist/modules/import-paths/entry-purity.d.ts +20 -0
- package/dist/modules/import-paths/entry-purity.d.ts.map +1 -0
- package/dist/modules/import-paths/entry-purity.js +306 -0
- package/dist/modules/import-paths/entry-purity.js.map +1 -0
- package/dist/modules/import-paths/guard.d.ts +2 -2
- package/dist/modules/import-paths/guard.d.ts.map +1 -1
- package/dist/modules/import-paths/guard.js +7 -2
- package/dist/modules/import-paths/guard.js.map +1 -1
- package/dist/modules/import-paths/guards.d.ts +18 -0
- package/dist/modules/import-paths/guards.d.ts.map +1 -0
- package/dist/modules/import-paths/guards.js +16 -0
- package/dist/modules/import-paths/guards.js.map +1 -0
- package/dist/modules/import-paths/package-entries.d.ts +46 -0
- package/dist/modules/import-paths/package-entries.d.ts.map +1 -0
- package/dist/modules/import-paths/package-entries.js +298 -0
- package/dist/modules/import-paths/package-entries.js.map +1 -0
- package/dist/modules/import-paths/package-imports.d.ts +8 -0
- package/dist/modules/import-paths/package-imports.d.ts.map +1 -0
- package/dist/modules/import-paths/package-imports.js +122 -0
- package/dist/modules/import-paths/package-imports.js.map +1 -0
- package/dist/modules/repo/ci-parity.d.ts +1 -1
- package/dist/modules/repo/ci-parity.d.ts.map +1 -1
- package/dist/modules/repo/ci-parity.js +12 -3
- package/dist/modules/repo/ci-parity.js.map +1 -1
- package/dist/modules/repo/cross-root.d.ts +2 -2
- package/dist/modules/repo/cross-root.d.ts.map +1 -1
- package/dist/modules/repo/cross-root.js +64 -16
- package/dist/modules/repo/cross-root.js.map +1 -1
- package/dist/modules/repo/dependency-overrides.d.ts +1 -1
- package/dist/modules/repo/dependency-overrides.d.ts.map +1 -1
- package/dist/modules/repo/dependency-overrides.js +10 -3
- package/dist/modules/repo/dependency-overrides.js.map +1 -1
- package/dist/modules/repo/document-drift.d.ts +1 -1
- package/dist/modules/repo/document-drift.d.ts.map +1 -1
- package/dist/modules/repo/document-drift.js +15 -2
- package/dist/modules/repo/document-drift.js.map +1 -1
- package/dist/modules/repo/duplicate-exports.d.ts +1 -1
- package/dist/modules/repo/duplicate-exports.d.ts.map +1 -1
- package/dist/modules/repo/duplicate-exports.js +26 -7
- package/dist/modules/repo/duplicate-exports.js.map +1 -1
- package/dist/modules/repo/env-public-values.d.ts +1 -1
- package/dist/modules/repo/env-public-values.d.ts.map +1 -1
- package/dist/modules/repo/env-public-values.js +9 -2
- package/dist/modules/repo/env-public-values.js.map +1 -1
- package/dist/modules/repo/{index.d.ts → guards.d.ts} +2 -3
- package/dist/modules/repo/guards.d.ts.map +1 -0
- package/dist/modules/repo/{index.js → guards.js} +2 -3
- package/dist/modules/repo/guards.js.map +1 -0
- package/dist/modules/repo/installed-packages-agnostic.d.ts +1 -1
- package/dist/modules/repo/installed-packages-agnostic.d.ts.map +1 -1
- package/dist/modules/repo/installed-packages-agnostic.js +25 -6
- package/dist/modules/repo/installed-packages-agnostic.js.map +1 -1
- package/dist/modules/repo/local-only-variables.d.ts +1 -1
- package/dist/modules/repo/local-only-variables.d.ts.map +1 -1
- package/dist/modules/repo/local-only-variables.js.map +1 -1
- package/dist/modules/repo/project-scripts.d.ts +1 -1
- package/dist/modules/repo/project-scripts.d.ts.map +1 -1
- package/dist/modules/repo/project-scripts.js +13 -3
- package/dist/modules/repo/project-scripts.js.map +1 -1
- package/dist/modules/repo/secret-bindings.d.ts +1 -1
- package/dist/modules/repo/secret-bindings.d.ts.map +1 -1
- package/dist/modules/repo/secret-bindings.js +73 -19
- package/dist/modules/repo/secret-bindings.js.map +1 -1
- package/dist/modules/repo/shell-safe.d.ts +2 -2
- package/dist/modules/repo/shell-safe.d.ts.map +1 -1
- package/dist/modules/repo/shell-safe.js +1 -1
- package/dist/modules/repo/shell-safe.js.map +1 -1
- package/dist/modules/repo/specifiers.d.ts.map +1 -1
- package/dist/modules/repo/specifiers.js +8 -1
- package/dist/modules/repo/specifiers.js.map +1 -1
- package/dist/modules/repo/test-source-root.d.ts +1 -1
- package/dist/modules/repo/test-source-root.d.ts.map +1 -1
- package/dist/modules/repo/test-source-root.js +5 -1
- package/dist/modules/repo/test-source-root.js.map +1 -1
- package/dist/modules/repo/walker-read-failure.d.ts +1 -1
- package/dist/modules/repo/walker-read-failure.d.ts.map +1 -1
- package/dist/modules/repo/walker-read-failure.js +15 -3
- package/dist/modules/repo/walker-read-failure.js.map +1 -1
- package/dist/modules/repo/worker-bounded-body.d.ts +1 -1
- package/dist/modules/repo/worker-bounded-body.d.ts.map +1 -1
- package/dist/modules/repo/worker-bounded-body.js +21 -5
- package/dist/modules/repo/worker-bounded-body.js.map +1 -1
- package/dist/modules/repo/worker-config.d.ts +1 -1
- package/dist/modules/repo/worker-config.d.ts.map +1 -1
- package/dist/modules/repo/worker-config.js +19 -7
- package/dist/modules/repo/worker-config.js.map +1 -1
- package/dist/modules/repo/wrangler-toml.d.ts.map +1 -1
- package/dist/modules/repo/wrangler-toml.js +13 -2
- package/dist/modules/repo/wrangler-toml.js.map +1 -1
- package/dist/modules/ui/cascade.d.ts +1 -1
- package/dist/modules/ui/cascade.d.ts.map +1 -1
- package/dist/modules/ui/cascade.js +93 -22
- package/dist/modules/ui/cascade.js.map +1 -1
- package/dist/modules/ui/css.d.ts.map +1 -1
- package/dist/modules/ui/css.js +6 -2
- package/dist/modules/ui/css.js.map +1 -1
- package/dist/modules/ui/definitions.d.ts +2 -2
- package/dist/modules/ui/definitions.d.ts.map +1 -1
- package/dist/modules/ui/definitions.js +22 -6
- package/dist/modules/ui/definitions.js.map +1 -1
- package/dist/modules/ui/{index.d.ts → guards.d.ts} +2 -2
- package/dist/modules/ui/guards.d.ts.map +1 -0
- package/dist/modules/ui/{index.js → guards.js} +1 -1
- package/dist/modules/ui/guards.js.map +1 -0
- package/dist/modules/ui/interaction.d.ts +1 -1
- package/dist/modules/ui/interaction.d.ts.map +1 -1
- package/dist/modules/ui/interaction.js +118 -26
- package/dist/modules/ui/interaction.js.map +1 -1
- package/dist/modules/ui/motion.d.ts +1 -1
- package/dist/modules/ui/motion.d.ts.map +1 -1
- package/dist/modules/ui/motion.js +36 -10
- package/dist/modules/ui/motion.js.map +1 -1
- package/dist/modules/ui/source.d.ts.map +1 -1
- package/dist/modules/ui/source.js +14 -4
- package/dist/modules/ui/source.js.map +1 -1
- package/dist/modules/ui/stylesheets.d.ts.map +1 -1
- package/dist/modules/ui/stylesheets.js +8 -2
- package/dist/modules/ui/stylesheets.js.map +1 -1
- package/dist/modules/ui/styling.d.ts +2 -2
- package/dist/modules/ui/styling.d.ts.map +1 -1
- package/dist/modules/ui/styling.js +68 -18
- package/dist/modules/ui/styling.js.map +1 -1
- package/dist/node/index.d.ts +2 -2
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +2 -2
- package/dist/node/index.js.map +1 -1
- package/dist/{reader → node}/layout.d.ts.map +1 -1
- package/dist/node/layout.js.map +1 -0
- package/dist/{reader → node}/reader.d.ts +1 -1
- package/dist/{reader → node}/reader.d.ts.map +1 -1
- package/dist/{reader → node}/reader.js +11 -5
- package/dist/node/reader.js.map +1 -0
- package/dist/node/reports/index.d.ts +2 -0
- package/dist/node/reports/index.d.ts.map +1 -0
- package/dist/node/reports/index.js +2 -0
- package/dist/node/reports/index.js.map +1 -0
- package/dist/{reports/index.d.ts → node/reports/reports.d.ts} +5 -5
- package/dist/node/reports/reports.d.ts.map +1 -0
- package/dist/{reports/index.js → node/reports/reports.js} +21 -8
- package/dist/node/reports/reports.js.map +1 -0
- package/dist/{config.d.ts → node/suite/config.d.ts} +2 -2
- package/dist/node/suite/config.d.ts.map +1 -0
- package/dist/{config.js → node/suite/config.js} +10 -5
- package/dist/node/suite/config.js.map +1 -0
- package/dist/node/suite/index.d.ts +8 -0
- package/dist/node/suite/index.d.ts.map +1 -0
- package/dist/node/suite/index.js +7 -0
- package/dist/node/suite/index.js.map +1 -0
- package/dist/{suite/index.d.ts → node/suite/register.d.ts} +5 -11
- package/dist/node/suite/register.d.ts.map +1 -0
- package/dist/{suite/index.js → node/suite/register.js} +10 -11
- package/dist/node/suite/register.js.map +1 -0
- package/dist/node/suite/registry.d.ts +13 -0
- package/dist/node/suite/registry.d.ts.map +1 -0
- package/dist/node/suite/registry.js +27 -0
- package/dist/node/suite/registry.js.map +1 -0
- package/dist/{suite → node/suite}/run.d.ts +2 -2
- package/dist/node/suite/run.d.ts.map +1 -0
- package/dist/{suite → node/suite}/run.js +2 -2
- package/dist/node/suite/run.js.map +1 -0
- package/dist/reader/strip-comments.d.ts.map +1 -1
- package/dist/reader/strip-comments.js +4 -1
- package/dist/reader/strip-comments.js.map +1 -1
- package/dist/reader/view.d.ts +1 -1
- package/dist/reader/view.d.ts.map +1 -1
- package/dist/reader/view.js +2 -2
- package/dist/reader/view.js.map +1 -1
- package/dist/seed/index.d.ts +2 -53
- package/dist/seed/index.d.ts.map +1 -1
- package/dist/seed/index.js +1 -100
- package/dist/seed/index.js.map +1 -1
- package/dist/seed/seed-writer.d.ts +54 -0
- package/dist/seed/seed-writer.d.ts.map +1 -0
- package/dist/seed/seed-writer.js +103 -0
- package/dist/seed/seed-writer.js.map +1 -0
- package/dist/shapes/shapes.d.ts +2 -2
- package/dist/shapes/shapes.d.ts.map +1 -1
- package/dist/shapes/shapes.js +28 -7
- package/dist/shapes/shapes.js.map +1 -1
- package/dist/support/ast.d.ts.map +1 -1
- package/dist/support/ast.js.map +1 -1
- package/dist/support/facts.d.ts.map +1 -1
- package/dist/support/facts.js +3 -1
- package/dist/support/facts.js.map +1 -1
- package/dist/support/imports.d.ts.map +1 -1
- package/dist/support/imports.js +40 -9
- package/dist/support/imports.js.map +1 -1
- package/dist/support/paths.d.ts.map +1 -1
- package/dist/support/paths.js +1 -1
- package/dist/support/paths.js.map +1 -1
- package/dist/support/text.d.ts.map +1 -1
- package/dist/support/text.js.map +1 -1
- package/dist/zod-shape/index.d.ts +1 -20
- package/dist/zod-shape/index.d.ts.map +1 -1
- package/dist/zod-shape/index.js +1 -89
- package/dist/zod-shape/index.js.map +1 -1
- package/dist/zod-shape/zod-shape.d.ts +21 -0
- package/dist/zod-shape/zod-shape.d.ts.map +1 -0
- package/dist/zod-shape/zod-shape.js +95 -0
- package/dist/zod-shape/zod-shape.js.map +1 -0
- package/package.json +7 -7
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/modules/backend/index.d.ts.map +0 -1
- package/dist/modules/backend/index.js.map +0 -1
- package/dist/modules/core-definitions/index.d.ts.map +0 -1
- package/dist/modules/core-definitions/index.js.map +0 -1
- package/dist/modules/firestore/index.d.ts.map +0 -1
- package/dist/modules/firestore/index.js.map +0 -1
- package/dist/modules/frontend-actions/index.d.ts.map +0 -1
- package/dist/modules/frontend-actions/index.js.map +0 -1
- package/dist/modules/frontend-reads/index.d.ts.map +0 -1
- package/dist/modules/frontend-reads/index.js.map +0 -1
- package/dist/modules/import-paths/index.d.ts +0 -9
- package/dist/modules/import-paths/index.d.ts.map +0 -1
- package/dist/modules/import-paths/index.js +0 -7
- package/dist/modules/import-paths/index.js.map +0 -1
- package/dist/modules/repo/index.d.ts.map +0 -1
- package/dist/modules/repo/index.js.map +0 -1
- package/dist/modules/ui/index.d.ts.map +0 -1
- package/dist/modules/ui/index.js.map +0 -1
- package/dist/reader/layout.js.map +0 -1
- package/dist/reader/reader.js.map +0 -1
- package/dist/registry.d.ts +0 -13
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -27
- package/dist/registry.js.map +0 -1
- package/dist/reports/index.d.ts.map +0 -1
- package/dist/reports/index.js.map +0 -1
- package/dist/suite/index.d.ts.map +0 -1
- package/dist/suite/index.js.map +0 -1
- package/dist/suite/run.d.ts.map +0 -1
- package/dist/suite/run.js.map +0 -1
- /package/dist/{reader → node}/layout.d.ts +0 -0
- /package/dist/{reader → node}/layout.js +0 -0
package/dist/guard.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { RulesService } from './
|
|
2
|
-
import type { RepoReader, Scope } from './
|
|
1
|
+
import type { RulesService } from './node/layout.js';
|
|
2
|
+
import type { RepoReader, Scope } from './node/reader.js';
|
|
3
3
|
import type { FileView } from './reader/view.js';
|
|
4
4
|
/** One place a guard failed. */
|
|
5
5
|
export interface Finding {
|
package/dist/guard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,gCAAgC;AAChC,MAAM,WAAW,OAAO;IACtB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IAChC,mGAAmG;IACnG,UAAU,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,QAAQ,EAAE,CAAC;CAChD;AAED,sGAAsG;AACtG,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7D,MAAM,WAAW,KAAK;IACpB,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gGAAgG;IAChG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,2FAA2F;IAC3F,OAAO,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE;QACjB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,SAAS,OAAO,EAAE,CAAC;KAC7C,CAAC;IACF,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CAChD;AAED,gDAAgD;AAChD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAAC,EAC3C,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B,MAAM,CAIR"}
|
package/dist/guard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,mDAAmD;AAyDnD,gDAAgD;AAChD,MAAM,UAAU,cAAc,
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,mDAAmD;AAyDnD,gDAAgD;AAChD,MAAM,UAAU,cAAc,CAC5B,KAA2C,EAC3C,QAA4B;IAE5B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,aAAa,EAAE,EAAE,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC3F,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC","sourcesContent":["// What a guard is: a named check over the files the reader hands it. Generic guards and an app's\n// business guards are the same thing to the suite.\n\nimport type { RulesService } from './node/layout.js';\nimport type { RepoReader, Scope } from './node/reader.js';\nimport type { FileView } from './reader/view.js';\n\n/** One place a guard failed. */\nexport interface Finding {\n /** Repo-relative path, or the config entry the finding is about. */\n file: string;\n line?: number;\n detail: string;\n}\n\n/**\n * What a guard run reads through. Every scope a guard reads is counted on its own, so a run whose\n * scope reached no file fails as vacuous even when it also read a named file.\n */\nexport interface GuardContext {\n readonly reader: RepoReader;\n files(scope: Scope): FileView[];\n file(relPath: string): FileView;\n /** Every rules file the layout lists, or those written for one service: a scope like any other. */\n rulesFiles(service?: RulesService): FileView[];\n}\n\n/** A must-fail or must-pass input for a guard's matcher. A bare string is the text of `sample.ts`. */\nexport type Sample = string | { path: string; text: string };\n\nexport interface Guard {\n /** The behavior the guard proves, in words; it names the guard's test. */\n readonly title: string;\n /** What the check requires and how a failure is fixed, in words. Printed with every failure. */\n readonly description: string;\n /** Loads what the guard needs before its samples or its run (an app's declared values). */\n prepare?(): Promise<void>;\n run(context: GuardContext): Finding[] | Promise<Finding[]>;\n /**\n * The guard's own proof that it still catches what it exists to catch: every `flags` sample must\n * produce a hit and every `passes` sample none. Generic guards prove themselves in the package's\n * own tests; a business guard carries its samples here.\n */\n readonly samples?: {\n flags: readonly Sample[];\n passes: readonly Sample[];\n probe(sample: FileView): readonly unknown[];\n };\n /** A whole-repository sweep can take longer than a unit test's default. */\n readonly timeoutMs?: number;\n /**\n * Why this guard cannot run here, or null when it can. Only a guard whose input lies outside the\n * checkout (a sibling repository CI never checks out) has one; the suite shows the guard SKIPPED\n * with this reason, never passed.\n */\n skipReason?(reader: RepoReader): string | null;\n}\n\n/** A printable failure report for one guard. */\nexport function formatFindings(\n guard: Pick<Guard, 'title' | 'description'>,\n findings: readonly Finding[],\n): string {\n const lines = [`${guard.title}: ${findings.length} finding(s)`, '', guard.description, ''];\n for (const f of findings) lines.push(` ${f.file}${f.line ? `:${f.line}` : ''} — ${f.detail}`);\n return lines.join('\\n');\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { declaredLiteral, matchPattern, ownerOnly, reviewedAllowlist, sampleHits, type AllowlistEntry, type Hit, type Literal, type Matcher, } from './shapes/shapes.js';
|
|
2
|
-
export { formatFindings, type Finding, type Guard, type GuardContext, type Sample } from './guard.js';
|
|
2
|
+
export { formatFindings, type Finding, type Guard, type GuardContext, type Sample, } from './guard.js';
|
|
3
3
|
export { viewOfText, type FileView } from './reader/view.js';
|
|
4
|
-
export { MODULE_LOADS, type ImportedName, type ImportKind, type ModuleImport } from './support/imports.js';
|
|
4
|
+
export { MODULE_LOADS, type ImportedName, type ImportKind, type ModuleImport, } from './support/imports.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,OAAO,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,KAAK,cAAc,EACnB,KAAK,GAAG,EACR,KAAK,OAAO,EACZ,KAAK,OAAO,GACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,KAAK,OAAO,EACZ,KAAK,KAAK,EACV,KAAK,YAAY,EACjB,KAAK,MAAM,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// The pure entry: the three shapes an app builds its business guards on, and the guard contract.
|
|
2
2
|
// Reading the repository is the `./node` entry's job; running the suite is `./suite`'s.
|
|
3
3
|
export { declaredLiteral, matchPattern, ownerOnly, reviewedAllowlist, sampleHits, } from './shapes/shapes.js';
|
|
4
|
-
export { formatFindings } from './guard.js';
|
|
4
|
+
export { formatFindings, } from './guard.js';
|
|
5
5
|
export { viewOfText } from './reader/view.js';
|
|
6
|
-
export { MODULE_LOADS } from './support/imports.js';
|
|
6
|
+
export { MODULE_LOADS, } from './support/imports.js';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,wFAAwF;AAExF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,GAKX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,wFAAwF;AAExF,OAAO,EACL,eAAe,EACf,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,UAAU,GAKX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,GAKf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EACL,YAAY,GAIb,MAAM,sBAAsB,CAAC","sourcesContent":["// The pure entry: the three shapes an app builds its business guards on, and the guard contract.\n// Reading the repository is the `./node` entry's job; running the suite is `./suite`'s.\n\nexport {\n declaredLiteral,\n matchPattern,\n ownerOnly,\n reviewedAllowlist,\n sampleHits,\n type AllowlistEntry,\n type Hit,\n type Literal,\n type Matcher,\n} from './shapes/shapes.js';\nexport {\n formatFindings,\n type Finding,\n type Guard,\n type GuardContext,\n type Sample,\n} from './guard.js';\nexport { viewOfText, type FileView } from './reader/view.js';\nexport {\n MODULE_LOADS,\n type ImportedName,\n type ImportKind,\n type ModuleImport,\n} from './support/imports.js';\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import type { GenericGuardDefinition } from '../../config.js';
|
|
2
|
+
import type { GenericGuardDefinition } from '../../node/suite/config.js';
|
|
3
3
|
import type { FileView } from '../../reader/view.js';
|
|
4
|
-
import type { Reviewed } from '../../
|
|
4
|
+
import type { Reviewed } from '../../node/layout.js';
|
|
5
5
|
import { type Matcher } from '../../shapes/shapes.js';
|
|
6
6
|
import { type ServerZone } from './shared.js';
|
|
7
7
|
export interface AuditWriterFacts {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { ownerOnly, reviewedAllowlist } from '../../shapes/shapes.js';
|
|
|
5
5
|
import { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';
|
|
6
6
|
import { namesProblem, reviewedProblems, textProblem } from '../../support/facts.js';
|
|
7
7
|
import { MODULE_LOADS, moduleImports, namesModule } from '../../support/imports.js';
|
|
8
|
-
import { serverZoneContext, serverZoneProblems, staleServerFolders } from './shared.js';
|
|
8
|
+
import { serverZoneContext, serverZoneProblems, staleServerFolders, } from './shared.js';
|
|
9
9
|
const FUNCTIONS_CODE = { roots: ['functions'], kinds: ['code'], tests: false };
|
|
10
10
|
const AUDIT_WRITER_SCOPE = {
|
|
11
11
|
roots: ['functions', 'scripts', 'app'],
|
|
@@ -22,7 +22,8 @@ export function auditCollectionMatcher(facts) {
|
|
|
22
22
|
const sf = file.sourceFile;
|
|
23
23
|
const loads = new Map(moduleImports(sf, MODULE_LOADS).map((site) => [site.node, site.spec]));
|
|
24
24
|
forEachNode(sf, (node) => {
|
|
25
|
-
if (ts.isPropertyAccessExpression(node) &&
|
|
25
|
+
if (ts.isPropertyAccessExpression(node) &&
|
|
26
|
+
handles.has(`${node.expression.getText(sf)}.${node.name.text}`)) {
|
|
26
27
|
hits.push({ index: node.getStart(sf), detail: node.getText(sf) });
|
|
27
28
|
}
|
|
28
29
|
const specifier = loads.get(node);
|
|
@@ -30,7 +31,8 @@ export function auditCollectionMatcher(facts) {
|
|
|
30
31
|
hits.push({ index: node.getStart(sf), detail: `imports ${specifier}` });
|
|
31
32
|
return;
|
|
32
33
|
}
|
|
33
|
-
const isSpecifier = !!node.parent &&
|
|
34
|
+
const isSpecifier = !!node.parent &&
|
|
35
|
+
(ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent));
|
|
34
36
|
if (isPlainString(node) && !isSpecifier && namesCollection(node.text)) {
|
|
35
37
|
hits.push({ index: node.getStart(sf), detail: `'${node.text}'` });
|
|
36
38
|
}
|
|
@@ -51,7 +53,8 @@ export function personActorMatcher(facts) {
|
|
|
51
53
|
if (!ts.isObjectLiteralExpression(node))
|
|
52
54
|
return;
|
|
53
55
|
for (const prop of node.properties) {
|
|
54
|
-
if (!ts.isPropertyAssignment(prop) ||
|
|
56
|
+
if (!ts.isPropertyAssignment(prop) ||
|
|
57
|
+
prop.name.getText(sf).replace(/^['"]|['"]$/g, '') !== facts.modeField)
|
|
55
58
|
continue;
|
|
56
59
|
const init = unwrap(prop.initializer);
|
|
57
60
|
if (ts.isStringLiteralLike(init) && modes.has(init.text)) {
|
|
@@ -100,7 +103,9 @@ export const auditWriterGuard = {
|
|
|
100
103
|
`db.doc(\`${facts.collectionName}/\${id}\`).set(event);`,
|
|
101
104
|
`db.collection(${facts.collectionHandles[0]}).doc(id).set(event);`,
|
|
102
105
|
],
|
|
103
|
-
passes: [
|
|
106
|
+
passes: [
|
|
107
|
+
`// writes ${facts.collectionName} through ${facts.collectionHandles[0]}\nconst label = '${facts.collectionName}Count';`,
|
|
108
|
+
],
|
|
104
109
|
},
|
|
105
110
|
});
|
|
106
111
|
const actors = ownerOnly({
|
|
@@ -112,14 +117,21 @@ export const auditWriterGuard = {
|
|
|
112
117
|
match: personActorMatcher(facts.personActor),
|
|
113
118
|
owners: [facts.personActor.constructors],
|
|
114
119
|
samples: {
|
|
115
|
-
flags: [
|
|
116
|
-
|
|
120
|
+
flags: [
|
|
121
|
+
`const actor = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' as const, uid };`,
|
|
122
|
+
],
|
|
123
|
+
passes: [
|
|
124
|
+
`type A = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };\nconst b = { other${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };`,
|
|
125
|
+
],
|
|
117
126
|
},
|
|
118
127
|
});
|
|
119
128
|
const inZone = (guard) => ({
|
|
120
129
|
...guard,
|
|
121
130
|
async run(context) {
|
|
122
|
-
return [
|
|
131
|
+
return [
|
|
132
|
+
...staleServerFolders(context, facts.appServerZone),
|
|
133
|
+
...(await guard.run(serverZoneContext(context, facts.appServerZone))),
|
|
134
|
+
];
|
|
123
135
|
},
|
|
124
136
|
});
|
|
125
137
|
return [inZone(collection), inZone(actors)];
|
|
@@ -180,7 +192,9 @@ export const auditPayloadGuard = {
|
|
|
180
192
|
const problems = [];
|
|
181
193
|
namesProblem(facts?.entryPoints, 'entryPoints', problems);
|
|
182
194
|
textProblem(facts?.payloadKey, 'payloadKey', problems);
|
|
183
|
-
namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, {
|
|
195
|
+
namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, {
|
|
196
|
+
nonEmpty: false,
|
|
197
|
+
});
|
|
184
198
|
reviewedProblems(facts?.operatorCopy, 'operatorCopy', problems, { key: 'site' });
|
|
185
199
|
for (const entry of facts?.operatorCopy ?? []) {
|
|
186
200
|
if (typeof entry?.site === 'string' && !/^[^#]+#[^#]+$/.test(entry.site))
|
|
@@ -206,12 +220,19 @@ export const auditPayloadGuard = {
|
|
|
206
220
|
const site = `${file.path}#${key}`;
|
|
207
221
|
seen.add(site);
|
|
208
222
|
if (!reviewed.has(site))
|
|
209
|
-
findings.push({
|
|
223
|
+
findings.push({
|
|
224
|
+
file: file.path,
|
|
225
|
+
line: lineOfNode(file, node),
|
|
226
|
+
detail: `prose-named payload key ${key}`,
|
|
227
|
+
});
|
|
210
228
|
}
|
|
211
229
|
}
|
|
212
230
|
for (const site of reviewed)
|
|
213
231
|
if (!seen.has(site))
|
|
214
|
-
findings.push({
|
|
232
|
+
findings.push({
|
|
233
|
+
file: site,
|
|
234
|
+
detail: 'stale operator-copy entry: the key no longer occurs',
|
|
235
|
+
});
|
|
215
236
|
return findings;
|
|
216
237
|
},
|
|
217
238
|
},
|
|
@@ -223,14 +244,25 @@ export function chainedFailureAudits(file, names) {
|
|
|
223
244
|
const sf = file.sourceFile;
|
|
224
245
|
const hits = [];
|
|
225
246
|
forEachNode(sf, (node) => {
|
|
226
|
-
if (ts.isImportSpecifier(node) &&
|
|
247
|
+
if (ts.isImportSpecifier(node) &&
|
|
248
|
+
node.propertyName &&
|
|
249
|
+
names.has(node.propertyName.text) &&
|
|
250
|
+
node.propertyName.text !== node.name.text) {
|
|
227
251
|
hits.push({ node, detail: `imports ${node.propertyName.text} under another name` });
|
|
228
252
|
}
|
|
229
253
|
const name = ts.isCallExpression(node) ? calleeName(node) : undefined;
|
|
230
254
|
if (ts.isCallExpression(node) && name && names.has(name)) {
|
|
231
255
|
const parent = node.parent;
|
|
232
|
-
const chained = ts.isPropertyAccessExpression(parent) &&
|
|
233
|
-
|
|
256
|
+
const chained = ts.isPropertyAccessExpression(parent) &&
|
|
257
|
+
parent.expression === node &&
|
|
258
|
+
['catch', 'then', 'finally'].includes(parent.name.text);
|
|
259
|
+
hits.push({
|
|
260
|
+
node,
|
|
261
|
+
name,
|
|
262
|
+
detail: chained
|
|
263
|
+
? `chains .${parent.name.text} onto ${name}`
|
|
264
|
+
: '',
|
|
265
|
+
});
|
|
234
266
|
}
|
|
235
267
|
});
|
|
236
268
|
return hits;
|
|
@@ -260,7 +292,11 @@ export const failureAuditGuard = {
|
|
|
260
292
|
if (hit.name)
|
|
261
293
|
called.add(hit.name);
|
|
262
294
|
if (hit.detail)
|
|
263
|
-
findings.push({
|
|
295
|
+
findings.push({
|
|
296
|
+
file: file.path,
|
|
297
|
+
line: lineOfNode(file, hit.node),
|
|
298
|
+
detail: hit.detail,
|
|
299
|
+
});
|
|
264
300
|
}
|
|
265
301
|
}
|
|
266
302
|
for (const name of names)
|
|
@@ -286,7 +322,9 @@ export function fireAndForgetShapes(file, auditWrites) {
|
|
|
286
322
|
const name = calleeName(node);
|
|
287
323
|
if (name && auditWrites.has(name))
|
|
288
324
|
writes.push(name);
|
|
289
|
-
if (name === 'catch' &&
|
|
325
|
+
if (name === 'catch' &&
|
|
326
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
327
|
+
ts.isCallExpression(node.expression.expression)) {
|
|
290
328
|
const inner = calleeName(node.expression.expression);
|
|
291
329
|
if (inner && auditWrites.has(inner))
|
|
292
330
|
swallowed.push({ node, name: inner });
|
|
@@ -327,14 +365,25 @@ export const fireAndForgetGuard = {
|
|
|
327
365
|
voidFiles.add(file.path);
|
|
328
366
|
if (!reviewed.has(file.path)) {
|
|
329
367
|
for (const node of voided)
|
|
330
|
-
findings.push({
|
|
368
|
+
findings.push({
|
|
369
|
+
file: file.path,
|
|
370
|
+
line: lineOfNode(file, node),
|
|
371
|
+
detail: `fire-and-forget: ${node.getText(file.sourceFile).slice(0, 80)}`,
|
|
372
|
+
});
|
|
331
373
|
}
|
|
332
374
|
for (const { node, name } of swallowed)
|
|
333
|
-
findings.push({
|
|
375
|
+
findings.push({
|
|
376
|
+
file: file.path,
|
|
377
|
+
line: lineOfNode(file, node),
|
|
378
|
+
detail: `${name}(…).catch(…) swallows an audit write`,
|
|
379
|
+
});
|
|
334
380
|
}
|
|
335
381
|
for (const path of reviewed)
|
|
336
382
|
if (!voidFiles.has(path))
|
|
337
|
-
findings.push({
|
|
383
|
+
findings.push({
|
|
384
|
+
file: path,
|
|
385
|
+
detail: 'stale void site: the file has no void-ed call',
|
|
386
|
+
});
|
|
338
387
|
for (const name of auditWrites)
|
|
339
388
|
if (!called.has(name))
|
|
340
389
|
findings.push({ file: '(auditWrites)', detail: `${name} is called nowhere` });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,yFAAyF;AAEzF,OAAO,EAAE,MAAM,YAAY,CAAC;AAM5B,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAA0B,MAAM,wBAAwB,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAmB,MAAM,aAAa,CAAC;AAEzG,MAAM,cAAc,GAAU,EAAE,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAsBtF,MAAM,kBAAkB,GAAU;IAChC,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC;IACtC,aAAa,EAAE,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,CAAC,MAAM,CAAC;IACf,KAAK,EAAE,KAAK;CACb,CAAC;AAEF,yFAAyF;AACzF,MAAM,UAAU,sBAAsB,CAAC,KAAwF;IAC7H,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACjD,MAAM,eAAe,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;IACvH,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,MAAM,IAAI,GAAU,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7F,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;gBAC3G,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,SAAS,KAAK,SAAS,IAAI,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3F,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,SAAS,EAAE,EAAE,CAAC,CAAC;gBACxE,OAAO;YACT,CAAC;YACD,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAClH,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACrE,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,cAAc,gBAAgB,EAAE,CAAC,CAAC;YAC3F,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,kBAAkB,CAAC,KAAsC;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,EAAE,EAAE;QACd,MAAM,IAAI,GAAU,EAAE,CAAC;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;QAC3B,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;gBAAE,OAAO;YAChD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS;oBAAE,SAAS;gBACtH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACtC,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzD,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,MAAM,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;gBACxF,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAA6C;IACxE,EAAE,EAAE,aAAa;IACjB,UAAU,EAAE,iCAAiC;IAC7C,YAAY,CAAC,KAAK;QAChB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QAC/D,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;QACtE,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;YACpD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,qBAAqB,MAAM,sBAAsB,CAAC,CAAC;QACvI,CAAC;QACD,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACrF,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAC7G,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,0BAA0B,EAAE,QAAQ,CAAC,CAAC;QACpF,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;QAC9E,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;QACvE,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;QACpE,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,MAAM,UAAU,GAAG,iBAAiB,CAAC;YACnC,KAAK,EAAE,qDAAqD;YAC5D,WAAW,EACT,QAAQ,KAAK,CAAC,MAAM,gCAAgC,KAAK,CAAC,cAAc,KAAK,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;gBACnH,+GAA+G;gBAC/G,yGAAyG;gBACzG,mGAAmG;YACrG,KAAK,EAAE,kBAAkB;YACzB,KAAK,EAAE,sBAAsB,CAAC,KAAK,CAAC;YACpC,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,sBAAsB,EAAE,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC;YAClF,OAAO,EAAE;gBACP,KAAK,EAAE;oBACL,kBAAkB,KAAK,CAAC,cAAc,gBAAgB;oBACtD,YAAY,KAAK,CAAC,cAAc,wBAAwB;oBACxD,iBAAiB,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,uBAAuB;iBACnE;gBACD,MAAM,EAAE,CAAC,aAAa,KAAK,CAAC,cAAc,YAAY,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,oBAAoB,KAAK,CAAC,cAAc,SAAS,CAAC;aACnI;SACF,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC;YACvB,KAAK,EAAE,wDAAwD;YAC/D,WAAW,EACT,QAAQ,KAAK,CAAC,WAAW,CAAC,YAAY,2BAA2B,KAAK,CAAC,WAAW,CAAC,SAAS,oBAAoB;gBAChH,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,wEAAwE;gBAC9G,yFAAyF;YAC3F,KAAK,EAAE,kBAAkB;YACzB,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC;YAC5C,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC;YACxC,OAAO,EAAE;gBACP,KAAK,EAAE,CAAC,mBAAmB,KAAK,CAAC,WAAW,CAAC,SAAS,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC;gBAC3G,MAAM,EAAE,CAAC,cAAc,KAAK,CAAC,WAAW,CAAC,SAAS,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,0BAA0B,KAAK,CAAC,WAAW,CAAC,SAAS,MAAM,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;aAC/K;SACF,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,CAAC,KAAY,EAAS,EAAE,CAAC,CAAC;YACvC,GAAG,KAAK;YACR,KAAK,CAAC,GAAG,CAAC,OAAqB;gBAC7B,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;YACtI,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;CACF,CAAC;AAgBF,+DAA+D;AAC/D,MAAM,SAAS,GAAG,kGAAkG,CAAC;AACrH,yFAAyF;AACzF,MAAM,cAAc,GAAG,mBAAmB,CAAC;AAE3C,yGAAyG;AACzG,MAAM,UAAU,wBAAwB,CAAC,IAAc,EAAE,KAAwB;IAC/E,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3B,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACtD,MAAM,IAAI,GAA0C,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,IAAiC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAChH,MAAM,WAAW,GAAG,CAAC,GAA+B,EAAE,EAAE;QACtD,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,6BAA6B,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxF,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YACxB,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACxD,IAAI,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/D,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACvC,IAAI,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC;oBAAE,WAAW,CAAC,KAAK,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,OAAmC,EAAE,IAAyB,EAAE,EAAE;QACnF,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACtC,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAAE,SAAS;YACvE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvC,IAAI,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC;gBAAE,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QACvB,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACzE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC1B,IAAI,EAAE,CAAC,yBAAyB,CAAC,KAAK,CAAC;oBAAE,SAAS,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;YAAE,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAA8C;IAC1E,EAAE,EAAE,cAAc;IAClB,UAAU,EAAE,iCAAiC;IAC7C,YAAY,CAAC,KAAK;QAChB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;QAC1D,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;QACvD,YAAY,CAAC,KAAK,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QACjG,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACjF,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC;YAC9C,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,qBAAqB,KAAK,CAAC,IAAI,kBAAkB,CAAC,CAAC;QAC7I,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO;YACL;gBACE,KAAK,EAAE,wDAAwD;gBAC/D,WAAW,EACT,kHAAkH;oBAClH,+GAA+G;oBAC/G,6GAA6G;oBAC7G,gHAAgH;oBAChH,kGAAkG;gBACpG,GAAG,CAAC,OAAO;oBACT,MAAM,QAAQ,GAAc,EAAE,CAAC;oBAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBAChE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;oBAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;wBACjD,KAAK,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;4BAClE,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;4BACnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BACf,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;gCAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,2BAA2B,GAAG,EAAE,EAAE,CAAC,CAAC;wBACtI,CAAC;oBACH,CAAC;oBACD,KAAK,MAAM,IAAI,IAAI,QAAQ;wBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,qDAAqD,EAAE,CAAC,CAAC;oBAC/I,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAUF,kGAAkG;AAClG,MAAM,UAAU,oBAAoB,CAAC,IAAc,EAAE,KAA0B;IAC7E,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3B,MAAM,IAAI,GAA4D,EAAE,CAAC;IACzE,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QACvB,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACtI,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,IAAI,CAAC,YAAY,CAAC,IAAI,qBAAqB,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACtE,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,MAAM,OAAO,GAAG,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/I,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,WAAY,MAAsC,CAAC,IAAI,CAAC,IAAI,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAChI,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAA8C;IAC1E,EAAE,EAAE,mBAAmB;IACvB,UAAU,EAAE,iCAAiC;IAC7C,YAAY,CAAC,KAAK;QAChB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,QAAQ,CAAC,CAAC;QACxE,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO;YACL;gBACE,KAAK,EAAE,wDAAwD;gBAC/D,WAAW,EACT,mCAAmC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,2CAA2C;oBACjH,mHAAmH;oBACnH,+GAA+G;oBAC/G,6FAA6F;gBAC/F,GAAG,CAAC,OAAO;oBACT,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;oBAChD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;oBACjC,MAAM,QAAQ,GAAc,EAAE,CAAC;oBAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;wBACjD,KAAK,MAAM,GAAG,IAAI,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;4BACpD,IAAI,GAAG,CAAC,IAAI;gCAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;4BACnC,IAAI,GAAG,CAAC,MAAM;gCAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;wBAC3G,CAAC;oBACH,CAAC;oBACD,KAAK,MAAM,IAAI,IAAI,KAAK;wBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,MAAM,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAAC,CAAC;oBACtI,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAYF,oGAAoG;AACpG,MAAM,UAAU,mBAAmB,CAAC,IAAc,EAAE,WAAgC;IAClF,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC;IAC3B,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,MAAM,SAAS,GAA2C,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE;QACvB,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjG,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO;QACvC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,IAAI,KAAK,OAAO,IAAI,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1H,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACrD,IAAI,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAA+C;IAC5E,EAAE,EAAE,eAAe;IACnB,UAAU,EAAE,KAAK;IACjB,YAAY,CAAC,KAAK;QAChB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/E,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC1D,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO;YACL;gBACE,KAAK,EAAE,yEAAyE;gBAChF,WAAW,EACT,kHAAkH;oBAClH,0GAA0G;oBAC1G,8GAA8G;oBAC9G,8GAA8G;oBAC9G,8GAA8G;oBAC9G,kHAAkH;oBAClH,sBAAsB;gBACxB,GAAG,CAAC,OAAO;oBACT,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC/C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC7D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;oBACpC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;oBACjC,MAAM,QAAQ,GAAc,EAAE,CAAC;oBAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;wBACjD,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;wBAC7E,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;wBACrC,IAAI,MAAM,CAAC,MAAM;4BAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC5C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC7B,KAAK,MAAM,IAAI,IAAI,MAAM;gCAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,oBAAoB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;wBACxK,CAAC;wBACD,KAAK,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,sCAAsC,EAAE,CAAC,CAAC;oBAClK,CAAC;oBACD,KAAK,MAAM,IAAI,IAAI,QAAQ;wBAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,+CAA+C,EAAE,CAAC,CAAC;oBAC9I,KAAK,MAAM,IAAI,IAAI,WAAW;wBAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;4BAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAAC,CAAC;oBACrI,OAAO,QAAQ,CAAC;gBAClB,CAAC;aACF;SACF,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["// The audit guards: one writer of the audit collection, one builder of person-actors, no\n// member-written text in an audit payload, and no handler wrapped around an audit write.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { Scope } from '../../reader/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport type { Reviewed } from '../../reader/layout.js';\nimport { ownerOnly, reviewedAllowlist, type Hit, type Matcher } from '../../shapes/shapes.js';\nimport { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';\nimport { namesProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { MODULE_LOADS, moduleImports, namesModule } from '../../support/imports.js';\nimport { serverZoneContext, serverZoneProblems, staleServerFolders, type ServerZone } from './shared.js';\n\nconst FUNCTIONS_CODE: Scope = { roots: ['functions'], kinds: ['code'], tests: false };\n\n// ---------------------------------------------------------------------------------------------\n// One audit writer.\n\nexport interface AuditWriterFacts {\n /** The one module that writes audit documents. */\n writer: string;\n /** The audit collection's name as stored (`auditEvents`). */\n collectionName: string;\n /** The core's handles on the collection, as `OWNER.member` (`COLLECTIONS.AUDIT_EVENTS`). */\n collectionHandles: readonly string[];\n /** Packages that write audit documents themselves; only the writer imports them. */\n writerPackages: readonly string[];\n /** Modules that name the collection to READ it, never to write; a stale entry fails. */\n readers: readonly Reviewed[];\n /** The one module that builds a person-actor, the field that says an actor's mode, and the person modes. */\n personActor: { constructors: string; modeField: string; modes: readonly string[] };\n /** Server code in the app root, held to the same rules as the Functions tree. */\n appServerZone: ServerZone;\n}\n\nconst AUDIT_WRITER_SCOPE: Scope = {\n roots: ['functions', 'scripts', 'app'],\n optionalRoots: ['scripts'],\n kinds: ['code'],\n tests: false,\n};\n\n/** Every place a file names the audit collection or imports a package that writes it. */\nexport function auditCollectionMatcher(facts: Pick<AuditWriterFacts, 'collectionName' | 'collectionHandles' | 'writerPackages'>): Matcher {\n const handles = new Set(facts.collectionHandles);\n const namesCollection = (text: string) => text === facts.collectionName || text.startsWith(`${facts.collectionName}/`);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n const loads = new Map(moduleImports(sf, MODULE_LOADS).map((site) => [site.node, site.spec]));\n forEachNode(sf, (node) => {\n if (ts.isPropertyAccessExpression(node) && handles.has(`${node.expression.getText(sf)}.${node.name.text}`)) {\n hits.push({ index: node.getStart(sf), detail: node.getText(sf) });\n }\n const specifier = loads.get(node);\n if (specifier !== undefined && facts.writerPackages.some((p) => namesModule(specifier, p))) {\n hits.push({ index: node.getStart(sf), detail: `imports ${specifier}` });\n return;\n }\n const isSpecifier = !!node.parent && (ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent));\n if (isPlainString(node) && !isSpecifier && namesCollection(node.text)) {\n hits.push({ index: node.getStart(sf), detail: `'${node.text}'` });\n }\n if (ts.isTemplateExpression(node) && namesCollection(node.head.text)) {\n hits.push({ index: node.getStart(sf), detail: `${facts.collectionName} template path` });\n }\n });\n return hits;\n };\n}\n\n/** Every object literal that builds a person-actor by hand: its mode field set to a person mode. */\nexport function personActorMatcher(facts: AuditWriterFacts['personActor']): Matcher {\n const modes = new Set(facts.modes);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n forEachNode(sf, (node) => {\n if (!ts.isObjectLiteralExpression(node)) return;\n for (const prop of node.properties) {\n if (!ts.isPropertyAssignment(prop) || prop.name.getText(sf).replace(/^['\"]|['\"]$/g, '') !== facts.modeField) continue;\n const init = unwrap(prop.initializer);\n if (ts.isStringLiteralLike(init) && modes.has(init.text)) {\n hits.push({ index: prop.getStart(sf), detail: `${facts.modeField}: '${init.text}'` });\n }\n }\n });\n return hits;\n };\n}\n\nexport const auditWriterGuard: GenericGuardDefinition<AuditWriterFacts> = {\n id: 'auditWriter',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.writer, 'writer', problems);\n textProblem(facts?.collectionName, 'collectionName', problems);\n namesProblem(facts?.collectionHandles, 'collectionHandles', problems);\n for (const handle of facts?.collectionHandles ?? []) {\n if (typeof handle === 'string' && !/^[\\w$]+\\.[\\w$]+$/.test(handle)) problems.push(`collection handle ${handle} is not OWNER.member`);\n }\n namesProblem(facts?.writerPackages, 'writerPackages', problems, { nonEmpty: false });\n reviewedProblems(facts?.readers, 'readers', problems);\n if (facts?.readers?.some((r) => r?.path === facts.writer)) problems.push('the writer is listed as a reader');\n textProblem(facts?.personActor?.constructors, 'personActor.constructors', problems);\n textProblem(facts?.personActor?.modeField, 'personActor.modeField', problems);\n namesProblem(facts?.personActor?.modes, 'personActor.modes', problems);\n serverZoneProblems(facts?.appServerZone, 'appServerZone', problems);\n return problems;\n },\n build(facts) {\n const collection = reviewedAllowlist({\n title: 'audit documents are written by the one audit writer',\n description:\n `Only ${facts.writer} names the audit collection (${facts.collectionName}, ${facts.collectionHandles.join(', ')}) ` +\n 'or imports a package that writes it; a second writer would skip the attribution, the request origin, and the ' +\n 'append-only rules the writer owns. Write audit events through the writer. A module that only READS the ' +\n 'collection is a reviewed reader with its why; a reader that stops naming the collection is stale.',\n scope: AUDIT_WRITER_SCOPE,\n match: auditCollectionMatcher(facts),\n allowlist: [{ path: facts.writer, why: 'the one audit writer' }, ...facts.readers],\n samples: {\n flags: [\n `db.collection('${facts.collectionName}').add(event);`,\n `db.doc(\\`${facts.collectionName}/\\${id}\\`).set(event);`,\n `db.collection(${facts.collectionHandles[0]}).doc(id).set(event);`,\n ],\n passes: [`// writes ${facts.collectionName} through ${facts.collectionHandles[0]}\\nconst label = '${facts.collectionName}Count';`],\n },\n });\n const actors = ownerOnly({\n title: 'person-actors are built only by the actor constructors',\n description:\n `Only ${facts.personActor.constructors} writes an object whose ${facts.personActor.modeField} is a person mode ` +\n `(${facts.personActor.modes.join(', ')}). A person-actor carries the origin of the request it acted through; ` +\n 'built by hand it can carry none, or a forged one. Build it with the actor constructors.',\n scope: AUDIT_WRITER_SCOPE,\n match: personActorMatcher(facts.personActor),\n owners: [facts.personActor.constructors],\n samples: {\n flags: [`const actor = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' as const, uid };`],\n passes: [`type A = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };\\nconst b = { other${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };`],\n },\n });\n const inZone = (guard: Guard): Guard => ({\n ...guard,\n async run(context: GuardContext) {\n return [...staleServerFolders(context, facts.appServerZone), ...(await guard.run(serverZoneContext(context, facts.appServerZone)))];\n },\n });\n return [inZone(collection), inZone(actors)];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No member-written text in an audit payload.\n\nexport interface AuditPayloadFacts {\n /** The audit writer's entry points (`writeAuditEventAs`, the failure entry points). */\n entryPoints: readonly string[];\n /** The key under which an entry point takes its payload (`payload`). */\n payloadKey: string;\n /** Keys elsewhere whose object literal is handed to an entry point as its payload (`auditPayload`). */\n forwardedPayloadKeys: readonly string[];\n /** Prose-named keys an operator (never a member) writes, as `file#key`, each with its why. */\n operatorCopy: ReadonlyArray<{ site: string; why: string }>;\n}\n\n/** A key named like prose: a title, a name, a body of text. */\nconst PROSE_KEY = /(title|name|description|subject|body|text|message|content|caption|narrative|comment|bio|words)$/i;\n/** A map whose keys NAME fields rather than carry their text (`changedFieldLengths`). */\nconst NAMES_NOT_TEXT = /(Lengths|Fields)$/;\n\n/** Every prose-named key, at any depth, of the payload literals a file hands to an audit entry point. */\nexport function proseKeysInAuditPayloads(file: FileView, facts: AuditPayloadFacts): Array<{ key: string; node: ts.Node }> {\n const sf = file.sourceFile;\n const entryPoints = new Set(facts.entryPoints);\n const forwarded = new Set(facts.forwardedPayloadKeys);\n const hits: Array<{ key: string; node: ts.Node }> = [];\n const keyOf = (prop: ts.ObjectLiteralElementLike) => prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const walkPayload = (obj: ts.ObjectLiteralExpression) => {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop)) continue;\n const key = keyOf(prop);\n if (PROSE_KEY.test(key)) hits.push({ key, node: prop });\n if (ts.isPropertyAssignment(prop) && !NAMES_NOT_TEXT.test(key)) {\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n }\n };\n const payloadOf = (details: ts.ObjectLiteralExpression, keys: ReadonlySet<string>) => {\n for (const prop of details.properties) {\n if (!ts.isPropertyAssignment(prop) || !keys.has(keyOf(prop))) continue;\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n };\n const payloadKeys = new Set([facts.payloadKey]);\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node) && entryPoints.has(calleeName(node) ?? '')) {\n for (const arg of node.arguments) {\n const value = unwrap(arg);\n if (ts.isObjectLiteralExpression(value)) payloadOf(value, payloadKeys);\n }\n }\n if (ts.isObjectLiteralExpression(node)) payloadOf(node, forwarded);\n });\n return hits;\n}\n\nexport const auditPayloadGuard: GenericGuardDefinition<AuditPayloadFacts> = {\n id: 'auditPayload',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.entryPoints, 'entryPoints', problems);\n textProblem(facts?.payloadKey, 'payloadKey', problems);\n namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, { nonEmpty: false });\n reviewedProblems(facts?.operatorCopy, 'operatorCopy', problems, { key: 'site' });\n for (const entry of facts?.operatorCopy ?? []) {\n if (typeof entry?.site === 'string' && !/^[^#]+#[^#]+$/.test(entry.site)) problems.push(`operatorCopy site ${entry.site} is not file#key`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no member-written text is copied into an audit payload',\n description:\n 'An audit payload records identifiers, field names, lengths, and decisions — never member-written text. An audit ' +\n 'event outlives every edit and every erasure, so a title, name, description, subject, body, or message copied ' +\n \"into one survives the member's own change and their account's deletion. Record the changed field names and \" +\n 'their lengths instead. A key under a `…Lengths` or `…Fields` map names fields and is exempt; text an operator ' +\n 'writes is a reviewed `file#key` entry with its why, and an entry that no longer occurs is stale.',\n run(context) {\n const findings: Finding[] = [];\n const reviewed = new Set(facts.operatorCopy.map((e) => e.site));\n const seen = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const { key, node } of proseKeysInAuditPayloads(file, facts)) {\n const site = `${file.path}#${key}`;\n seen.add(site);\n if (!reviewed.has(site)) findings.push({ file: file.path, line: lineOfNode(file, node), detail: `prose-named payload key ${key}` });\n }\n }\n for (const site of reviewed) if (!seen.has(site)) findings.push({ file: site, detail: 'stale operator-copy entry: the key no longer occurs' });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No handler chained onto a failure-audit entry point.\n\nexport interface FailureAuditFacts {\n /** The audit writer's best-effort failure entry points, which log and capture and never throw. */\n failureEntryPoints: readonly string[];\n}\n\n/** Each aliased import of a failure entry point, and each call with a handler chained onto it. */\nexport function chainedFailureAudits(file: FileView, names: ReadonlySet<string>): Array<{ node: ts.Node; detail: string; name?: string }> {\n const sf = file.sourceFile;\n const hits: Array<{ node: ts.Node; detail: string; name?: string }> = [];\n forEachNode(sf, (node) => {\n if (ts.isImportSpecifier(node) && node.propertyName && names.has(node.propertyName.text) && node.propertyName.text !== node.name.text) {\n hits.push({ node, detail: `imports ${node.propertyName.text} under another name` });\n }\n const name = ts.isCallExpression(node) ? calleeName(node) : undefined;\n if (ts.isCallExpression(node) && name && names.has(name)) {\n const parent = node.parent;\n const chained = ts.isPropertyAccessExpression(parent) && parent.expression === node && ['catch', 'then', 'finally'].includes(parent.name.text);\n hits.push({ node, name, detail: chained ? `chains .${(parent as ts.PropertyAccessExpression).name.text} onto ${name}` : '' });\n }\n });\n return hits;\n}\n\nexport const failureAuditGuard: GenericGuardDefinition<FailureAuditFacts> = {\n id: 'failureAuditChain',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no handler is chained onto a failure-audit entry point',\n description:\n `The failure-audit entry points (${facts.failureEntryPoints.join(', ')}) never throw — each logs and captures a ` +\n 'write that failed — so a `.catch`, `.then`, or `.finally` chained onto one is dead code that hides the contract, ' +\n 'and an aliased import hides the call from this check. Import each under its own name and call it bare. Every ' +\n 'declared entry point must still be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const names = new Set(facts.failureEntryPoints);\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const hit of chainedFailureAudits(file, names)) {\n if (hit.name) called.add(hit.name);\n if (hit.detail) findings.push({ file: file.path, line: lineOfNode(file, hit.node), detail: hit.detail });\n }\n }\n for (const name of names) if (!called.has(name)) findings.push({ file: '(failureEntryPoints)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No fire-and-forget work and no swallowed audit write.\n\nexport interface FireAndForgetFacts {\n /** The audit writer's success entry points, whose failure is never swallowed by a `.catch`. */\n auditWrites: readonly string[];\n /** Files whose `void`-ed calls are reviewed, each with its why; a file that no longer has one is stale. */\n voidSites: readonly Reviewed[];\n}\n\n/** Every `void`-ed call, every `.catch` chained onto an audit write, and every audit write call. */\nexport function fireAndForgetShapes(file: FileView, auditWrites: ReadonlySet<string>) {\n const sf = file.sourceFile;\n const voided: ts.Node[] = [];\n const swallowed: Array<{ node: ts.Node; name: string }> = [];\n const writes: string[] = [];\n forEachNode(sf, (node) => {\n if (ts.isVoidExpression(node) && ts.isCallExpression(unwrap(node.expression))) voided.push(node);\n if (!ts.isCallExpression(node)) return;\n const name = calleeName(node);\n if (name && auditWrites.has(name)) writes.push(name);\n if (name === 'catch' && ts.isPropertyAccessExpression(node.expression) && ts.isCallExpression(node.expression.expression)) {\n const inner = calleeName(node.expression.expression);\n if (inner && auditWrites.has(inner)) swallowed.push({ node, name: inner });\n }\n });\n return { voided, swallowed, writes };\n}\n\nexport const fireAndForgetGuard: GenericGuardDefinition<FireAndForgetFacts> = {\n id: 'fireAndForget',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.auditWrites, 'auditWrites', problems, { nonEmpty: false });\n reviewedProblems(facts?.voidSites, 'voidSites', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no backend work is fired and forgotten, and no audit write is swallowed',\n description:\n 'A `void`-ed call in a callable, trigger, or worker is never awaited and never has its failure captured, and the ' +\n 'runtime throttles the instance once it has answered, so the work may never run. Await it inside its own ' +\n 'try/catch with a capture, commit it in the primary transaction, or enqueue it to a durable outbox — a write ' +\n \"composed into a caller's transaction is awaited like any other. A `.catch` chained onto an audit write is a \" +\n 'second, silent owner of a failure the best-effort failure-audit entry points already own. A reviewed `void` ' +\n 'site is a file with its why; one with no `void`-ed call left is stale, and each declared audit write must still ' +\n 'be called somewhere.',\n run(context) {\n const auditWrites = new Set(facts.auditWrites);\n const reviewed = new Set(facts.voidSites.map((s) => s.path));\n const voidFiles = new Set<string>();\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n const { voided, swallowed, writes } = fireAndForgetShapes(file, auditWrites);\n writes.forEach((w) => called.add(w));\n if (voided.length) voidFiles.add(file.path);\n if (!reviewed.has(file.path)) {\n for (const node of voided) findings.push({ file: file.path, line: lineOfNode(file, node), detail: `fire-and-forget: ${node.getText(file.sourceFile).slice(0, 80)}` });\n }\n for (const { node, name } of swallowed) findings.push({ file: file.path, line: lineOfNode(file, node), detail: `${name}(…).catch(…) swallows an audit write` });\n }\n for (const path of reviewed) if (!voidFiles.has(path)) findings.push({ file: path, detail: 'stale void site: the file has no void-ed call' });\n for (const name of auditWrites) if (!called.has(name)) findings.push({ file: '(auditWrites)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n"]}
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/modules/backend/audit.ts"],"names":[],"mappings":"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","sourcesContent":["// The audit guards: one writer of the audit collection, one builder of person-actors, no\n// member-written text in an audit payload, and no handler wrapped around an audit write.\n\nimport ts from 'typescript';\nimport type { GenericGuardDefinition } from '../../node/suite/config.js';\nimport type { Finding, Guard, GuardContext } from '../../guard.js';\nimport type { Scope } from '../../node/reader.js';\nimport type { FileView } from '../../reader/view.js';\nimport type { Reviewed } from '../../node/layout.js';\nimport { ownerOnly, reviewedAllowlist, type Hit, type Matcher } from '../../shapes/shapes.js';\nimport { calleeName, forEachNode, isPlainString, lineOfNode, unwrap } from '../../support/ast.js';\nimport { namesProblem, reviewedProblems, textProblem } from '../../support/facts.js';\nimport { MODULE_LOADS, moduleImports, namesModule } from '../../support/imports.js';\nimport {\n serverZoneContext,\n serverZoneProblems,\n staleServerFolders,\n type ServerZone,\n} from './shared.js';\n\nconst FUNCTIONS_CODE: Scope = { roots: ['functions'], kinds: ['code'], tests: false };\n\n// ---------------------------------------------------------------------------------------------\n// One audit writer.\n\nexport interface AuditWriterFacts {\n /** The one module that writes audit documents. */\n writer: string;\n /** The audit collection's name as stored (`auditEvents`). */\n collectionName: string;\n /** The core's handles on the collection, as `OWNER.member` (`COLLECTIONS.AUDIT_EVENTS`). */\n collectionHandles: readonly string[];\n /** Packages that write audit documents themselves; only the writer imports them. */\n writerPackages: readonly string[];\n /** Modules that name the collection to READ it, never to write; a stale entry fails. */\n readers: readonly Reviewed[];\n /** The one module that builds a person-actor, the field that says an actor's mode, and the person modes. */\n personActor: { constructors: string; modeField: string; modes: readonly string[] };\n /** Server code in the app root, held to the same rules as the Functions tree. */\n appServerZone: ServerZone;\n}\n\nconst AUDIT_WRITER_SCOPE: Scope = {\n roots: ['functions', 'scripts', 'app'],\n optionalRoots: ['scripts'],\n kinds: ['code'],\n tests: false,\n};\n\n/** Every place a file names the audit collection or imports a package that writes it. */\nexport function auditCollectionMatcher(\n facts: Pick<AuditWriterFacts, 'collectionName' | 'collectionHandles' | 'writerPackages'>,\n): Matcher {\n const handles = new Set(facts.collectionHandles);\n const namesCollection = (text: string) =>\n text === facts.collectionName || text.startsWith(`${facts.collectionName}/`);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n const loads = new Map(moduleImports(sf, MODULE_LOADS).map((site) => [site.node, site.spec]));\n forEachNode(sf, (node) => {\n if (\n ts.isPropertyAccessExpression(node) &&\n handles.has(`${node.expression.getText(sf)}.${node.name.text}`)\n ) {\n hits.push({ index: node.getStart(sf), detail: node.getText(sf) });\n }\n const specifier = loads.get(node);\n if (specifier !== undefined && facts.writerPackages.some((p) => namesModule(specifier, p))) {\n hits.push({ index: node.getStart(sf), detail: `imports ${specifier}` });\n return;\n }\n const isSpecifier =\n !!node.parent &&\n (ts.isImportDeclaration(node.parent) || ts.isExportDeclaration(node.parent));\n if (isPlainString(node) && !isSpecifier && namesCollection(node.text)) {\n hits.push({ index: node.getStart(sf), detail: `'${node.text}'` });\n }\n if (ts.isTemplateExpression(node) && namesCollection(node.head.text)) {\n hits.push({ index: node.getStart(sf), detail: `${facts.collectionName} template path` });\n }\n });\n return hits;\n };\n}\n\n/** Every object literal that builds a person-actor by hand: its mode field set to a person mode. */\nexport function personActorMatcher(facts: AuditWriterFacts['personActor']): Matcher {\n const modes = new Set(facts.modes);\n return (file) => {\n const hits: Hit[] = [];\n const sf = file.sourceFile;\n forEachNode(sf, (node) => {\n if (!ts.isObjectLiteralExpression(node)) return;\n for (const prop of node.properties) {\n if (\n !ts.isPropertyAssignment(prop) ||\n prop.name.getText(sf).replace(/^['\"]|['\"]$/g, '') !== facts.modeField\n )\n continue;\n const init = unwrap(prop.initializer);\n if (ts.isStringLiteralLike(init) && modes.has(init.text)) {\n hits.push({ index: prop.getStart(sf), detail: `${facts.modeField}: '${init.text}'` });\n }\n }\n });\n return hits;\n };\n}\n\nexport const auditWriterGuard: GenericGuardDefinition<AuditWriterFacts> = {\n id: 'auditWriter',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n textProblem(facts?.writer, 'writer', problems);\n textProblem(facts?.collectionName, 'collectionName', problems);\n namesProblem(facts?.collectionHandles, 'collectionHandles', problems);\n for (const handle of facts?.collectionHandles ?? []) {\n if (typeof handle === 'string' && !/^[\\w$]+\\.[\\w$]+$/.test(handle))\n problems.push(`collection handle ${handle} is not OWNER.member`);\n }\n namesProblem(facts?.writerPackages, 'writerPackages', problems, { nonEmpty: false });\n reviewedProblems(facts?.readers, 'readers', problems);\n if (facts?.readers?.some((r) => r?.path === facts.writer))\n problems.push('the writer is listed as a reader');\n textProblem(facts?.personActor?.constructors, 'personActor.constructors', problems);\n textProblem(facts?.personActor?.modeField, 'personActor.modeField', problems);\n namesProblem(facts?.personActor?.modes, 'personActor.modes', problems);\n serverZoneProblems(facts?.appServerZone, 'appServerZone', problems);\n return problems;\n },\n build(facts) {\n const collection = reviewedAllowlist({\n title: 'audit documents are written by the one audit writer',\n description:\n `Only ${facts.writer} names the audit collection (${facts.collectionName}, ${facts.collectionHandles.join(', ')}) ` +\n 'or imports a package that writes it; a second writer would skip the attribution, the request origin, and the ' +\n 'append-only rules the writer owns. Write audit events through the writer. A module that only READS the ' +\n 'collection is a reviewed reader with its why; a reader that stops naming the collection is stale.',\n scope: AUDIT_WRITER_SCOPE,\n match: auditCollectionMatcher(facts),\n allowlist: [{ path: facts.writer, why: 'the one audit writer' }, ...facts.readers],\n samples: {\n flags: [\n `db.collection('${facts.collectionName}').add(event);`,\n `db.doc(\\`${facts.collectionName}/\\${id}\\`).set(event);`,\n `db.collection(${facts.collectionHandles[0]}).doc(id).set(event);`,\n ],\n passes: [\n `// writes ${facts.collectionName} through ${facts.collectionHandles[0]}\\nconst label = '${facts.collectionName}Count';`,\n ],\n },\n });\n const actors = ownerOnly({\n title: 'person-actors are built only by the actor constructors',\n description:\n `Only ${facts.personActor.constructors} writes an object whose ${facts.personActor.modeField} is a person mode ` +\n `(${facts.personActor.modes.join(', ')}). A person-actor carries the origin of the request it acted through; ` +\n 'built by hand it can carry none, or a forged one. Build it with the actor constructors.',\n scope: AUDIT_WRITER_SCOPE,\n match: personActorMatcher(facts.personActor),\n owners: [facts.personActor.constructors],\n samples: {\n flags: [\n `const actor = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' as const, uid };`,\n ],\n passes: [\n `type A = { ${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };\\nconst b = { other${facts.personActor.modeField}: '${facts.personActor.modes[0]}' };`,\n ],\n },\n });\n const inZone = (guard: Guard): Guard => ({\n ...guard,\n async run(context: GuardContext) {\n return [\n ...staleServerFolders(context, facts.appServerZone),\n ...(await guard.run(serverZoneContext(context, facts.appServerZone))),\n ];\n },\n });\n return [inZone(collection), inZone(actors)];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No member-written text in an audit payload.\n\nexport interface AuditPayloadFacts {\n /** The audit writer's entry points (`writeAuditEventAs`, the failure entry points). */\n entryPoints: readonly string[];\n /** The key under which an entry point takes its payload (`payload`). */\n payloadKey: string;\n /** Keys elsewhere whose object literal is handed to an entry point as its payload (`auditPayload`). */\n forwardedPayloadKeys: readonly string[];\n /** Prose-named keys an operator (never a member) writes, as `file#key`, each with its why. */\n operatorCopy: ReadonlyArray<{ site: string; why: string }>;\n}\n\n/** A key named like prose: a title, a name, a body of text. */\nconst PROSE_KEY =\n /(title|name|description|subject|body|text|message|content|caption|narrative|comment|bio|words)$/i;\n/** A map whose keys NAME fields rather than carry their text (`changedFieldLengths`). */\nconst NAMES_NOT_TEXT = /(Lengths|Fields)$/;\n\n/** Every prose-named key, at any depth, of the payload literals a file hands to an audit entry point. */\nexport function proseKeysInAuditPayloads(\n file: FileView,\n facts: AuditPayloadFacts,\n): Array<{ key: string; node: ts.Node }> {\n const sf = file.sourceFile;\n const entryPoints = new Set(facts.entryPoints);\n const forwarded = new Set(facts.forwardedPayloadKeys);\n const hits: Array<{ key: string; node: ts.Node }> = [];\n const keyOf = (prop: ts.ObjectLiteralElementLike) =>\n prop.name?.getText(sf).replace(/^['\"`]|['\"`]$/g, '') ?? '';\n const walkPayload = (obj: ts.ObjectLiteralExpression) => {\n for (const prop of obj.properties) {\n if (!ts.isPropertyAssignment(prop) && !ts.isShorthandPropertyAssignment(prop)) continue;\n const key = keyOf(prop);\n if (PROSE_KEY.test(key)) hits.push({ key, node: prop });\n if (ts.isPropertyAssignment(prop) && !NAMES_NOT_TEXT.test(key)) {\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n }\n };\n const payloadOf = (details: ts.ObjectLiteralExpression, keys: ReadonlySet<string>) => {\n for (const prop of details.properties) {\n if (!ts.isPropertyAssignment(prop) || !keys.has(keyOf(prop))) continue;\n const value = unwrap(prop.initializer);\n if (ts.isObjectLiteralExpression(value)) walkPayload(value);\n }\n };\n const payloadKeys = new Set([facts.payloadKey]);\n forEachNode(sf, (node) => {\n if (ts.isCallExpression(node) && entryPoints.has(calleeName(node) ?? '')) {\n for (const arg of node.arguments) {\n const value = unwrap(arg);\n if (ts.isObjectLiteralExpression(value)) payloadOf(value, payloadKeys);\n }\n }\n if (ts.isObjectLiteralExpression(node)) payloadOf(node, forwarded);\n });\n return hits;\n}\n\nexport const auditPayloadGuard: GenericGuardDefinition<AuditPayloadFacts> = {\n id: 'auditPayload',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.entryPoints, 'entryPoints', problems);\n textProblem(facts?.payloadKey, 'payloadKey', problems);\n namesProblem(facts?.forwardedPayloadKeys, 'forwardedPayloadKeys', problems, {\n nonEmpty: false,\n });\n reviewedProblems(facts?.operatorCopy, 'operatorCopy', problems, { key: 'site' });\n for (const entry of facts?.operatorCopy ?? []) {\n if (typeof entry?.site === 'string' && !/^[^#]+#[^#]+$/.test(entry.site))\n problems.push(`operatorCopy site ${entry.site} is not file#key`);\n }\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no member-written text is copied into an audit payload',\n description:\n 'An audit payload records identifiers, field names, lengths, and decisions — never member-written text. An audit ' +\n 'event outlives every edit and every erasure, so a title, name, description, subject, body, or message copied ' +\n \"into one survives the member's own change and their account's deletion. Record the changed field names and \" +\n 'their lengths instead. A key under a `…Lengths` or `…Fields` map names fields and is exempt; text an operator ' +\n 'writes is a reviewed `file#key` entry with its why, and an entry that no longer occurs is stale.',\n run(context) {\n const findings: Finding[] = [];\n const reviewed = new Set(facts.operatorCopy.map((e) => e.site));\n const seen = new Set<string>();\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const { key, node } of proseKeysInAuditPayloads(file, facts)) {\n const site = `${file.path}#${key}`;\n seen.add(site);\n if (!reviewed.has(site))\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `prose-named payload key ${key}`,\n });\n }\n }\n for (const site of reviewed)\n if (!seen.has(site))\n findings.push({\n file: site,\n detail: 'stale operator-copy entry: the key no longer occurs',\n });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No handler chained onto a failure-audit entry point.\n\nexport interface FailureAuditFacts {\n /** The audit writer's best-effort failure entry points, which log and capture and never throw. */\n failureEntryPoints: readonly string[];\n}\n\n/** Each aliased import of a failure entry point, and each call with a handler chained onto it. */\nexport function chainedFailureAudits(\n file: FileView,\n names: ReadonlySet<string>,\n): Array<{ node: ts.Node; detail: string; name?: string }> {\n const sf = file.sourceFile;\n const hits: Array<{ node: ts.Node; detail: string; name?: string }> = [];\n forEachNode(sf, (node) => {\n if (\n ts.isImportSpecifier(node) &&\n node.propertyName &&\n names.has(node.propertyName.text) &&\n node.propertyName.text !== node.name.text\n ) {\n hits.push({ node, detail: `imports ${node.propertyName.text} under another name` });\n }\n const name = ts.isCallExpression(node) ? calleeName(node) : undefined;\n if (ts.isCallExpression(node) && name && names.has(name)) {\n const parent = node.parent;\n const chained =\n ts.isPropertyAccessExpression(parent) &&\n parent.expression === node &&\n ['catch', 'then', 'finally'].includes(parent.name.text);\n hits.push({\n node,\n name,\n detail: chained\n ? `chains .${(parent as ts.PropertyAccessExpression).name.text} onto ${name}`\n : '',\n });\n }\n });\n return hits;\n}\n\nexport const failureAuditGuard: GenericGuardDefinition<FailureAuditFacts> = {\n id: 'failureAuditChain',\n absentWhen: 'the app records no audit events',\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.failureEntryPoints, 'failureEntryPoints', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no handler is chained onto a failure-audit entry point',\n description:\n `The failure-audit entry points (${facts.failureEntryPoints.join(', ')}) never throw — each logs and captures a ` +\n 'write that failed — so a `.catch`, `.then`, or `.finally` chained onto one is dead code that hides the contract, ' +\n 'and an aliased import hides the call from this check. Import each under its own name and call it bare. Every ' +\n 'declared entry point must still be called somewhere: one renamed away would pass unchecked.',\n run(context) {\n const names = new Set(facts.failureEntryPoints);\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n for (const hit of chainedFailureAudits(file, names)) {\n if (hit.name) called.add(hit.name);\n if (hit.detail)\n findings.push({\n file: file.path,\n line: lineOfNode(file, hit.node),\n detail: hit.detail,\n });\n }\n }\n for (const name of names)\n if (!called.has(name))\n findings.push({ file: '(failureEntryPoints)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n\n// ---------------------------------------------------------------------------------------------\n// No fire-and-forget work and no swallowed audit write.\n\nexport interface FireAndForgetFacts {\n /** The audit writer's success entry points, whose failure is never swallowed by a `.catch`. */\n auditWrites: readonly string[];\n /** Files whose `void`-ed calls are reviewed, each with its why; a file that no longer has one is stale. */\n voidSites: readonly Reviewed[];\n}\n\n/** Every `void`-ed call, every `.catch` chained onto an audit write, and every audit write call. */\nexport function fireAndForgetShapes(file: FileView, auditWrites: ReadonlySet<string>) {\n const sf = file.sourceFile;\n const voided: ts.Node[] = [];\n const swallowed: Array<{ node: ts.Node; name: string }> = [];\n const writes: string[] = [];\n forEachNode(sf, (node) => {\n if (ts.isVoidExpression(node) && ts.isCallExpression(unwrap(node.expression)))\n voided.push(node);\n if (!ts.isCallExpression(node)) return;\n const name = calleeName(node);\n if (name && auditWrites.has(name)) writes.push(name);\n if (\n name === 'catch' &&\n ts.isPropertyAccessExpression(node.expression) &&\n ts.isCallExpression(node.expression.expression)\n ) {\n const inner = calleeName(node.expression.expression);\n if (inner && auditWrites.has(inner)) swallowed.push({ node, name: inner });\n }\n });\n return { voided, swallowed, writes };\n}\n\nexport const fireAndForgetGuard: GenericGuardDefinition<FireAndForgetFacts> = {\n id: 'fireAndForget',\n absentWhen: false,\n factProblems(facts) {\n const problems: string[] = [];\n namesProblem(facts?.auditWrites, 'auditWrites', problems, { nonEmpty: false });\n reviewedProblems(facts?.voidSites, 'voidSites', problems);\n return problems;\n },\n build(facts) {\n return [\n {\n title: 'no backend work is fired and forgotten, and no audit write is swallowed',\n description:\n 'A `void`-ed call in a callable, trigger, or worker is never awaited and never has its failure captured, and the ' +\n 'runtime throttles the instance once it has answered, so the work may never run. Await it inside its own ' +\n 'try/catch with a capture, commit it in the primary transaction, or enqueue it to a durable outbox — a write ' +\n \"composed into a caller's transaction is awaited like any other. A `.catch` chained onto an audit write is a \" +\n 'second, silent owner of a failure the best-effort failure-audit entry points already own. A reviewed `void` ' +\n 'site is a file with its why; one with no `void`-ed call left is stale, and each declared audit write must still ' +\n 'be called somewhere.',\n run(context) {\n const auditWrites = new Set(facts.auditWrites);\n const reviewed = new Set(facts.voidSites.map((s) => s.path));\n const voidFiles = new Set<string>();\n const called = new Set<string>();\n const findings: Finding[] = [];\n for (const file of context.files(FUNCTIONS_CODE)) {\n const { voided, swallowed, writes } = fireAndForgetShapes(file, auditWrites);\n writes.forEach((w) => called.add(w));\n if (voided.length) voidFiles.add(file.path);\n if (!reviewed.has(file.path)) {\n for (const node of voided)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `fire-and-forget: ${node.getText(file.sourceFile).slice(0, 80)}`,\n });\n }\n for (const { node, name } of swallowed)\n findings.push({\n file: file.path,\n line: lineOfNode(file, node),\n detail: `${name}(…).catch(…) swallows an audit write`,\n });\n }\n for (const path of reviewed)\n if (!voidFiles.has(path))\n findings.push({\n file: path,\n detail: 'stale void site: the file has no void-ed call',\n });\n for (const name of auditWrites)\n if (!called.has(name))\n findings.push({ file: '(auditWrites)', detail: `${name} is called nowhere` });\n return findings;\n },\n },\n ];\n },\n};\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
|
-
import type { GenericGuardDefinition } from '../../config.js';
|
|
3
|
-
import type { Reviewed } from '../../
|
|
2
|
+
import type { GenericGuardDefinition } from '../../node/suite/config.js';
|
|
3
|
+
import type { Reviewed } from '../../node/layout.js';
|
|
4
4
|
import type { FileView } from '../../reader/view.js';
|
|
5
5
|
import { type Matcher } from '../../shapes/shapes.js';
|
|
6
6
|
import { type CallableDeclarationFacts } from '../frontend-actions/declarations.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/auth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/modules/backend/auth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAA0C,KAAK,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAK9F,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAOrB,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,wGAAwG;IACxG,OAAO,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC7B,gFAAgF;IAChF,aAAa,EAAE,UAAU,CAAC;CAC3B;AAKD,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAmBvE;AAED,eAAO,MAAM,eAAe,EAAE,sBAAsB,CAAC,eAAe,CAkDnE,CAAC;AAKF,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,eAAO,MAAM,kBAAkB,EAAE,sBAAsB,CAAC,kBAAkB,CAsCzE,CAAC;AAKF,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAK5D,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAc9F;AAED,eAAO,MAAM,uBAAuB,EAAE,sBAAsB,CAAC,uBAAuB,CAyBnF,CAAC;AAKF,MAAM,WAAW,aAAa;IAC5B,4GAA4G;IAC5G,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,sGAAsG;IACtG,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,6GAA6G;IAC7G,iBAAiB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,oFAAoF;IACpF,kBAAkB,EAAE,wBAAwB,CAAC;IAC7C,iGAAiG;IACjG,mBAAmB,EAAE,aAAa,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,OAAO,EAAE,EAAE,CAAC,uBAAuB,GAAG,IAAI,CAAC;CAC5C;AAgBD,+GAA+G;AAC/G,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,CA0CtD;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,GAAG,OAAO,CAa3F;AAED,eAAO,MAAM,aAAa,EAAE,sBAAsB,CAAC,aAAa,CAqL/D,CAAC"}
|