@ryanstark24/sfgraph-core 1.1.8 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyze/__tests__/audit-graph.test.js +79 -0
- package/dist/analyze/__tests__/audit-graph.test.js.map +1 -1
- package/dist/analyze/__tests__/edge-filters.test.d.ts +2 -0
- package/dist/analyze/__tests__/edge-filters.test.d.ts.map +1 -0
- package/dist/analyze/__tests__/edge-filters.test.js +66 -0
- package/dist/analyze/__tests__/edge-filters.test.js.map +1 -0
- package/dist/analyze/__tests__/find-nodes.test.d.ts +2 -0
- package/dist/analyze/__tests__/find-nodes.test.d.ts.map +1 -0
- package/dist/analyze/__tests__/find-nodes.test.js +129 -0
- package/dist/analyze/__tests__/find-nodes.test.js.map +1 -0
- package/dist/analyze/__tests__/findings.test.d.ts +2 -0
- package/dist/analyze/__tests__/findings.test.d.ts.map +1 -0
- package/dist/analyze/__tests__/findings.test.js +100 -0
- package/dist/analyze/__tests__/findings.test.js.map +1 -0
- package/dist/analyze/__tests__/governor-risks-detection.test.js +90 -0
- package/dist/analyze/__tests__/governor-risks-detection.test.js.map +1 -1
- package/dist/analyze/__tests__/security-fls-filter.test.d.ts +2 -0
- package/dist/analyze/__tests__/security-fls-filter.test.d.ts.map +1 -0
- package/dist/analyze/__tests__/security-fls-filter.test.js +23 -0
- package/dist/analyze/__tests__/security-fls-filter.test.js.map +1 -0
- package/dist/analyze/audit-graph.d.ts +26 -2
- package/dist/analyze/audit-graph.d.ts.map +1 -1
- package/dist/analyze/audit-graph.js +52 -5
- package/dist/analyze/audit-graph.js.map +1 -1
- package/dist/analyze/dependencies.d.ts +2 -2
- package/dist/analyze/dependencies.d.ts.map +1 -1
- package/dist/analyze/dependencies.js +9 -3
- package/dist/analyze/dependencies.js.map +1 -1
- package/dist/analyze/dependents.d.ts +6 -1
- package/dist/analyze/dependents.d.ts.map +1 -1
- package/dist/analyze/dependents.js +12 -2
- package/dist/analyze/dependents.js.map +1 -1
- package/dist/analyze/edge-filters.d.ts +37 -0
- package/dist/analyze/edge-filters.d.ts.map +1 -0
- package/dist/analyze/edge-filters.js +51 -0
- package/dist/analyze/edge-filters.js.map +1 -0
- package/dist/analyze/find-nodes.d.ts +38 -0
- package/dist/analyze/find-nodes.d.ts.map +1 -0
- package/dist/analyze/find-nodes.js +51 -0
- package/dist/analyze/find-nodes.js.map +1 -0
- package/dist/analyze/findings.d.ts +86 -0
- package/dist/analyze/findings.d.ts.map +1 -0
- package/dist/analyze/findings.js +141 -0
- package/dist/analyze/findings.js.map +1 -0
- package/dist/analyze/index.d.ts +2 -0
- package/dist/analyze/index.d.ts.map +1 -1
- package/dist/analyze/index.js +2 -0
- package/dist/analyze/index.js.map +1 -1
- package/dist/analyze/populate.d.ts.map +1 -1
- package/dist/analyze/populate.js +55 -10
- package/dist/analyze/populate.js.map +1 -1
- package/dist/analyze/security.d.ts +15 -0
- package/dist/analyze/security.d.ts.map +1 -1
- package/dist/analyze/security.js +59 -3
- package/dist/analyze/security.js.map +1 -1
- package/dist/analyze/wip-impact.d.ts.map +1 -1
- package/dist/analyze/wip-impact.js +12 -2
- package/dist/analyze/wip-impact.js.map +1 -1
- package/dist/domain/edge-fact.d.ts +25 -0
- package/dist/domain/edge-fact.d.ts.map +1 -1
- package/dist/domain/metadata-category.d.ts +1 -0
- package/dist/domain/metadata-category.d.ts.map +1 -1
- package/dist/domain/metadata-category.js +1 -0
- package/dist/domain/metadata-category.js.map +1 -1
- package/dist/domain/rel-types.d.ts +4 -0
- package/dist/domain/rel-types.d.ts.map +1 -1
- package/dist/domain/rel-types.js +7 -0
- package/dist/domain/rel-types.js.map +1 -1
- package/dist/embedding/__tests__/embed.test.d.ts +2 -0
- package/dist/embedding/__tests__/embed.test.d.ts.map +1 -0
- package/dist/embedding/__tests__/embed.test.js +72 -0
- package/dist/embedding/__tests__/embed.test.js.map +1 -0
- package/dist/embedding/embed.d.ts.map +1 -1
- package/dist/embedding/embed.js +14 -1
- package/dist/embedding/embed.js.map +1 -1
- package/dist/extractors/interfaces/metadata-source.d.ts +11 -0
- package/dist/extractors/interfaces/metadata-source.d.ts.map +1 -1
- package/dist/extractors/live-org/__tests__/bulk-retrieve.test.js.map +1 -1
- package/dist/extractors/live-org/__tests__/custom-settings.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/custom-settings.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/custom-settings.test.js +79 -0
- package/dist/extractors/live-org/__tests__/custom-settings.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.js +70 -8
- package/dist/extractors/live-org/__tests__/extractor-enrichment.test.js.map +1 -1
- package/dist/extractors/live-org/__tests__/liveness.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/liveness.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/liveness.test.js +148 -0
- package/dist/extractors/live-org/__tests__/liveness.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.js +177 -0
- package/dist/extractors/live-org/__tests__/mcd-baseline.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.js +75 -0
- package/dist/extractors/live-org/__tests__/metadata-read-batch.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.js +135 -0
- package/dist/extractors/live-org/__tests__/omnistudio-retrieve.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/pools.test.js +4 -1
- package/dist/extractors/live-org/__tests__/pools.test.js.map +1 -1
- package/dist/extractors/live-org/__tests__/rate-limit.test.js +1 -6
- package/dist/extractors/live-org/__tests__/rate-limit.test.js.map +1 -1
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.js +118 -0
- package/dist/extractors/live-org/__tests__/soql-rebatch.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/stop-waiting.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/stop-waiting.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/stop-waiting.test.js +243 -0
- package/dist/extractors/live-org/__tests__/stop-waiting.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.js +27 -0
- package/dist/extractors/live-org/__tests__/vlocity-runner.test.js.map +1 -1
- package/dist/extractors/live-org/__tests__/watchdog-budgets.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/watchdog-budgets.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/watchdog-budgets.test.js +40 -0
- package/dist/extractors/live-org/__tests__/watchdog-budgets.test.js.map +1 -0
- package/dist/extractors/live-org/__tests__/wedge-isolation.test.d.ts +2 -0
- package/dist/extractors/live-org/__tests__/wedge-isolation.test.d.ts.map +1 -0
- package/dist/extractors/live-org/__tests__/wedge-isolation.test.js +270 -0
- package/dist/extractors/live-org/__tests__/wedge-isolation.test.js.map +1 -0
- package/dist/extractors/live-org/bulk-retrieve.d.ts +176 -0
- package/dist/extractors/live-org/bulk-retrieve.d.ts.map +1 -1
- package/dist/extractors/live-org/bulk-retrieve.js +509 -71
- package/dist/extractors/live-org/bulk-retrieve.js.map +1 -1
- package/dist/extractors/live-org/capabilities.d.ts.map +1 -1
- package/dist/extractors/live-org/capabilities.js.map +1 -1
- package/dist/extractors/live-org/extractors/__tests__/apex.test.d.ts +2 -0
- package/dist/extractors/live-org/extractors/__tests__/apex.test.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/__tests__/apex.test.js +73 -0
- package/dist/extractors/live-org/extractors/__tests__/apex.test.js.map +1 -0
- package/dist/extractors/live-org/extractors/__tests__/lwc.parallel.test.d.ts +2 -0
- package/dist/extractors/live-org/extractors/__tests__/lwc.parallel.test.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/__tests__/lwc.parallel.test.js +183 -0
- package/dist/extractors/live-org/extractors/__tests__/lwc.parallel.test.js.map +1 -0
- package/dist/extractors/live-org/extractors/apex.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/apex.js +76 -51
- package/dist/extractors/live-org/extractors/apex.js.map +1 -1
- package/dist/extractors/live-org/extractors/custom-settings.d.ts +3 -0
- package/dist/extractors/live-org/extractors/custom-settings.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/custom-settings.js +66 -0
- package/dist/extractors/live-org/extractors/custom-settings.js.map +1 -0
- package/dist/extractors/live-org/extractors/flow.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/flow.js.map +1 -1
- package/dist/extractors/live-org/extractors/generic-metadata.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/generic-metadata.js.map +1 -1
- package/dist/extractors/live-org/extractors/generic-sobject.js.map +1 -1
- package/dist/extractors/live-org/extractors/lwc.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/lwc.js +81 -41
- package/dist/extractors/live-org/extractors/lwc.js.map +1 -1
- package/dist/extractors/live-org/extractors/mcd-baseline.d.ts +60 -0
- package/dist/extractors/live-org/extractors/mcd-baseline.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/mcd-baseline.js +118 -0
- package/dist/extractors/live-org/extractors/mcd-baseline.js.map +1 -0
- package/dist/extractors/live-org/extractors/object.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/object.js.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.d.ts +23 -0
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.d.ts.map +1 -0
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.js +172 -0
- package/dist/extractors/live-org/extractors/omnistudio-retrieve.js.map +1 -0
- package/dist/extractors/live-org/extractors/omnistudio.d.ts +8 -1
- package/dist/extractors/live-org/extractors/omnistudio.d.ts.map +1 -1
- package/dist/extractors/live-org/extractors/omnistudio.js +59 -6
- package/dist/extractors/live-org/extractors/omnistudio.js.map +1 -1
- package/dist/extractors/live-org/rate-limit.d.ts +98 -15
- package/dist/extractors/live-org/rate-limit.d.ts.map +1 -1
- package/dist/extractors/live-org/rate-limit.js +278 -41
- package/dist/extractors/live-org/rate-limit.js.map +1 -1
- package/dist/extractors/live-org/vlocity/runner.d.ts +1 -1
- package/dist/extractors/live-org/vlocity/runner.d.ts.map +1 -1
- package/dist/extractors/live-org/vlocity/runner.js +49 -14
- package/dist/extractors/live-org/vlocity/runner.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ingest/__tests__/config-values.test.d.ts +2 -0
- package/dist/ingest/__tests__/config-values.test.d.ts.map +1 -0
- package/dist/ingest/__tests__/config-values.test.js +65 -0
- package/dist/ingest/__tests__/config-values.test.js.map +1 -0
- package/dist/ingest/__tests__/full-sync-deletion.test.js +11 -4
- package/dist/ingest/__tests__/full-sync-deletion.test.js.map +1 -1
- package/dist/ingest/__tests__/live-ingest.detect-deletions-guard.test.d.ts +10 -0
- package/dist/ingest/__tests__/live-ingest.detect-deletions-guard.test.d.ts.map +1 -0
- package/dist/ingest/__tests__/live-ingest.detect-deletions-guard.test.js +251 -0
- package/dist/ingest/__tests__/live-ingest.detect-deletions-guard.test.js.map +1 -0
- package/dist/ingest/__tests__/live-ingest.test.js.map +1 -1
- package/dist/ingest/__tests__/multi-org-orchestrator.test.js +3 -0
- package/dist/ingest/__tests__/multi-org-orchestrator.test.js.map +1 -1
- package/dist/ingest/__tests__/parser-dispatch.test.d.ts +2 -0
- package/dist/ingest/__tests__/parser-dispatch.test.d.ts.map +1 -0
- package/dist/ingest/__tests__/parser-dispatch.test.js +55 -0
- package/dist/ingest/__tests__/parser-dispatch.test.js.map +1 -0
- package/dist/ingest/__tests__/vlocity-dispatch-integration.test.d.ts +2 -0
- package/dist/ingest/__tests__/vlocity-dispatch-integration.test.d.ts.map +1 -0
- package/dist/ingest/__tests__/vlocity-dispatch-integration.test.js +134 -0
- package/dist/ingest/__tests__/vlocity-dispatch-integration.test.js.map +1 -0
- package/dist/ingest/detect-deletions-guard.d.ts +45 -0
- package/dist/ingest/detect-deletions-guard.d.ts.map +1 -0
- package/dist/ingest/detect-deletions-guard.js +63 -0
- package/dist/ingest/detect-deletions-guard.js.map +1 -0
- package/dist/ingest/live-ingest.d.ts +86 -0
- package/dist/ingest/live-ingest.d.ts.map +1 -1
- package/dist/ingest/live-ingest.js +783 -449
- package/dist/ingest/live-ingest.js.map +1 -1
- package/dist/parsers/__tests__/datatransform-structured.test.d.ts +2 -0
- package/dist/parsers/__tests__/datatransform-structured.test.d.ts.map +1 -0
- package/dist/parsers/__tests__/datatransform-structured.test.js +147 -0
- package/dist/parsers/__tests__/datatransform-structured.test.js.map +1 -0
- package/dist/parsers/__tests__/edge-provenance.test.d.ts +2 -0
- package/dist/parsers/__tests__/edge-provenance.test.d.ts.map +1 -0
- package/dist/parsers/__tests__/edge-provenance.test.js +47 -0
- package/dist/parsers/__tests__/edge-provenance.test.js.map +1 -0
- package/dist/parsers/__tests__/lwc-bindings.test.js +78 -3
- package/dist/parsers/__tests__/lwc-bindings.test.js.map +1 -1
- package/dist/parsers/__tests__/mcd-gap-fills.test.d.ts +2 -0
- package/dist/parsers/__tests__/mcd-gap-fills.test.d.ts.map +1 -0
- package/dist/parsers/__tests__/mcd-gap-fills.test.js +75 -0
- package/dist/parsers/__tests__/mcd-gap-fills.test.js.map +1 -0
- package/dist/parsers/__tests__/object-inline-fields.test.js +2 -2
- package/dist/parsers/__tests__/object-inline-fields.test.js.map +1 -1
- package/dist/parsers/__tests__/omnistudio-overlap.test.d.ts +2 -0
- package/dist/parsers/__tests__/omnistudio-overlap.test.d.ts.map +1 -0
- package/dist/parsers/__tests__/omnistudio-overlap.test.js +163 -0
- package/dist/parsers/__tests__/omnistudio-overlap.test.js.map +1 -0
- package/dist/parsers/__tests__/omnistudio.golden.test.js +5 -6
- package/dist/parsers/__tests__/omnistudio.golden.test.js.map +1 -1
- package/dist/parsers/__tests__/reflection-walker.test.d.ts +2 -0
- package/dist/parsers/__tests__/reflection-walker.test.d.ts.map +1 -0
- package/dist/parsers/__tests__/reflection-walker.test.js +162 -0
- package/dist/parsers/__tests__/reflection-walker.test.js.map +1 -0
- package/dist/parsers/__tests__/vlocity.golden.test.js +9 -13
- package/dist/parsers/__tests__/vlocity.golden.test.js.map +1 -1
- package/dist/parsers/apex/__tests__/ast-extractor.test.js +64 -4
- package/dist/parsers/apex/__tests__/ast-extractor.test.js.map +1 -1
- package/dist/parsers/apex/__tests__/empty-body.test.d.ts +2 -0
- package/dist/parsers/apex/__tests__/empty-body.test.d.ts.map +1 -0
- package/dist/parsers/apex/__tests__/empty-body.test.js +40 -0
- package/dist/parsers/apex/__tests__/empty-body.test.js.map +1 -0
- package/dist/parsers/apex/__tests__/is-test-attribute.test.d.ts +2 -0
- package/dist/parsers/apex/__tests__/is-test-attribute.test.d.ts.map +1 -0
- package/dist/parsers/apex/__tests__/is-test-attribute.test.js +56 -0
- package/dist/parsers/apex/__tests__/is-test-attribute.test.js.map +1 -0
- package/dist/parsers/apex/__tests__/regex-arg-count.test.d.ts +2 -0
- package/dist/parsers/apex/__tests__/regex-arg-count.test.d.ts.map +1 -0
- package/dist/parsers/apex/__tests__/regex-arg-count.test.js +82 -0
- package/dist/parsers/apex/__tests__/regex-arg-count.test.js.map +1 -0
- package/dist/parsers/apex/__tests__/regex-inloop.test.d.ts +2 -0
- package/dist/parsers/apex/__tests__/regex-inloop.test.d.ts.map +1 -0
- package/dist/parsers/apex/__tests__/regex-inloop.test.js +70 -0
- package/dist/parsers/apex/__tests__/regex-inloop.test.js.map +1 -0
- package/dist/parsers/apex/arity-resolver.d.ts.map +1 -1
- package/dist/parsers/apex/arity-resolver.js.map +1 -1
- package/dist/parsers/apex/ast-extractor.d.ts.map +1 -1
- package/dist/parsers/apex/ast-extractor.js +33 -1
- package/dist/parsers/apex/ast-extractor.js.map +1 -1
- package/dist/parsers/apex/class.d.ts.map +1 -1
- package/dist/parsers/apex/class.js +162 -5
- package/dist/parsers/apex/class.js.map +1 -1
- package/dist/parsers/apex/trigger.d.ts.map +1 -1
- package/dist/parsers/apex/trigger.js +10 -0
- package/dist/parsers/apex/trigger.js.map +1 -1
- package/dist/parsers/common.d.ts +4 -1
- package/dist/parsers/common.d.ts.map +1 -1
- package/dist/parsers/common.js +15 -2
- package/dist/parsers/common.js.map +1 -1
- package/dist/parsers/flow/__tests__/invocable-resolver.test.js.map +1 -1
- package/dist/parsers/flow/invocable-resolver.d.ts.map +1 -1
- package/dist/parsers/flow/invocable-resolver.js.map +1 -1
- package/dist/parsers/generic/reflection-walker.d.ts +90 -0
- package/dist/parsers/generic/reflection-walker.d.ts.map +1 -0
- package/dist/parsers/generic/reflection-walker.js +193 -0
- package/dist/parsers/generic/reflection-walker.js.map +1 -0
- package/dist/parsers/lwc/html-visitor.d.ts.map +1 -1
- package/dist/parsers/lwc/html-visitor.js +82 -3
- package/dist/parsers/lwc/html-visitor.js.map +1 -1
- package/dist/parsers/lwc/js-visitor.d.ts.map +1 -1
- package/dist/parsers/lwc/js-visitor.js +6 -2
- package/dist/parsers/lwc/js-visitor.js.map +1 -1
- package/dist/parsers/object/object.d.ts.map +1 -1
- package/dist/parsers/object/object.js +35 -5
- package/dist/parsers/object/object.js.map +1 -1
- package/dist/parsers/omnistudio/data-transform.d.ts.map +1 -1
- package/dist/parsers/omnistudio/data-transform.js +39 -6
- package/dist/parsers/omnistudio/data-transform.js.map +1 -1
- package/dist/parsers/omnistudio/integration-procedure.d.ts.map +1 -1
- package/dist/parsers/omnistudio/integration-procedure.js +3 -2
- package/dist/parsers/omnistudio/integration-procedure.js.map +1 -1
- package/dist/parsers/omnistudio/overlap-detector.d.ts +50 -0
- package/dist/parsers/omnistudio/overlap-detector.d.ts.map +1 -0
- package/dist/parsers/omnistudio/overlap-detector.js +122 -0
- package/dist/parsers/omnistudio/overlap-detector.js.map +1 -0
- package/dist/parsers/omnistudio/process.d.ts.map +1 -1
- package/dist/parsers/omnistudio/process.js +3 -2
- package/dist/parsers/omnistudio/process.js.map +1 -1
- package/dist/parsers/omnistudio/ui-card.d.ts.map +1 -1
- package/dist/parsers/omnistudio/ui-card.js +3 -2
- package/dist/parsers/omnistudio/ui-card.js.map +1 -1
- package/dist/parsers/rules/custom-metadata-type.yml +7 -0
- package/dist/parsers/rules/custom-setting.yml +24 -0
- package/dist/parsers/vlocity/common.d.ts +16 -0
- package/dist/parsers/vlocity/common.d.ts.map +1 -1
- package/dist/parsers/vlocity/common.js +62 -0
- package/dist/parsers/vlocity/common.js.map +1 -1
- package/dist/parsers/vlocity/data-raptor.d.ts.map +1 -1
- package/dist/parsers/vlocity/data-raptor.js +43 -14
- package/dist/parsers/vlocity/data-raptor.js.map +1 -1
- package/dist/render/__tests__/sarif.test.d.ts +2 -0
- package/dist/render/__tests__/sarif.test.d.ts.map +1 -0
- package/dist/render/__tests__/sarif.test.js +126 -0
- package/dist/render/__tests__/sarif.test.js.map +1 -0
- package/dist/render/sarif.d.ts +94 -0
- package/dist/render/sarif.d.ts.map +1 -0
- package/dist/render/sarif.js +131 -0
- package/dist/render/sarif.js.map +1 -0
- package/dist/storage/__tests__/analysis-tables-migration.test.js +1 -1
- package/dist/storage/__tests__/graph-store.test.js +13 -0
- package/dist/storage/__tests__/graph-store.test.js.map +1 -1
- package/dist/storage/__tests__/migrations.test.js +4 -4
- package/dist/storage/__tests__/rename-stability.test.d.ts +2 -0
- package/dist/storage/__tests__/rename-stability.test.d.ts.map +1 -0
- package/dist/storage/__tests__/rename-stability.test.js +135 -0
- package/dist/storage/__tests__/rename-stability.test.js.map +1 -0
- package/dist/storage/__tests__/sync-generation.test.d.ts +2 -0
- package/dist/storage/__tests__/sync-generation.test.d.ts.map +1 -0
- package/dist/storage/__tests__/sync-generation.test.js +159 -0
- package/dist/storage/__tests__/sync-generation.test.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/interfaces.d.ts +60 -0
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage/sqlite/graph-store.d.ts +21 -1
- package/dist/storage/sqlite/graph-store.d.ts.map +1 -1
- package/dist/storage/sqlite/graph-store.js +86 -0
- package/dist/storage/sqlite/graph-store.js.map +1 -1
- package/dist/storage/sqlite/migrations.d.ts.map +1 -1
- package/dist/storage/sqlite/migrations.js +38 -0
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/rename-stability.d.ts +94 -0
- package/dist/storage/sqlite/rename-stability.d.ts.map +1 -0
- package/dist/storage/sqlite/rename-stability.js +92 -0
- package/dist/storage/sqlite/rename-stability.js.map +1 -0
- package/package.json +4 -1
|
@@ -25,6 +25,16 @@ export interface DanglingEdgeSample {
|
|
|
25
25
|
export interface AuditResult {
|
|
26
26
|
totalEdges: number;
|
|
27
27
|
danglingCount: number;
|
|
28
|
+
/** Dangling edges whose dst is a platform built-in that can never have a
|
|
29
|
+
* metadata source: standard tabs (`CustomTab:standard-*`) and fields /
|
|
30
|
+
* objects of standard-schema entities (no `__c`/`__mdt`/… suffix).
|
|
31
|
+
* These are *expected* — the reference data is real and useful (e.g.
|
|
32
|
+
* profile tab visibility), the target just isn't org metadata. Included
|
|
33
|
+
* in `danglingCount`; broken out so the headline number isn't dominated
|
|
34
|
+
* by ~60k standard-tab grants on a vanilla org. */
|
|
35
|
+
platformRefCount: number;
|
|
36
|
+
/** danglingCount - platformRefCount: the subset worth investigating. */
|
|
37
|
+
unexpectedCount: number;
|
|
28
38
|
byRel: Record<string, number>;
|
|
29
39
|
byDstPrefix: Record<string, number>;
|
|
30
40
|
sample: DanglingEdgeSample[];
|
|
@@ -35,14 +45,28 @@ export interface AuditOpts {
|
|
|
35
45
|
/** Hard upper bound on rows scanned per edge table. Default unlimited. */
|
|
36
46
|
scanLimit?: number;
|
|
37
47
|
}
|
|
48
|
+
/** True when a dangling dst names a platform built-in that no extractor can
|
|
49
|
+
* ever materialize: standard tabs, or fields/objects of standard-schema
|
|
50
|
+
* entities (Incident, Location, Case, …) the org metadata pass doesn't
|
|
51
|
+
* enumerate. Custom-suffixed targets are NEVER platform refs — a missing
|
|
52
|
+
* `__c` target is a real gap worth surfacing. */
|
|
53
|
+
export declare function isPlatformBuiltinRef(dst: string): boolean;
|
|
38
54
|
export declare function auditDanglingEdges(store: GraphStore, orgIdIn: OrgId | string, opts?: AuditOpts): AuditResult;
|
|
39
55
|
/**
|
|
40
|
-
* Destructive companion to `auditDanglingEdges`: deletes
|
|
56
|
+
* Destructive companion to `auditDanglingEdges`: deletes dangling edges.
|
|
41
57
|
* Reserved for the CLI `--delete-dangling --yes` flag; callers must own the
|
|
42
58
|
* authorization decision (we just do the work).
|
|
59
|
+
*
|
|
60
|
+
* Platform-builtin references (standard-tab grants, standard-schema field
|
|
61
|
+
* grants) are KEPT by default — they're real, queryable security data whose
|
|
62
|
+
* target simply has no metadata source. Pass `includePlatformRefs: true` to
|
|
63
|
+
* delete those too.
|
|
43
64
|
*/
|
|
44
|
-
export declare function deleteDanglingEdges(store: GraphStore, orgIdIn: OrgId | string
|
|
65
|
+
export declare function deleteDanglingEdges(store: GraphStore, orgIdIn: OrgId | string, opts?: {
|
|
66
|
+
includePlatformRefs?: boolean;
|
|
67
|
+
}): {
|
|
45
68
|
deleted: number;
|
|
69
|
+
keptPlatformRefs: number;
|
|
46
70
|
};
|
|
47
71
|
export type { EdgeFact };
|
|
48
72
|
//# sourceMappingURL=audit-graph.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-graph.d.ts","sourceRoot":"","sources":["../../src/analyze/audit-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"audit-graph.d.ts","sourceRoot":"","sources":["../../src/analyze/audit-graph.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAW,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;wDAMoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,SAAS;IACxB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD;;;;kDAIkD;AAClD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAczD;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,KAAK,GAAG,MAAM,EACvB,IAAI,GAAE,SAAc,GACnB,WAAW,CA2Cb;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,KAAK,GAAG,MAAM,EACvB,IAAI,GAAE;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3C;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAqB/C;AAED,YAAY,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -3,6 +3,29 @@ function prefix(qname) {
|
|
|
3
3
|
const idx = qname.indexOf(":");
|
|
4
4
|
return idx > 0 ? qname.slice(0, idx) : "(unlabeled)";
|
|
5
5
|
}
|
|
6
|
+
const CUSTOM_SUFFIX_RE = /__(?:c|e|b|mdt|x|kav)$/i;
|
|
7
|
+
/** True when a dangling dst names a platform built-in that no extractor can
|
|
8
|
+
* ever materialize: standard tabs, or fields/objects of standard-schema
|
|
9
|
+
* entities (Incident, Location, Case, …) the org metadata pass doesn't
|
|
10
|
+
* enumerate. Custom-suffixed targets are NEVER platform refs — a missing
|
|
11
|
+
* `__c` target is a real gap worth surfacing. */
|
|
12
|
+
export function isPlatformBuiltinRef(dst) {
|
|
13
|
+
if (dst.startsWith("CustomTab:standard-"))
|
|
14
|
+
return true;
|
|
15
|
+
if (dst.startsWith("CustomField:")) {
|
|
16
|
+
const rest = dst.slice("CustomField:".length);
|
|
17
|
+
const dot = rest.indexOf(".");
|
|
18
|
+
if (dot <= 0)
|
|
19
|
+
return false;
|
|
20
|
+
const obj = rest.slice(0, dot);
|
|
21
|
+
const field = rest.slice(dot + 1);
|
|
22
|
+
return !CUSTOM_SUFFIX_RE.test(obj) && !CUSTOM_SUFFIX_RE.test(field);
|
|
23
|
+
}
|
|
24
|
+
if (dst.startsWith("CustomObject:")) {
|
|
25
|
+
return !CUSTOM_SUFFIX_RE.test(dst.slice("CustomObject:".length));
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
6
29
|
export function auditDanglingEdges(store, orgIdIn, opts = {}) {
|
|
7
30
|
const orgId = typeof orgIdIn === "string" ? asOrgId(orgIdIn) : orgIdIn;
|
|
8
31
|
// Clamp to ≥0; a negative slice index would silently return a tail of the
|
|
@@ -12,12 +35,24 @@ export function auditDanglingEdges(store, orgIdIn, opts = {}) {
|
|
|
12
35
|
const dangling = store.listDanglingEdges(orgId, opts.scanLimit);
|
|
13
36
|
const byRel = {};
|
|
14
37
|
const byDstPrefix = {};
|
|
38
|
+
let platformRefCount = 0;
|
|
15
39
|
for (const e of dangling) {
|
|
16
40
|
byRel[e.relType] = (byRel[e.relType] ?? 0) + 1;
|
|
17
|
-
const
|
|
41
|
+
const dst = String(e.dstQualifiedName);
|
|
42
|
+
const p = prefix(dst);
|
|
18
43
|
byDstPrefix[p] = (byDstPrefix[p] ?? 0) + 1;
|
|
44
|
+
if (isPlatformBuiltinRef(dst))
|
|
45
|
+
platformRefCount += 1;
|
|
19
46
|
}
|
|
20
|
-
|
|
47
|
+
// Sample the *unexpected* dangling edges first — those are the ones a
|
|
48
|
+
// user can act on; platform refs only pad the sample once the unexpected
|
|
49
|
+
// set is smaller than sampleSize.
|
|
50
|
+
const unexpectedFirst = [...dangling].sort((a, b) => {
|
|
51
|
+
const ap = isPlatformBuiltinRef(String(a.dstQualifiedName)) ? 1 : 0;
|
|
52
|
+
const bp = isPlatformBuiltinRef(String(b.dstQualifiedName)) ? 1 : 0;
|
|
53
|
+
return ap - bp;
|
|
54
|
+
});
|
|
55
|
+
const sample = unexpectedFirst.slice(0, sampleSize).map((e) => ({
|
|
21
56
|
src: String(e.srcQualifiedName),
|
|
22
57
|
rel: String(e.relType),
|
|
23
58
|
dst: String(e.dstQualifiedName),
|
|
@@ -25,26 +60,38 @@ export function auditDanglingEdges(store, orgIdIn, opts = {}) {
|
|
|
25
60
|
return {
|
|
26
61
|
totalEdges,
|
|
27
62
|
danglingCount: dangling.length,
|
|
63
|
+
platformRefCount,
|
|
64
|
+
unexpectedCount: dangling.length - platformRefCount,
|
|
28
65
|
byRel,
|
|
29
66
|
byDstPrefix,
|
|
30
67
|
sample,
|
|
31
68
|
};
|
|
32
69
|
}
|
|
33
70
|
/**
|
|
34
|
-
* Destructive companion to `auditDanglingEdges`: deletes
|
|
71
|
+
* Destructive companion to `auditDanglingEdges`: deletes dangling edges.
|
|
35
72
|
* Reserved for the CLI `--delete-dangling --yes` flag; callers must own the
|
|
36
73
|
* authorization decision (we just do the work).
|
|
74
|
+
*
|
|
75
|
+
* Platform-builtin references (standard-tab grants, standard-schema field
|
|
76
|
+
* grants) are KEPT by default — they're real, queryable security data whose
|
|
77
|
+
* target simply has no metadata source. Pass `includePlatformRefs: true` to
|
|
78
|
+
* delete those too.
|
|
37
79
|
*/
|
|
38
|
-
export function deleteDanglingEdges(store, orgIdIn) {
|
|
80
|
+
export function deleteDanglingEdges(store, orgIdIn, opts = {}) {
|
|
39
81
|
const orgId = typeof orgIdIn === "string" ? asOrgId(orgIdIn) : orgIdIn;
|
|
40
82
|
const dangling = store.listDanglingEdges(orgId);
|
|
41
83
|
let deleted = 0;
|
|
84
|
+
let keptPlatformRefs = 0;
|
|
42
85
|
store.transaction(() => {
|
|
43
86
|
for (const e of dangling) {
|
|
87
|
+
if (!opts.includePlatformRefs && isPlatformBuiltinRef(String(e.dstQualifiedName))) {
|
|
88
|
+
keptPlatformRefs += 1;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
44
91
|
store.deleteEdge(orgId, e.srcQualifiedName, e.dstQualifiedName, e.relType);
|
|
45
92
|
deleted += 1;
|
|
46
93
|
}
|
|
47
94
|
});
|
|
48
|
-
return { deleted };
|
|
95
|
+
return { deleted, keptPlatformRefs };
|
|
49
96
|
}
|
|
50
97
|
//# sourceMappingURL=audit-graph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit-graph.js","sourceRoot":"","sources":["../../src/analyze/audit-graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"audit-graph.js","sourceRoot":"","sources":["../../src/analyze/audit-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { OrgId, QualifiedName } from "@ryanstark24/sfgraph-shared";
|
|
2
2
|
import type { GraphStore } from "../storage/interfaces.js";
|
|
3
|
-
import { type TraversalResult } from "./dependents.js";
|
|
4
|
-
export declare function findDependencies(store: GraphStore, orgId: OrgId, qname: QualifiedName, depth?: number): TraversalResult;
|
|
3
|
+
import { type TraversalOpts, type TraversalResult } from "./dependents.js";
|
|
4
|
+
export declare function findDependencies(store: GraphStore, orgId: OrgId, qname: QualifiedName, depth?: number, opts?: TraversalOpts): TraversalResult;
|
|
5
5
|
//# sourceMappingURL=dependencies.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/analyze/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,
|
|
1
|
+
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/analyze/dependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAUzB,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,aAAa,EACpB,KAAK,SAAI,EACT,IAAI,GAAE,aAAkB,GACvB,eAAe,CAkCjB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { TRAVERSAL_NODE_CAP_DEFAULT } from "./dependents.js";
|
|
1
|
+
import { TRAVERSAL_NODE_CAP_DEFAULT, } from "./dependents.js";
|
|
2
|
+
import { keepEdge } from "./edge-filters.js";
|
|
2
3
|
function nodeCap() {
|
|
3
4
|
const raw = process.env.SFGRAPH_TRAVERSAL_NODE_CAP;
|
|
4
5
|
if (!raw)
|
|
@@ -6,7 +7,7 @@ function nodeCap() {
|
|
|
6
7
|
const n = Number.parseInt(raw, 10);
|
|
7
8
|
return Number.isFinite(n) && n > 0 ? n : TRAVERSAL_NODE_CAP_DEFAULT;
|
|
8
9
|
}
|
|
9
|
-
export function findDependencies(store, orgId, qname, depth = 3) {
|
|
10
|
+
export function findDependencies(store, orgId, qname, depth = 3, opts = {}) {
|
|
10
11
|
const cap = nodeCap();
|
|
11
12
|
const visited = new Set();
|
|
12
13
|
const nodes = [];
|
|
@@ -14,11 +15,16 @@ export function findDependencies(store, orgId, qname, depth = 3) {
|
|
|
14
15
|
let frontier = [qname];
|
|
15
16
|
visited.add(qname);
|
|
16
17
|
let truncated = false;
|
|
18
|
+
let filtered = 0;
|
|
17
19
|
bfs: for (let d = 0; d < depth && frontier.length > 0; d++) {
|
|
18
20
|
const next = [];
|
|
19
21
|
for (const cur of frontier) {
|
|
20
22
|
const outgoing = store.listEdgesFrom(orgId, cur);
|
|
21
23
|
for (const e of outgoing) {
|
|
24
|
+
if (!keepEdge(e, opts)) {
|
|
25
|
+
filtered += 1;
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
22
28
|
edges.push(e);
|
|
23
29
|
if (!visited.has(e.dstQualifiedName)) {
|
|
24
30
|
visited.add(e.dstQualifiedName);
|
|
@@ -35,6 +41,6 @@ export function findDependencies(store, orgId, qname, depth = 3) {
|
|
|
35
41
|
}
|
|
36
42
|
frontier = next;
|
|
37
43
|
}
|
|
38
|
-
return { nodes, edges, truncated };
|
|
44
|
+
return { nodes, edges, truncated, filtered };
|
|
39
45
|
}
|
|
40
46
|
//# sourceMappingURL=dependencies.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/analyze/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/analyze/dependencies.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,0BAA0B,GAG3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,SAAS,OAAO;IACd,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACnD,IAAI,CAAC,GAAG;QAAE,OAAO,0BAA0B,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,KAAiB,EACjB,KAAY,EACZ,KAAoB,EACpB,KAAK,GAAG,CAAC,EACT,OAAsB,EAAE;IAExB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAoB,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACjD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;oBACvB,QAAQ,IAAI,CAAC,CAAC;oBACd,SAAS;gBACX,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBACrC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBAChC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBACnD,IAAI,CAAC;wBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBAC9B,IAAI,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;wBACxB,SAAS,GAAG,IAAI,CAAC;wBACjB,MAAM,GAAG,CAAC;oBACZ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import type { OrgId, QualifiedName } from "@ryanstark24/sfgraph-shared";
|
|
2
2
|
import type { EdgeFact, NodeFact } from "../domain/index.js";
|
|
3
3
|
import type { GraphStore } from "../storage/interfaces.js";
|
|
4
|
+
import { type EdgeFilterOpts } from "./edge-filters.js";
|
|
4
5
|
export interface TraversalResult {
|
|
5
6
|
nodes: NodeFact[];
|
|
6
7
|
edges: EdgeFact[];
|
|
7
8
|
/** Set when the traversal hit `NODE_CAP` before exhausting the graph. */
|
|
8
9
|
truncated?: boolean;
|
|
10
|
+
/** Edges dropped by the relType/security/reflection filter — surfaced so
|
|
11
|
+
* the tool can tell the user "N security/inferred edges hidden". */
|
|
12
|
+
filtered?: number;
|
|
9
13
|
}
|
|
14
|
+
export type TraversalOpts = EdgeFilterOpts;
|
|
10
15
|
/**
|
|
11
16
|
* Hard ceiling on visited nodes per traversal. Prevents an agent — or a
|
|
12
17
|
* crafted call — from blowing memory by asking for depth=5 on a hub like
|
|
@@ -15,5 +20,5 @@ export interface TraversalResult {
|
|
|
15
20
|
* Override via `TRAVERSAL_NODE_CAP` env var if you really need more.
|
|
16
21
|
*/
|
|
17
22
|
export declare const TRAVERSAL_NODE_CAP_DEFAULT = 500;
|
|
18
|
-
export declare function findDependents(store: GraphStore, orgId: OrgId, qname: QualifiedName, depth?: number): TraversalResult;
|
|
23
|
+
export declare function findDependents(store: GraphStore, orgId: OrgId, qname: QualifiedName, depth?: number, opts?: TraversalOpts): TraversalResult;
|
|
19
24
|
//# sourceMappingURL=dependents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependents.d.ts","sourceRoot":"","sources":["../../src/analyze/dependents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"dependents.d.ts","sourceRoot":"","sources":["../../src/analyze/dependents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,KAAK,cAAc,EAAY,MAAM,mBAAmB,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;yEACqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAE3C;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAQ9C,wBAAgB,cAAc,CAC5B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,aAAa,EACpB,KAAK,SAAI,EACT,IAAI,GAAE,aAAkB,GACvB,eAAe,CAsCjB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { keepEdge } from "./edge-filters.js";
|
|
1
2
|
/**
|
|
2
3
|
* Hard ceiling on visited nodes per traversal. Prevents an agent — or a
|
|
3
4
|
* crafted call — from blowing memory by asking for depth=5 on a hub like
|
|
@@ -13,7 +14,7 @@ function nodeCap() {
|
|
|
13
14
|
const n = Number.parseInt(raw, 10);
|
|
14
15
|
return Number.isFinite(n) && n > 0 ? n : TRAVERSAL_NODE_CAP_DEFAULT;
|
|
15
16
|
}
|
|
16
|
-
export function findDependents(store, orgId, qname, depth = 3) {
|
|
17
|
+
export function findDependents(store, orgId, qname, depth = 3, opts = {}) {
|
|
17
18
|
const cap = nodeCap();
|
|
18
19
|
const visited = new Set();
|
|
19
20
|
const nodes = [];
|
|
@@ -21,11 +22,20 @@ export function findDependents(store, orgId, qname, depth = 3) {
|
|
|
21
22
|
let frontier = [qname];
|
|
22
23
|
visited.add(qname);
|
|
23
24
|
let truncated = false;
|
|
25
|
+
let filtered = 0;
|
|
24
26
|
bfs: for (let d = 0; d < depth && frontier.length > 0; d++) {
|
|
25
27
|
const next = [];
|
|
26
28
|
for (const cur of frontier) {
|
|
27
29
|
const incoming = store.listEdgesTo(orgId, cur);
|
|
28
30
|
for (const e of incoming) {
|
|
31
|
+
// Filter noise (security grants / reflection inferences) before the
|
|
32
|
+
// edge contributes a node — otherwise a hub like a class granted to
|
|
33
|
+
// 100+ profiles blows the node cap on grant edges alone and the real
|
|
34
|
+
// dependency frontier never gets explored.
|
|
35
|
+
if (!keepEdge(e, opts)) {
|
|
36
|
+
filtered += 1;
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
29
39
|
edges.push(e);
|
|
30
40
|
if (!visited.has(e.srcQualifiedName)) {
|
|
31
41
|
visited.add(e.srcQualifiedName);
|
|
@@ -42,6 +52,6 @@ export function findDependents(store, orgId, qname, depth = 3) {
|
|
|
42
52
|
}
|
|
43
53
|
frontier = next;
|
|
44
54
|
}
|
|
45
|
-
return { nodes, edges, truncated };
|
|
55
|
+
return { nodes, edges, truncated, filtered };
|
|
46
56
|
}
|
|
47
57
|
//# sourceMappingURL=dependents.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependents.js","sourceRoot":"","sources":["../../src/analyze/dependents.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dependents.js","sourceRoot":"","sources":["../../src/analyze/dependents.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAclE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAC9C,SAAS,OAAO;IACd,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;IACnD,IAAI,CAAC,GAAG;QAAE,OAAO,0BAA0B,CAAC;IAC5C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAAiB,EACjB,KAAY,EACZ,KAAoB,EACpB,KAAK,GAAG,CAAC,EACT,OAAsB,EAAE;IAExB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAoB,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAoB,EAAE,CAAC;QACjC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,oEAAoE;gBACpE,oEAAoE;gBACpE,qEAAqE;gBACrE,2CAA2C;gBAC3C,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;oBACvB,QAAQ,IAAI,CAAC,CAAC;oBACd,SAAS;gBACX,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBACrC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBAChC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBACnD,IAAI,CAAC;wBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;oBAC9B,IAAI,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,CAAC;wBACxB,SAAS,GAAG,IAAI,CAAC;wBACjB,MAAM,GAAG,CAAC;oBACZ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ,GAAG,IAAI,CAAC;IAClB,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EdgeFact } from "../domain/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Edge classification + filtering shared by the traversal tools
|
|
4
|
+
* (trace_upstream / trace_downstream).
|
|
5
|
+
*
|
|
6
|
+
* Real-org traces are dominated by two kinds of edge that are technically
|
|
7
|
+
* correct but almost never what "what depends on X / what does X depend on"
|
|
8
|
+
* is asking for:
|
|
9
|
+
*
|
|
10
|
+
* 1. Security grants — every Profile/PermissionSet that can see an Apex
|
|
11
|
+
* class emits a GRANTS_APEX_ACCESS edge. A class used by 111 profiles
|
|
12
|
+
* buries its single IS_TEST_FOR / CALLS edge under 111 grant edges.
|
|
13
|
+
* 2. Reflection-walker inferences — low-confidence REFERENCES edges tagged
|
|
14
|
+
* `source: "reflection"`, emitted when a node's blob string happens to
|
|
15
|
+
* match another node's bare name. On Vlocity nodes these produce
|
|
16
|
+
* spurious links like DataRaptor:Foo → CustomApplication:DataRaptor.
|
|
17
|
+
*
|
|
18
|
+
* Dependency/dependent traces exclude both by default; callers can opt back
|
|
19
|
+
* in (a dedicated security view, or "show inferred references").
|
|
20
|
+
*/
|
|
21
|
+
/** Security / sharing grant edges — relationship of access, not of code dependency. */
|
|
22
|
+
export declare const SECURITY_GRANT_RELTYPES: ReadonlySet<string>;
|
|
23
|
+
/** True for a low-confidence reflection-walker REFERENCES edge. */
|
|
24
|
+
export declare function isReflectionEdge(e: EdgeFact): boolean;
|
|
25
|
+
export interface EdgeFilterOpts {
|
|
26
|
+
/** Only keep these relTypes (applied before excludes). */
|
|
27
|
+
includeRelTypes?: ReadonlySet<string>;
|
|
28
|
+
/** Drop these relTypes. */
|
|
29
|
+
excludeRelTypes?: ReadonlySet<string>;
|
|
30
|
+
/** Drop security/sharing grant edges. Default true for dependency traces. */
|
|
31
|
+
excludeSecurity?: boolean;
|
|
32
|
+
/** Drop reflection-inferred REFERENCES edges. Default true for traces. */
|
|
33
|
+
excludeReflection?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** Decide whether an edge survives the filter. */
|
|
36
|
+
export declare function keepEdge(e: EdgeFact, opts: EdgeFilterOpts): boolean;
|
|
37
|
+
//# sourceMappingURL=edge-filters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-filters.d.ts","sourceRoot":"","sources":["../../src/analyze/edge-filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;;;;;;;;;;;;;;;;;GAkBG;AAEH,uFAAuF;AACvF,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAWtD,CAAC;AAEH,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,GAAG,OAAO,CAKrD;AAED,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,2BAA2B;IAC3B,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,6EAA6E;IAC7E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,kDAAkD;AAClD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAMnE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { REL_TYPES } from "../domain/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Edge classification + filtering shared by the traversal tools
|
|
4
|
+
* (trace_upstream / trace_downstream).
|
|
5
|
+
*
|
|
6
|
+
* Real-org traces are dominated by two kinds of edge that are technically
|
|
7
|
+
* correct but almost never what "what depends on X / what does X depend on"
|
|
8
|
+
* is asking for:
|
|
9
|
+
*
|
|
10
|
+
* 1. Security grants — every Profile/PermissionSet that can see an Apex
|
|
11
|
+
* class emits a GRANTS_APEX_ACCESS edge. A class used by 111 profiles
|
|
12
|
+
* buries its single IS_TEST_FOR / CALLS edge under 111 grant edges.
|
|
13
|
+
* 2. Reflection-walker inferences — low-confidence REFERENCES edges tagged
|
|
14
|
+
* `source: "reflection"`, emitted when a node's blob string happens to
|
|
15
|
+
* match another node's bare name. On Vlocity nodes these produce
|
|
16
|
+
* spurious links like DataRaptor:Foo → CustomApplication:DataRaptor.
|
|
17
|
+
*
|
|
18
|
+
* Dependency/dependent traces exclude both by default; callers can opt back
|
|
19
|
+
* in (a dedicated security view, or "show inferred references").
|
|
20
|
+
*/
|
|
21
|
+
/** Security / sharing grant edges — relationship of access, not of code dependency. */
|
|
22
|
+
export const SECURITY_GRANT_RELTYPES = new Set([
|
|
23
|
+
REL_TYPES.GRANTS_OBJECT_ACCESS,
|
|
24
|
+
REL_TYPES.GRANTS_FIELD_ACCESS,
|
|
25
|
+
REL_TYPES.GRANTS_APEX_ACCESS,
|
|
26
|
+
REL_TYPES.GRANTS_PAGE_ACCESS,
|
|
27
|
+
REL_TYPES.GRANTS_TAB_ACCESS,
|
|
28
|
+
REL_TYPES.GRANTS_USER_PERMISSION,
|
|
29
|
+
REL_TYPES.SHARING_GRANTS,
|
|
30
|
+
REL_TYPES.SHARING_TO_GROUP,
|
|
31
|
+
REL_TYPES.SHARING_TO_ROLE,
|
|
32
|
+
REL_TYPES.SHARING_FROM_OWNER_GROUP,
|
|
33
|
+
]);
|
|
34
|
+
/** True for a low-confidence reflection-walker REFERENCES edge. */
|
|
35
|
+
export function isReflectionEdge(e) {
|
|
36
|
+
return (e.relType === REL_TYPES.REFERENCES &&
|
|
37
|
+
e.attributes?.source === "reflection");
|
|
38
|
+
}
|
|
39
|
+
/** Decide whether an edge survives the filter. */
|
|
40
|
+
export function keepEdge(e, opts) {
|
|
41
|
+
if (opts.includeRelTypes && !opts.includeRelTypes.has(e.relType))
|
|
42
|
+
return false;
|
|
43
|
+
if (opts.excludeRelTypes?.has(e.relType))
|
|
44
|
+
return false;
|
|
45
|
+
if (opts.excludeSecurity !== false && SECURITY_GRANT_RELTYPES.has(e.relType))
|
|
46
|
+
return false;
|
|
47
|
+
if (opts.excludeReflection !== false && isReflectionEdge(e))
|
|
48
|
+
return false;
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=edge-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-filters.js","sourceRoot":"","sources":["../../src/analyze/edge-filters.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;GAkBG;AAEH,uFAAuF;AACvF,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC;IAClE,SAAS,CAAC,oBAAoB;IAC9B,SAAS,CAAC,mBAAmB;IAC7B,SAAS,CAAC,kBAAkB;IAC5B,SAAS,CAAC,kBAAkB;IAC5B,SAAS,CAAC,iBAAiB;IAC3B,SAAS,CAAC,sBAAsB;IAChC,SAAS,CAAC,cAAc;IACxB,SAAS,CAAC,gBAAgB;IAC1B,SAAS,CAAC,eAAe;IACzB,SAAS,CAAC,wBAAwB;CACnC,CAAC,CAAC;AAEH,mEAAmE;AACnE,MAAM,UAAU,gBAAgB,CAAC,CAAW;IAC1C,OAAO,CACL,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,UAAU;QACjC,CAAC,CAAC,UAA+C,EAAE,MAAM,KAAK,YAAY,CAC5E,CAAC;AACJ,CAAC;AAaD,kDAAkD;AAClD,MAAM,UAAU,QAAQ,CAAC,CAAW,EAAE,IAAoB;IACxD,IAAI,IAAI,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/E,IAAI,IAAI,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK,IAAI,uBAAuB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3F,IAAI,IAAI,CAAC,iBAAiB,KAAK,KAAK,IAAI,gBAAgB,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1E,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { OrgId } from "@ryanstark24/sfgraph-shared";
|
|
2
|
+
import type { NodeFact } from "../domain/index.js";
|
|
3
|
+
import type { GraphStore } from "../storage/interfaces.js";
|
|
4
|
+
/**
|
|
5
|
+
* Glob-pattern node lookup. Patterns use the conventional shell glob
|
|
6
|
+
* vocabulary (handled by picomatch):
|
|
7
|
+
*
|
|
8
|
+
* - `*` matches any non-separator characters
|
|
9
|
+
* - `?` matches a single character
|
|
10
|
+
* - `**` matches zero or more segments (separator = `.`)
|
|
11
|
+
* - `[abc]` / `[a-z]` character classes
|
|
12
|
+
* - `{a,b}` brace expansion
|
|
13
|
+
*
|
|
14
|
+
* The separator is `.` not `/` — node qualified names like
|
|
15
|
+
* `CustomField:Account.Name` make a dot-separator more natural than the
|
|
16
|
+
* Unix path-style. picomatch is configured accordingly.
|
|
17
|
+
*
|
|
18
|
+
* Result ordering: lexicographic by qualifiedName. The cap defaults to
|
|
19
|
+
* 500 with `truncated: true` set on overflow — at that scale the agent
|
|
20
|
+
* should refine the pattern rather than scan further.
|
|
21
|
+
*/
|
|
22
|
+
export interface FindNodesOpts {
|
|
23
|
+
/** When set, restrict matching to nodes of this label (e.g. `ApexClass`,
|
|
24
|
+
* `CustomField`). Faster than scanning every label table when the
|
|
25
|
+
* pattern is type-anchored. */
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Result cap. Default 500. */
|
|
28
|
+
limit?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface FindNodesResult {
|
|
31
|
+
matches: NodeFact[];
|
|
32
|
+
truncated: boolean;
|
|
33
|
+
/** Total matched before truncation (when truncated=false, equals
|
|
34
|
+
* matches.length). */
|
|
35
|
+
total: number;
|
|
36
|
+
}
|
|
37
|
+
export declare function findNodesByGlob(store: GraphStore, orgId: OrgId, pattern: string, opts?: FindNodesOpts): FindNodesResult;
|
|
38
|
+
//# sourceMappingURL=find-nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-nodes.d.ts","sourceRoot":"","sources":["../../src/analyze/find-nodes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,aAAa;IAC5B;;oCAEgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB;2BACuB;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,UAAU,EACjB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,aAAkB,GACvB,eAAe,CAkCjB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import picomatch from "picomatch";
|
|
2
|
+
export function findNodesByGlob(store, orgId, pattern, opts = {}) {
|
|
3
|
+
const limit = Math.max(1, opts.limit ?? 500);
|
|
4
|
+
const matcher = picomatch(pattern, {
|
|
5
|
+
// Treat `.` as the separator so `apex.Class.*` matches everything inside
|
|
6
|
+
// the apex.Class.* namespace and `**` crosses dots.
|
|
7
|
+
dot: true,
|
|
8
|
+
nocase: false,
|
|
9
|
+
contains: false,
|
|
10
|
+
// Don't expand globstar to filesystem semantics — we just want it as
|
|
11
|
+
// "zero or more segments at this position."
|
|
12
|
+
bash: false,
|
|
13
|
+
});
|
|
14
|
+
const labels = opts.label ? [opts.label] : listAllLabels(store, orgId);
|
|
15
|
+
const allMatches = [];
|
|
16
|
+
for (const label of labels) {
|
|
17
|
+
// listNodesByLabel pages internally; passing a generous cap avoids
|
|
18
|
+
// truncation at the label level while still bounding memory on
|
|
19
|
+
// pathologically large labels (Salesforce orgs with 50k+ ApexClass
|
|
20
|
+
// nodes exist).
|
|
21
|
+
const nodes = store.listNodesByLabel(orgId, label, 50_000);
|
|
22
|
+
for (const n of nodes) {
|
|
23
|
+
if (matcher(String(n.qualifiedName)))
|
|
24
|
+
allMatches.push(n);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
allMatches.sort((a, b) => String(a.qualifiedName).localeCompare(String(b.qualifiedName)));
|
|
28
|
+
const truncated = allMatches.length > limit;
|
|
29
|
+
return {
|
|
30
|
+
matches: truncated ? allMatches.slice(0, limit) : allMatches,
|
|
31
|
+
truncated,
|
|
32
|
+
total: allMatches.length,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* List every distinct label the store knows about for this org. The
|
|
37
|
+
* GraphStore interface doesn't expose this directly; we read the
|
|
38
|
+
* label registry table that ensureNodeTable populates. Falls back to
|
|
39
|
+
* an empty list when the store doesn't expose the helper — caller can
|
|
40
|
+
* pass an explicit `label` to bypass.
|
|
41
|
+
*/
|
|
42
|
+
function listAllLabels(store, _orgId) {
|
|
43
|
+
// The SqliteGraphStore exposes a private nodeLabelCache; we read it
|
|
44
|
+
// through the public `listAllLabels()` method if present. Stores that
|
|
45
|
+
// don't implement it (test mocks) return [].
|
|
46
|
+
const s = store;
|
|
47
|
+
if (typeof s.listAllLabels === "function")
|
|
48
|
+
return s.listAllLabels();
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=find-nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-nodes.js","sourceRoot":"","sources":["../../src/analyze/find-nodes.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,WAAW,CAAC;AAwClC,MAAM,UAAU,eAAe,CAC7B,KAAiB,EACjB,KAAY,EACZ,OAAe,EACf,OAAsB,EAAE;IAExB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE;QACjC,yEAAyE;QACzE,oDAAoD;QACpD,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,KAAK;QACf,qEAAqE;QACrE,4CAA4C;QAC5C,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACvE,MAAM,UAAU,GAAe,EAAE,CAAC;IAElC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,mEAAmE;QACnE,+DAA+D;QAC/D,mEAAmE;QACnE,gBAAgB;QAChB,MAAM,KAAK,GAAG,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IAC1F,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC;IAC5C,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU;QAC5D,SAAS;QACT,KAAK,EAAE,UAAU,CAAC,MAAM;KACzB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,KAAiB,EAAE,MAAa;IACrD,oEAAoE;IACpE,sEAAsE;IACtE,6CAA6C;IAC7C,MAAM,CAAC,GAAG,KAAsD,CAAC;IACjE,IAAI,OAAO,CAAC,CAAC,aAAa,KAAK,UAAU;QAAE,OAAO,CAAC,CAAC,aAAa,EAAE,CAAC;IACpE,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical finding shape for everything in sfgraph that produces
|
|
3
|
+
* actionable diagnostics: governor-risk scan, security audit, dead-code
|
|
4
|
+
* audit, dangling-edge audit, future rule-engine outputs. Aligned with
|
|
5
|
+
* PMD's rule metadata vocabulary (name / message / description /
|
|
6
|
+
* priority / externalInfoUrl / properties) so the SARIF emitter can
|
|
7
|
+
* map a single shape rather than a switch over every producer.
|
|
8
|
+
*
|
|
9
|
+
* NOTE: the YAML files in parsers/rules/* are NOT lint rules — they're
|
|
10
|
+
* declarative metadata-to-graph extraction shortcuts. The Wave 3 plan's
|
|
11
|
+
* "PMD-aligned YAML rule schema" was a category error from the
|
|
12
|
+
* competitive analysis. The real PMD-aligned schema is this Finding
|
|
13
|
+
* type plus the rule catalog below — the producers stay where they are
|
|
14
|
+
* (analyze/governor.ts, analyze/security.ts, etc.) and emit Findings
|
|
15
|
+
* via the adapters in `findingAdapters` below.
|
|
16
|
+
*/
|
|
17
|
+
export type Severity = "error" | "warning" | "note";
|
|
18
|
+
export interface FindingLocation {
|
|
19
|
+
/** Graph node qualified name that the finding is anchored to. */
|
|
20
|
+
qualifiedName: string;
|
|
21
|
+
/** Optional: file URI when the finding maps to a parsed source artifact. */
|
|
22
|
+
sourceUri?: string;
|
|
23
|
+
/** Optional: 1-indexed line / column for SARIF physicalLocation. */
|
|
24
|
+
line?: number;
|
|
25
|
+
column?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface Finding {
|
|
28
|
+
/** PMD-style stable rule identifier, e.g. `governor.soql-in-loop`. */
|
|
29
|
+
ruleId: string;
|
|
30
|
+
/** One-line problem statement shown verbatim in SARIF / IDE diagnostics. */
|
|
31
|
+
message: string;
|
|
32
|
+
level: Severity;
|
|
33
|
+
/** Where the finding lives in the graph (and optionally in source). */
|
|
34
|
+
location: FindingLocation;
|
|
35
|
+
/** Free-form key/value pairs for downstream consumers (SARIF
|
|
36
|
+
* `properties` bag carries this verbatim). */
|
|
37
|
+
properties?: Record<string, string | number | boolean | null>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Static catalog of every rule sfgraph emits today. SARIF requires a rule
|
|
41
|
+
* definition (`reportingDescriptor`) for each unique `ruleId` referenced
|
|
42
|
+
* by a result, so we index findings against this map at emit time. New
|
|
43
|
+
* audits register their ruleIds here so SARIF stays valid without per-emit
|
|
44
|
+
* boilerplate.
|
|
45
|
+
*
|
|
46
|
+
* Fields mirror PMD's `name / description / priority / externalInfoUrl`:
|
|
47
|
+
* - `name`: short display name
|
|
48
|
+
* - `shortDescription`: 1-line summary
|
|
49
|
+
* - `fullDescription`: paragraph-length explanation (markdown ok)
|
|
50
|
+
* - `defaultLevel`: severity floor; per-Finding `level` can downgrade
|
|
51
|
+
* - `helpUri`: optional documentation link
|
|
52
|
+
*/
|
|
53
|
+
export interface RuleDescriptor {
|
|
54
|
+
id: string;
|
|
55
|
+
name: string;
|
|
56
|
+
shortDescription: string;
|
|
57
|
+
fullDescription: string;
|
|
58
|
+
defaultLevel: Severity;
|
|
59
|
+
helpUri?: string;
|
|
60
|
+
}
|
|
61
|
+
export declare const RULE_CATALOG: Record<string, RuleDescriptor>;
|
|
62
|
+
import type { OrgId } from "@ryanstark24/sfgraph-shared";
|
|
63
|
+
import type { NodeFact } from "../domain/index.js";
|
|
64
|
+
import type { AuditResult } from "./audit-graph.js";
|
|
65
|
+
import { findDeadCode } from "./dead-code.js";
|
|
66
|
+
import type { GovernorRisk } from "./governor.js";
|
|
67
|
+
import type { SecurityAudit } from "./security.js";
|
|
68
|
+
export declare function governorRisksToFindings(risks: GovernorRisk[]): Finding[];
|
|
69
|
+
export declare function securityAuditToFindings(audit: SecurityAudit): Finding[];
|
|
70
|
+
export declare function deadCodeToFindings(nodes: NodeFact[]): Finding[];
|
|
71
|
+
export declare function danglingEdgesToFindings(audit: AuditResult): Finding[];
|
|
72
|
+
/**
|
|
73
|
+
* Convenience: run every adapter against an org and return a unified
|
|
74
|
+
* Finding[]. Caller controls which audits to invoke and threads the
|
|
75
|
+
* GraphStore + orgId. SARIF emitter consumes this directly.
|
|
76
|
+
*/
|
|
77
|
+
export interface AllFindingsOpts {
|
|
78
|
+
governor?: GovernorRisk[];
|
|
79
|
+
security?: SecurityAudit;
|
|
80
|
+
deadCode?: NodeFact[];
|
|
81
|
+
dangling?: AuditResult;
|
|
82
|
+
}
|
|
83
|
+
export declare function collectFindings(opts: AllFindingsOpts): Finding[];
|
|
84
|
+
export { findDeadCode };
|
|
85
|
+
export type { OrgId };
|
|
86
|
+
//# sourceMappingURL=findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings.d.ts","sourceRoot":"","sources":["../../src/analyze/findings.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,CAAC;IAChB,uEAAuE;IACvE,QAAQ,EAAE,eAAe,CAAC;IAC1B;mDAC+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,QAAQ,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAiEvD,CAAC;AAMF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAQxE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,EAAE,CAmBvE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CAW/D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,EAAE,CAQrE;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,EAAE,CAOhE;AAID,OAAO,EAAE,YAAY,EAAE,CAAC;AACxB,YAAY,EAAE,KAAK,EAAE,CAAC"}
|