@cplieger/deadset-ts 8.0.0-dev.2 → 8.0.0-dev.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/THIRD_PARTY_NOTICES.md +27 -0
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/alias-chain.js +35 -9
- package/dist/src/amd.js +81 -0
- package/dist/src/analysis.js +274 -496
- package/dist/src/augmentations.js +64 -3
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/bindings.js +382 -0
- package/dist/src/commands/held.js +499 -0
- package/dist/src/commands/read.js +161 -0
- package/dist/src/commands/shell.js +169 -0
- package/dist/src/commands/tools.js +1847 -0
- package/dist/src/component-files.js +3 -2
- package/dist/src/component-layer.js +4 -2
- package/dist/src/config.js +6 -82
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +10 -38
- package/dist/src/contextual-uses.js +57 -26
- package/dist/src/contract/config.generated.js +561 -0
- package/dist/src/contract/contract.generated.js +1370 -0
- package/dist/src/contract/report.generated.js +866 -0
- package/dist/src/dependencies.js +165 -122
- package/dist/src/destructuring.js +1 -19
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +181 -168
- package/dist/src/entries/build-scripts.js +222 -0
- package/dist/src/{configuration-files.js → entries/configuration-files.js} +52 -256
- package/dist/src/{convention-rows.js → entries/convention-rows.js} +170 -30
- package/dist/src/entries/conventions.js +740 -0
- package/dist/src/{html-entries.js → entries/html-entries.js} +12 -42
- package/dist/src/{mdx-entries.js → entries/mdx-entries.js} +5 -28
- package/dist/src/entries/run-directories.js +77 -0
- package/dist/src/entries/sources.js +144 -0
- package/dist/src/entries/static-module.js +670 -0
- package/dist/src/entries/test-runners.js +650 -0
- package/dist/src/entries/workflow-steps.js +345 -0
- package/dist/src/exemptions/argument-places.js +131 -0
- package/dist/src/exemptions/calls.js +338 -0
- package/dist/src/exemptions/classes.js +13 -0
- package/dist/src/{decorator.js → exemptions/decorator.js} +19 -30
- package/dist/src/exemptions/detectors.js +48 -0
- package/dist/src/{enum-group.js → exemptions/enum-group.js} +9 -16
- package/dist/src/{erased-stores.js → exemptions/erased-stores.js} +7 -11
- package/dist/src/{framework-lifecycle.js → exemptions/framework-lifecycle.js} +76 -54
- package/dist/src/exemptions/generated-file.js +241 -0
- package/dist/src/{injection-container.js → exemptions/injection-container.js} +20 -26
- package/dist/src/exemptions/installed-globals.js +173 -0
- package/dist/src/{interface-satisfaction.js → exemptions/interface-satisfaction.js} +52 -121
- package/dist/src/exemptions/lifecycle.js +150 -0
- package/dist/src/{reflective-lookup.js → exemptions/reflective-lookup.js} +3 -3
- package/dist/src/exemptions/serialization-contract.js +1276 -0
- package/dist/src/exemptions/sites.js +182 -0
- package/dist/src/{template-field.js → exemptions/template-field.js} +13 -23
- package/dist/src/{value-reach.js → exemptions/value-reach.js} +14 -7
- package/dist/src/exposure.js +400 -0
- package/dist/src/extensions.js +37 -0
- package/dist/src/facts.js +38 -0
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +3 -26
- package/dist/src/findings/completion.js +109 -56
- package/dist/src/findings/dependencies-and-module-machinery.js +4 -5
- package/dist/src/findings/emitters.js +27 -41
- package/dist/src/{implementations.js → findings/implementations.js} +3 -3
- package/dist/src/{in-operands.js → findings/in-operands.js} +3 -2
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +16 -13
- package/dist/src/findings/non-code-artifacts.js +17 -12
- package/dist/src/findings/reads-and-writes.js +86 -27
- package/dist/src/findings/self-check.js +44 -30
- package/dist/src/findings/unused-declarations.js +29 -45
- package/dist/src/findings/visibility-narrowing.js +23 -31
- package/dist/src/findings-pass.js +13 -21
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +67 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/git-ignore.js +39 -26
- package/dist/src/import-bindings.js +73 -28
- package/dist/src/index/sites.js +557 -0
- package/dist/src/index/values.js +124 -0
- package/dist/src/index.js +2 -2
- package/dist/src/indexed-access.js +523 -478
- package/dist/src/intra-function-parts.js +63 -43
- package/dist/src/inventory/commonjs.js +507 -0
- package/dist/src/inventory/enumerate.js +167 -0
- package/dist/src/inventory/syntax.js +236 -0
- package/dist/src/inventory.js +323 -724
- package/dist/src/javascript-file.js +48 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +126 -107
- package/dist/src/kinds.js +3 -366
- package/dist/src/{components.js → liveness/components.js} +2 -3
- package/dist/src/{graph.js → liveness/graph.js} +52 -28
- package/dist/src/liveness/matrix.js +99 -0
- package/dist/src/liveness/sweep.js +558 -0
- package/dist/src/load/classify.js +289 -0
- package/dist/src/load/diagnostics.js +87 -0
- package/dist/src/load/discover.js +285 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/package-scope.js +56 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +113 -0
- package/dist/src/load/synthesize.js +152 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +89 -66
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +24 -66
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/module-declarations.js +70 -85
- package/dist/src/overrides.js +134 -112
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +82 -16
- package/dist/src/platform-calls.js +78 -0
- package/dist/src/platform-symbols.js +134 -0
- package/dist/src/position.js +43 -1
- package/dist/src/print.js +11 -79
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +95 -0
- package/dist/src/ref.js +12 -20
- package/dist/src/references/read-rule.js +1 -0
- package/dist/src/references/read-rules.js +48 -0
- package/dist/src/references/sink.js +237 -0
- package/dist/src/references/sources.js +450 -0
- package/dist/src/references.js +117 -1074
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +57 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +246 -730
- package/dist/src/{configured-declarations.js → roots/configured-declarations.js} +22 -24
- package/dist/src/{entry-point-gaps.js → roots/entry-point-gaps.js} +6 -15
- package/dist/src/roots/manifest.js +216 -0
- package/dist/src/roots/published-reach.js +412 -0
- package/dist/src/roots/root-set.js +487 -0
- package/dist/src/roots/unseen-loads.js +236 -0
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +38 -115
- package/dist/src/session.js +37 -29
- package/dist/src/source-files.js +6 -10
- package/dist/src/stores.js +4 -2
- package/dist/src/suppress-file.js +25 -28
- package/dist/src/suppress-inline.js +36 -83
- package/dist/src/suppress.js +50 -71
- package/dist/src/symbol-keys.js +92 -88
- package/dist/src/tests/file-class.js +76 -0
- package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
- package/dist/src/{test-support.js → tests/support.js} +5 -12
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +298 -0
- package/dist/src/text/yaml.js +684 -0
- package/dist/src/type-errors.js +11 -232
- package/dist/src/type-parameter-reads.js +178 -139
- package/dist/src/unimplemented-callees.js +262 -242
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/vendor/unbash/ansi-c.js +132 -0
- package/dist/src/vendor/unbash/arithmetic-parts.js +37 -0
- package/dist/src/vendor/unbash/arithmetic.js +591 -0
- package/dist/src/vendor/unbash/assignment.js +131 -0
- package/dist/src/vendor/unbash/chars.js +48 -0
- package/dist/src/vendor/unbash/command.js +41 -0
- package/dist/src/vendor/unbash/expansion.js +80 -0
- package/dist/src/vendor/unbash/glob.js +268 -0
- package/dist/src/vendor/unbash/heredoc.js +27 -0
- package/dist/src/vendor/unbash/internal-types.js +1 -0
- package/dist/src/vendor/unbash/lexer.js +4274 -0
- package/dist/src/vendor/unbash/limits.js +3 -0
- package/dist/src/vendor/unbash/parser.js +1366 -0
- package/dist/src/vendor/unbash/parts.js +57 -0
- package/dist/src/vendor/unbash/substitution-context.js +8 -0
- package/dist/src/vendor/unbash/traversal.js +212 -0
- package/dist/src/vendor/unbash/types.js +1 -0
- package/dist/src/vendor/unbash/word-value.js +61 -0
- package/dist/src/vendor/unbash/word.js +40 -0
- package/dist/src/verbs/analyze.js +194 -127
- package/dist/src/verbs/describe.js +13 -18
- package/dist/src/verbs/explain.js +85 -139
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +30 -6
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/jsr.json +2 -1
- package/package.json +14 -8
- package/src/alias-chain.ts +40 -11
- package/src/amd.ts +130 -0
- package/src/analysis.ts +426 -733
- package/src/augmentations.ts +93 -4
- package/src/automatic-types.ts +12 -30
- package/src/bindings.ts +460 -0
- package/src/commands/held.ts +632 -0
- package/src/commands/read.ts +242 -0
- package/src/commands/shell.ts +228 -0
- package/src/commands/tools.ts +2382 -0
- package/src/component-files.ts +4 -2
- package/src/component-layer.ts +4 -2
- package/src/config.ts +31 -302
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +16 -66
- package/src/contextual-uses.ts +66 -34
- package/src/contract/config.generated.ts +821 -0
- package/src/contract/contract.generated.ts +1453 -0
- package/src/contract/report.generated.ts +1241 -0
- package/src/dependencies.ts +223 -128
- package/src/destructuring.ts +1 -31
- package/src/edges.ts +41 -140
- package/src/element-access.ts +190 -187
- package/src/entries/build-scripts.ts +292 -0
- package/src/{configuration-files.ts → entries/configuration-files.ts} +68 -278
- package/src/{convention-rows.ts → entries/convention-rows.ts} +227 -31
- package/src/{conventions.ts → entries/conventions.ts} +367 -583
- package/src/{html-entries.ts → entries/html-entries.ts} +22 -48
- package/src/{mdx-entries.ts → entries/mdx-entries.ts} +7 -30
- package/src/entries/run-directories.ts +108 -0
- package/src/entries/sources.ts +266 -0
- package/src/entries/static-module.ts +858 -0
- package/src/entries/test-runners.ts +835 -0
- package/src/entries/workflow-steps.ts +432 -0
- package/src/exemptions/argument-places.ts +198 -0
- package/src/exemptions/calls.ts +483 -0
- package/src/exemptions/classes.ts +49 -0
- package/src/exemptions/decorator.ts +56 -0
- package/src/exemptions/detectors.ts +75 -0
- package/src/{enum-group.ts → exemptions/enum-group.ts} +10 -19
- package/src/{erased-stores.ts → exemptions/erased-stores.ts} +7 -14
- package/src/{framework-lifecycle.ts → exemptions/framework-lifecycle.ts} +85 -66
- package/src/exemptions/generated-file.ts +318 -0
- package/src/{injection-container.ts → exemptions/injection-container.ts} +29 -34
- package/src/exemptions/installed-globals.ts +255 -0
- package/src/{interface-satisfaction.ts → exemptions/interface-satisfaction.ts} +69 -160
- package/src/exemptions/lifecycle.ts +286 -0
- package/src/{reflective-lookup.ts → exemptions/reflective-lookup.ts} +5 -5
- package/src/exemptions/serialization-contract.ts +1729 -0
- package/src/exemptions/sites.ts +293 -0
- package/src/{template-field.ts → exemptions/template-field.ts} +22 -32
- package/src/{value-reach.ts → exemptions/value-reach.ts} +16 -8
- package/src/exposure.ts +492 -0
- package/src/extensions.ts +45 -0
- package/src/facts.ts +46 -0
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +15 -25
- package/src/finding.ts +10 -10
- package/src/findings/boundary.ts +11 -0
- package/src/findings/completion.ts +133 -64
- package/src/findings/dependencies-and-module-machinery.ts +4 -7
- package/src/findings/emitter.ts +9 -10
- package/src/findings/emitters.ts +38 -52
- package/src/{implementations.ts → findings/implementations.ts} +4 -4
- package/src/{in-operands.ts → findings/in-operands.ts} +4 -3
- package/src/findings/interfaces.ts +7 -9
- package/src/findings/intra-function.ts +16 -14
- package/src/findings/non-code-artifacts.ts +24 -15
- package/src/findings/reads-and-writes.ts +118 -41
- package/src/findings/self-check.ts +51 -38
- package/src/findings/unused-declarations.ts +31 -49
- package/src/findings/visibility-narrowing.ts +36 -40
- package/src/findings-pass.ts +15 -31
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +96 -0
- package/src/fs/tree.ts +110 -0
- package/src/git-ignore.ts +50 -26
- package/src/host.ts +12 -5
- package/src/import-bindings.ts +98 -29
- package/src/index/sites.ts +781 -0
- package/src/index/values.ts +170 -0
- package/src/index.ts +2 -2
- package/src/indexed-access.ts +570 -527
- package/src/intra-function-parts.ts +73 -44
- package/src/inventory/commonjs.ts +696 -0
- package/src/inventory/enumerate.ts +203 -0
- package/src/inventory/syntax.ts +311 -0
- package/src/inventory.ts +442 -895
- package/src/javascript-file.ts +54 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +133 -122
- package/src/kinds.ts +5 -413
- package/src/{components.ts → liveness/components.ts} +4 -6
- package/src/{graph.ts → liveness/graph.ts} +100 -35
- package/src/liveness/matrix.ts +162 -0
- package/src/liveness/sweep.ts +855 -0
- package/src/load/classify.ts +433 -0
- package/src/load/diagnostics.ts +154 -0
- package/src/load/discover.ts +471 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +194 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/package-scope.ts +74 -0
- package/src/load/plan.ts +513 -0
- package/src/load/specifiers.ts +171 -0
- package/src/load/synthesize.ts +230 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +128 -85
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +41 -77
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/module-declarations.ts +74 -98
- package/src/overrides.ts +162 -134
- package/src/partial.ts +3 -2
- package/src/paths.ts +92 -16
- package/src/platform-calls.ts +119 -0
- package/src/platform-symbols.ts +189 -0
- package/src/position.ts +44 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/query.ts +201 -10
- package/src/ref.ts +12 -20
- package/src/references/read-rule.ts +60 -0
- package/src/references/read-rules.ts +55 -0
- package/src/references/sink.ts +314 -0
- package/src/references/sources.ts +632 -0
- package/src/references.ts +187 -1450
- package/src/report-schema.ts +68 -0
- package/src/report.ts +103 -226
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +284 -1115
- package/src/{configured-declarations.ts → roots/configured-declarations.ts} +26 -29
- package/src/{entry-point-gaps.ts → roots/entry-point-gaps.ts} +7 -16
- package/src/roots/manifest.ts +303 -0
- package/src/roots/published-reach.ts +486 -0
- package/src/{roots.ts → roots/root-set.ts} +286 -469
- package/src/roots/unseen-loads.ts +345 -0
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -388
- package/src/scope.ts +46 -138
- package/src/session.ts +87 -55
- package/src/source-files.ts +6 -11
- package/src/stores.ts +15 -3
- package/src/suppress-file.ts +24 -33
- package/src/suppress-inline.ts +55 -91
- package/src/suppress.ts +78 -79
- package/src/symbol-keys.ts +104 -107
- package/src/tests/file-class.ts +135 -0
- package/src/{outside-tests.ts → tests/outside.ts} +16 -10
- package/src/{test-support.ts → tests/support.ts} +15 -21
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.ts +388 -0
- package/src/text/yaml.ts +747 -0
- package/src/type-errors.ts +18 -288
- package/src/type-parameter-reads.ts +187 -158
- package/src/unimplemented-callees.ts +297 -280
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/vendor/unbash/LICENSE +15 -0
- package/src/vendor/unbash/VENDORED.md +16 -0
- package/src/vendor/unbash/ansi-c.ts +132 -0
- package/src/vendor/unbash/arithmetic-parts.ts +53 -0
- package/src/vendor/unbash/arithmetic.ts +641 -0
- package/src/vendor/unbash/assignment.ts +163 -0
- package/src/vendor/unbash/chars.ts +48 -0
- package/src/vendor/unbash/command.ts +47 -0
- package/src/vendor/unbash/expansion.ts +144 -0
- package/src/vendor/unbash/glob.ts +284 -0
- package/src/vendor/unbash/heredoc.ts +34 -0
- package/src/vendor/unbash/internal-types.ts +94 -0
- package/src/vendor/unbash/lexer.ts +4352 -0
- package/src/vendor/unbash/limits.ts +3 -0
- package/src/vendor/unbash/parser.ts +1612 -0
- package/src/vendor/unbash/parts.ts +96 -0
- package/src/vendor/unbash/substitution-context.ts +20 -0
- package/src/vendor/unbash/traversal.ts +182 -0
- package/src/vendor/unbash/types.ts +660 -0
- package/src/vendor/unbash/word-value.ts +64 -0
- package/src/vendor/unbash/word.ts +50 -0
- package/src/verbs/analyze.ts +255 -164
- package/src/verbs/describe.ts +19 -17
- package/src/verbs/explain.ts +93 -169
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +36 -6
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/dist/src/base-url.js +0 -18
- package/dist/src/calls.js +0 -155
- package/dist/src/conventions.js +0 -937
- package/dist/src/discover.js +0 -468
- package/dist/src/entry-points.js +0 -529
- package/dist/src/exempt-classes.js +0 -75
- package/dist/src/exempt.js +0 -209
- package/dist/src/generated-file.js +0 -95
- package/dist/src/glob.js +0 -65
- package/dist/src/manifest.js +0 -165
- package/dist/src/matrix.js +0 -246
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/roots.js +0 -672
- package/dist/src/serialization-contract.js +0 -611
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/sweep.js +0 -224
- package/dist/src/test-joins.js +0 -101
- package/dist/src/value-flow.js +0 -74
- package/dist/src/version.js +0 -7
- package/dist/src/workflow-steps.js +0 -185
- package/src/base-url.ts +0 -24
- package/src/calls.ts +0 -225
- package/src/decorator.ts +0 -78
- package/src/discover.ts +0 -653
- package/src/entry-points.ts +0 -687
- package/src/exempt-classes.ts +0 -123
- package/src/exempt.ts +0 -323
- package/src/generated-file.ts +0 -111
- package/src/glob.ts +0 -67
- package/src/manifest.ts +0 -234
- package/src/matrix.ts +0 -423
- package/src/pnpm-workspace.ts +0 -135
- package/src/serialization-contract.ts +0 -849
- package/src/setup-failure.ts +0 -39
- package/src/sweep.ts +0 -347
- package/src/test-joins.ts +0 -120
- package/src/value-flow.ts +0 -104
- package/src/version.ts +0 -7
- package/src/workflow-steps.ts +0 -216
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Holds a report to `contract/report.schema.json` and `contract/finding.schema.json`
|
|
3
|
+
* before it is written, reading the schemas the generator copies from the Contract, so
|
|
4
|
+
* this analyzer never writes a document a reader refuses.
|
|
5
|
+
*/
|
|
6
|
+
import { REPORT_SCHEMAS } from "./contract/report.generated.js";
|
|
7
|
+
import { schemaRefusals } from "./schema.js";
|
|
8
|
+
const reportSchema = schemaRefusals(REPORT_SCHEMAS, "report.schema.json");
|
|
9
|
+
/**
|
|
10
|
+
* What the report schema refuses in one report document, none for an instance, and, as
|
|
11
|
+
* no schema keyword can state it, a components listing that is not one entry per
|
|
12
|
+
* component a finding or an edge evaluation's finding names.
|
|
13
|
+
*/
|
|
14
|
+
export function reportRefusals(document) {
|
|
15
|
+
const found = reportSchema(document);
|
|
16
|
+
return found.length > 0 ? found : listingRefusals(document);
|
|
17
|
+
}
|
|
18
|
+
/** The components listing held to the components the findings name, once each. */
|
|
19
|
+
function listingRefusals(report) {
|
|
20
|
+
if (report.components === undefined) {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
const refuse = (pointer, reason) => [
|
|
24
|
+
{ pointer, keyword: "components", reason, member: "" },
|
|
25
|
+
];
|
|
26
|
+
const listed = new Set();
|
|
27
|
+
for (const [i, entry] of report.components.entries()) {
|
|
28
|
+
if (listed.has(entry.id)) {
|
|
29
|
+
return refuse(`/components/${String(i)}`, `the entry lists component ${entry.id} a second time`);
|
|
30
|
+
}
|
|
31
|
+
listed.add(entry.id);
|
|
32
|
+
}
|
|
33
|
+
const named = [
|
|
34
|
+
...report.findings.map((finding, i) => [`/findings/${String(i)}`, finding.component.id]),
|
|
35
|
+
...report.edge_evaluations.flatMap((one, i) => one.finding === undefined
|
|
36
|
+
? []
|
|
37
|
+
: [[`/edge_evaluations/${String(i)}/finding`, one.finding.component.id]]),
|
|
38
|
+
];
|
|
39
|
+
for (const [pointer, id] of named) {
|
|
40
|
+
if (!listed.has(id)) {
|
|
41
|
+
return refuse(pointer, `the finding names component ${id}, which the components listing lacks`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const ids = new Set(named.map(([, id]) => id));
|
|
45
|
+
for (const [i, entry] of report.components.entries()) {
|
|
46
|
+
if (!ids.has(entry.id)) {
|
|
47
|
+
return refuse(`/components/${String(i)}`, `the entry lists component ${entry.id}, which no finding names`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return [];
|
|
51
|
+
}
|
package/dist/src/report.js
CHANGED
|
@@ -3,20 +3,26 @@
|
|
|
3
3
|
* in the order its schema lists them, built from what one run answered. Every reporter
|
|
4
4
|
* renders this document, so no two renderings disagree about which findings exist.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
import { SCHEMA_VERSION, SCHEMA_VERSIONS } from "./contract/contract.generated.js";
|
|
7
|
+
import { bytewise } from "./text/compare.js";
|
|
8
|
+
import { LANGUAGE, PRODUCT } from "./product.js";
|
|
9
|
+
/**
|
|
10
|
+
* Each component the findings name, once, with the members the first finding naming it
|
|
11
|
+
* carries, in the order the findings are: `findings` paired with their wire forms and
|
|
12
|
+
* sorted, then the edge evaluations' findings.
|
|
13
|
+
*/
|
|
14
|
+
function componentsOf(findings) {
|
|
15
|
+
const listed = new Map();
|
|
16
|
+
for (const [written, finding] of findings) {
|
|
17
|
+
const { members } = finding.component;
|
|
18
|
+
if (members !== undefined && !listed.has(written.component.id)) {
|
|
19
|
+
listed.set(written.component.id, {
|
|
20
|
+
id: written.component.id,
|
|
21
|
+
members: members.map(wireSymbol),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
18
24
|
}
|
|
19
|
-
return
|
|
25
|
+
return [...listed.values()];
|
|
20
26
|
}
|
|
21
27
|
function wirePosition(position) {
|
|
22
28
|
return {
|
|
@@ -85,9 +91,6 @@ export function wireFinding(finding) {
|
|
|
85
91
|
root: finding.component.root,
|
|
86
92
|
symbol_count: finding.component.symbolCount,
|
|
87
93
|
deletable_lines: finding.component.deletableLines,
|
|
88
|
-
...(finding.component.members === undefined
|
|
89
|
-
? {}
|
|
90
|
-
: { members: finding.component.members.map(wireSymbol) }),
|
|
91
94
|
},
|
|
92
95
|
retained_by: finding.retainedBy,
|
|
93
96
|
configurations: finding.configurations,
|
|
@@ -128,19 +131,19 @@ function wireStale(stale) {
|
|
|
128
131
|
}
|
|
129
132
|
/** The canonical key over two findings: path, line, column, code, then the symbol reference. */
|
|
130
133
|
function canonical(a, b) {
|
|
131
|
-
return (
|
|
134
|
+
return (bytewise(a.position.path, b.position.path) ||
|
|
132
135
|
a.position.line - b.position.line ||
|
|
133
136
|
a.position.column - b.position.column ||
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
bytewise(a.code, b.code) ||
|
|
138
|
+
bytewise(a.symbol.ref, b.symbol.ref));
|
|
136
139
|
}
|
|
137
140
|
/** The canonical key over two stale suppressions, each component from the record's own member. */
|
|
138
141
|
function canonicalStale(a, b) {
|
|
139
|
-
return (
|
|
142
|
+
return (bytewise(a.position.path, b.position.path) ||
|
|
140
143
|
a.position.line - b.position.line ||
|
|
141
144
|
a.position.column - b.position.column ||
|
|
142
|
-
|
|
143
|
-
|
|
145
|
+
bytewise(a.code, b.code) ||
|
|
146
|
+
bytewise(a.symbol, b.symbol));
|
|
144
147
|
}
|
|
145
148
|
/** One declared gap as a report carries it, its members in the schema's order. */
|
|
146
149
|
function wireGap(gap) {
|
|
@@ -153,9 +156,9 @@ function wireGap(gap) {
|
|
|
153
156
|
}
|
|
154
157
|
/** Edge evaluations by edge, then side, then their compact encodings. */
|
|
155
158
|
function byEdge(a, b) {
|
|
156
|
-
return (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
return (bytewise(a.edge, b.edge) ||
|
|
160
|
+
bytewise(a.side, b.side) ||
|
|
161
|
+
bytewise(JSON.stringify(a), JSON.stringify(b)));
|
|
159
162
|
}
|
|
160
163
|
/**
|
|
161
164
|
* The lines a reader deletes by acting on every finding: each distinct component a root
|
|
@@ -198,21 +201,25 @@ function totalsOf(findings, result) {
|
|
|
198
201
|
}
|
|
199
202
|
/** Builds the report of one run, every array in the order the Contract fixes for it. */
|
|
200
203
|
export function buildReport(input) {
|
|
201
|
-
const
|
|
204
|
+
const paired = input.result.findings
|
|
205
|
+
.map((finding) => [wireFinding(finding), finding])
|
|
206
|
+
.sort(([a], [b]) => canonical(a, b));
|
|
207
|
+
const findings = paired.map(([wire]) => wire);
|
|
208
|
+
const evaluated = input.result.edgeEvaluations.flatMap((one) => one.finding === undefined ? [] : [[wireFinding(one.finding), one.finding]]);
|
|
202
209
|
const unavailable = [...new Map(input.unavailable.map((one) => [one.id, one])).values()]
|
|
203
|
-
.sort((a, b) =>
|
|
210
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
204
211
|
.map((one) => ({ id: one.id, role: "consumer", reason: one.reason }));
|
|
205
212
|
const loaded = [...input.loaded]
|
|
206
|
-
.sort((a, b) =>
|
|
213
|
+
.sort((a, b) => bytewise(a.id, b.id) || bytewise(a.path, b.path))
|
|
207
214
|
.map((one) => ({ id: one.id, role: "consumer", path: one.path }));
|
|
208
215
|
return {
|
|
209
216
|
schema_version: SCHEMA_VERSION,
|
|
210
217
|
contract_version: input.contractVersion,
|
|
211
218
|
analyzer: {
|
|
212
|
-
name:
|
|
219
|
+
name: PRODUCT,
|
|
213
220
|
version: input.version,
|
|
214
221
|
languages: [LANGUAGE],
|
|
215
|
-
schema_versions_accepted:
|
|
222
|
+
schema_versions_accepted: SCHEMA_VERSIONS,
|
|
216
223
|
conformance: {
|
|
217
224
|
corpus_version: input.conformance.corpusVersion,
|
|
218
225
|
result: input.conformance.result,
|
|
@@ -221,23 +228,26 @@ export function buildReport(input) {
|
|
|
221
228
|
},
|
|
222
229
|
target: { kind: input.target.kind, root: input.target.root, identity: input.target.identity },
|
|
223
230
|
configurations: [...input.configurations]
|
|
224
|
-
.sort((a, b) =>
|
|
231
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
225
232
|
.map((one) => ({ id: one.id, project: one.project })),
|
|
226
233
|
configurations_not_built: [...input.notBuilt]
|
|
227
|
-
.sort((a, b) =>
|
|
234
|
+
.sort((a, b) => bytewise(a.id, b.id))
|
|
228
235
|
.map((one) => ({ id: one.id, project: one.project, error: one.error })),
|
|
229
236
|
consumers: { declared: loaded.length + unavailable.length, loaded, unavailable },
|
|
230
237
|
findings,
|
|
238
|
+
...(input.listsComponents === true
|
|
239
|
+
? { components: componentsOf([...paired, ...evaluated]) }
|
|
240
|
+
: {}),
|
|
231
241
|
edge_evaluations: input.result.edgeEvaluations.map(wireEvaluation).sort(byEdge),
|
|
232
242
|
stale_suppressions: input.result.staleSuppressions.map(wireStale).sort(canonicalStale),
|
|
233
243
|
// Every gap shares the one component of the canonical key a gap supplies, the analyzer's
|
|
234
244
|
// name, so the compact encodings alone order them.
|
|
235
245
|
declared_gaps: input.declaredGaps
|
|
236
246
|
.map(wireGap)
|
|
237
|
-
.sort((a, b) =>
|
|
247
|
+
.sort((a, b) => bytewise(JSON.stringify(a), JSON.stringify(b))),
|
|
238
248
|
excluded_by_cgo: [],
|
|
239
249
|
test_file_rules: [...input.testFileRules]
|
|
240
|
-
.sort((a, b) =>
|
|
250
|
+
.sort((a, b) => bytewise(a.rule, b.rule) || a.matched - b.matched)
|
|
241
251
|
.map((one) => ({ rule: one.rule, matched: one.matched })),
|
|
242
252
|
type_error_skips: [
|
|
243
253
|
...new Map(input.typeErrorSkips.map((one) => {
|
|
@@ -245,14 +255,14 @@ export function buildReport(input) {
|
|
|
245
255
|
return [JSON.stringify(skip), skip];
|
|
246
256
|
})),
|
|
247
257
|
]
|
|
248
|
-
.sort(([a, x], [b, y]) =>
|
|
258
|
+
.sort(([a, x], [b, y]) => bytewise(x.path, y.path) || x.line - y.line || bytewise(a, b))
|
|
249
259
|
.map(([, skip]) => skip),
|
|
250
260
|
notes: [...new Map((input.notes ?? []).map((one) => [JSON.stringify(one), one])).entries()]
|
|
251
|
-
.sort(([a, x], [b, y]) =>
|
|
261
|
+
.sort(([a, x], [b, y]) => bytewise(x.kind, y.kind) || bytewise(x.path, y.path) || bytewise(a, b))
|
|
252
262
|
.map(([, note]) => note),
|
|
253
263
|
unanswered_questions: [...input.unanswered]
|
|
254
|
-
.sort((a, b) =>
|
|
255
|
-
|
|
264
|
+
.sort((a, b) => bytewise(a.configuration, b.configuration) ||
|
|
265
|
+
bytewise(JSON.stringify(a), JSON.stringify(b)))
|
|
256
266
|
.map((one) => ({
|
|
257
267
|
configuration: one.configuration,
|
|
258
268
|
questions: one.questions,
|
|
@@ -279,16 +289,22 @@ export function sortFindings(report, by) {
|
|
|
279
289
|
return { ...report, findings: [...report.findings].sort(by === "size" ? bySize : canonical) };
|
|
280
290
|
}
|
|
281
291
|
/**
|
|
282
|
-
* The report holding the first `most` findings of its order, the rest counted as omitted
|
|
283
|
-
*
|
|
292
|
+
* The report holding the first `most` findings of its order, the rest counted as omitted,
|
|
293
|
+
* and listing only the components those findings name. Every other total keeps describing
|
|
294
|
+
* the whole set. Zero keeps every finding.
|
|
284
295
|
*/
|
|
285
296
|
export function capFindings(report, most) {
|
|
286
297
|
if (most <= 0 || report.findings.length <= most) {
|
|
287
298
|
return report;
|
|
288
299
|
}
|
|
300
|
+
const findings = report.findings.slice(0, most);
|
|
301
|
+
const named = new Set([...findings, ...report.edge_evaluations.flatMap((one) => one.finding ?? [])].map((finding) => finding.component.id));
|
|
289
302
|
return {
|
|
290
303
|
...report,
|
|
291
|
-
findings
|
|
304
|
+
findings,
|
|
305
|
+
...(report.components === undefined
|
|
306
|
+
? {}
|
|
307
|
+
: { components: report.components.filter((listed) => named.has(listed.id)) }),
|
|
292
308
|
totals: { ...report.totals, omitted: report.findings.length - most },
|
|
293
309
|
};
|
|
294
310
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { fails } from "../config.js";
|
|
2
1
|
import { coalesced } from "../json-chunks.js";
|
|
3
2
|
import { KINDS } from "../kinds.js";
|
|
4
3
|
/** The escapes a workflow command's message needs, so a line break does not end the command. */
|
|
@@ -19,6 +18,12 @@ function escapeProperty(value) {
|
|
|
19
18
|
function kindName(code) {
|
|
20
19
|
return KINDS.get(code)?.name ?? code;
|
|
21
20
|
}
|
|
21
|
+
/** The command each finding severity is annotated with, whatever the failing severity. */
|
|
22
|
+
const LEVELS = {
|
|
23
|
+
deny: "error",
|
|
24
|
+
warn: "warning",
|
|
25
|
+
allow: "notice",
|
|
26
|
+
};
|
|
22
27
|
function command(level, at, endLine, title, message) {
|
|
23
28
|
return `::${level} file=${escapeProperty(at.path)},line=${String(at.line)},col=${String(at.column)},endLine=${String(endLine)},title=${escapeProperty(title)}::${escapeData(message)}`;
|
|
24
29
|
}
|
|
@@ -26,16 +31,15 @@ function command(level, at, endLine, title, message) {
|
|
|
26
31
|
const SKIP_TITLE = "type error skipped";
|
|
27
32
|
const SKIP_MESSAGE = "the analysis did not evaluate the function or statement holding this type error: ";
|
|
28
33
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* is fixed on at the failing severity.
|
|
34
|
+
* The annotations `contract/grammar/annotations.md` states: one per finding, at the
|
|
35
|
+
* command its severity names, and one error per stale suppression, each naming its file,
|
|
36
|
+
* line, column and last line and titled by its code and kind; then one warning per
|
|
37
|
+
* type-error skip naming its file and line, and one per note naming its directory.
|
|
34
38
|
*/
|
|
35
|
-
export function annotations(report
|
|
39
|
+
export function annotations(report) {
|
|
36
40
|
return coalesced((function* lines() {
|
|
37
41
|
for (const found of report.findings) {
|
|
38
|
-
yield `${command(
|
|
42
|
+
yield `${command(LEVELS[found.severity], found.position, found.position.end_line, `${found.code} ${found.kind}`, found.message)}\n`;
|
|
39
43
|
}
|
|
40
44
|
for (const stale of report.stale_suppressions) {
|
|
41
45
|
yield `${command("error", stale.position, stale.position.line, `${stale.code} ${kindName(stale.code)}`, stale.message)}\n`;
|
|
@@ -43,5 +47,8 @@ export function annotations(report, options) {
|
|
|
43
47
|
for (const skip of report.type_error_skips) {
|
|
44
48
|
yield `::warning file=${escapeProperty(skip.path)},line=${String(skip.line)},title=${escapeProperty(SKIP_TITLE)}::${escapeData(SKIP_MESSAGE + skip.message)}\n`;
|
|
45
49
|
}
|
|
50
|
+
for (const note of report.notes) {
|
|
51
|
+
yield `::warning file=${escapeProperty(note.path)},title=${escapeProperty(note.kind)}::${escapeData(note.message)}\n`;
|
|
52
|
+
}
|
|
46
53
|
})());
|
|
47
54
|
}
|
|
@@ -5,6 +5,8 @@ import { lineHashes, symbolFingerprint } from "./fingerprint.js";
|
|
|
5
5
|
import { RenderError } from "./reporter.js";
|
|
6
6
|
import { utf8Bytes } from "./sha256.js";
|
|
7
7
|
import { withheldLine } from "./text.js";
|
|
8
|
+
import { bytewise } from "../text/compare.js";
|
|
9
|
+
import { message } from "../product.js";
|
|
8
10
|
const SCHEMA = "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json";
|
|
9
11
|
const VERSION = "2.1.0";
|
|
10
12
|
/** The unit a finding's column counts. */
|
|
@@ -101,7 +103,7 @@ function lineHashCache(read) {
|
|
|
101
103
|
text = read(at.path);
|
|
102
104
|
}
|
|
103
105
|
catch (error) {
|
|
104
|
-
throw new RenderError(`read ${at.path} for its line fingerprint: ${
|
|
106
|
+
throw new RenderError(`read ${at.path} for its line fingerprint: ${message(error)}`);
|
|
105
107
|
}
|
|
106
108
|
hashes = lineHashes(text);
|
|
107
109
|
held.set(at.path, hashes);
|
|
@@ -114,7 +116,7 @@ function lineHashCache(read) {
|
|
|
114
116
|
};
|
|
115
117
|
}
|
|
116
118
|
/** Every position a finding names beyond its own, in the mapping's order, the first hundred. */
|
|
117
|
-
function relatedOf(found) {
|
|
119
|
+
function relatedOf(found, members) {
|
|
118
120
|
const related = [];
|
|
119
121
|
for (const one of found.details.implementations ?? []) {
|
|
120
122
|
related.push({ label: "implementation", at: one.position, endLine: one.position.end_line });
|
|
@@ -126,7 +128,7 @@ function relatedOf(found) {
|
|
|
126
128
|
const at = found.details.name_literal;
|
|
127
129
|
related.push({ label: "name", at, endLine: at.end_line });
|
|
128
130
|
}
|
|
129
|
-
for (const one of found.component.
|
|
131
|
+
for (const one of members(found.component.id)) {
|
|
130
132
|
if (declarationKey(one.ref, one.position.path) !==
|
|
131
133
|
declarationKey(found.symbol.ref, found.position.path)) {
|
|
132
134
|
related.push({ label: "member", at: one.position, endLine: one.position.end_line });
|
|
@@ -143,7 +145,9 @@ function messageWithLinks(message, related) {
|
|
|
143
145
|
return `${message} (see ${links.join(", ")})`;
|
|
144
146
|
}
|
|
145
147
|
/** Every member of the finding the mapping places nowhere else, under its schema name. */
|
|
146
|
-
|
|
148
|
+
/** A result's member bag, its component holding the members the report lists for it once. */
|
|
149
|
+
function propertiesOf(found, members) {
|
|
150
|
+
const listed = members(found.component.id);
|
|
147
151
|
return {
|
|
148
152
|
language: found.language,
|
|
149
153
|
symbol: found.symbol,
|
|
@@ -154,7 +158,7 @@ function propertiesOf(found) {
|
|
|
154
158
|
: { liveness_relation: found.liveness_relation }),
|
|
155
159
|
test_only: found.test_only,
|
|
156
160
|
generated: found.generated,
|
|
157
|
-
component: found.component,
|
|
161
|
+
component: listed.length === 0 ? found.component : { ...found.component, members: listed },
|
|
158
162
|
retained_by: found.retained_by,
|
|
159
163
|
configurations: found.configurations,
|
|
160
164
|
consumers_loaded: found.consumers_loaded,
|
|
@@ -169,8 +173,8 @@ function ruleIndex(index, code) {
|
|
|
169
173
|
}
|
|
170
174
|
return at;
|
|
171
175
|
}
|
|
172
|
-
function findingResult(found, index, hashOf) {
|
|
173
|
-
const related = relatedOf(found);
|
|
176
|
+
function findingResult(found, index, hashOf, members) {
|
|
177
|
+
const related = relatedOf(found, members);
|
|
174
178
|
return {
|
|
175
179
|
ruleId: found.code,
|
|
176
180
|
ruleIndex: ruleIndex(index, found.code),
|
|
@@ -190,7 +194,7 @@ function findingResult(found, index, hashOf) {
|
|
|
190
194
|
primaryLocationLineHash: hashOf(found.position),
|
|
191
195
|
"deadsetSymbolRef/v1": symbolFingerprint(found.code, found.symbol.ref),
|
|
192
196
|
},
|
|
193
|
-
properties: propertiesOf(found),
|
|
197
|
+
properties: propertiesOf(found, members),
|
|
194
198
|
};
|
|
195
199
|
}
|
|
196
200
|
/** A stale suppression at the failing level, at its own site; it is no finding, so it carries no member bag. */
|
|
@@ -218,11 +222,13 @@ export function sarif(report, options) {
|
|
|
218
222
|
const ruleList = rules(kinds);
|
|
219
223
|
const index = new Map(kinds.map((kind, at) => [kind.code, at]));
|
|
220
224
|
const hashOf = lineHashCache(options.readSource);
|
|
225
|
+
const listed = new Map((report.components ?? []).map((one) => [one.id, one.members]));
|
|
226
|
+
const members = (id) => listed.get(id) ?? [];
|
|
221
227
|
const results = [
|
|
222
|
-
...report.findings.map((found) => findingResult(found, index, hashOf)),
|
|
228
|
+
...report.findings.map((found) => findingResult(found, index, hashOf, members)),
|
|
223
229
|
...report.stale_suppressions.map((stale) => staleResult(stale, index, hashOf)),
|
|
224
230
|
];
|
|
225
|
-
const languages = [...report.analyzer.languages].sort().join("+");
|
|
231
|
+
const languages = [...report.analyzer.languages].sort(bytewise).join("+");
|
|
226
232
|
const withheld = withheldLine(report.totals);
|
|
227
233
|
const log = {
|
|
228
234
|
$schema: SCHEMA,
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { CHUNK_LENGTH } from "../json-chunks.js";
|
|
10
10
|
import { RenderError } from "./reporter.js";
|
|
11
11
|
import { utf8Bytes } from "./sha256.js";
|
|
12
|
+
import { bytewise } from "../text/compare.js";
|
|
12
13
|
/** A template that does not parse, which refuses the invocation before any analysis. */
|
|
13
14
|
export class TemplateError extends Error {
|
|
14
15
|
constructor(message) {
|
|
@@ -513,7 +514,7 @@ function formatted(value, nested) {
|
|
|
513
514
|
}
|
|
514
515
|
const object = value;
|
|
515
516
|
const entries = Object.keys(object)
|
|
516
|
-
.sort()
|
|
517
|
+
.sort(bytewise)
|
|
517
518
|
.map((key) => `${key}:${formatted(object[key] ?? null, true)}`);
|
|
518
519
|
return `map[${entries.join(" ")}]`;
|
|
519
520
|
}
|
|
@@ -538,26 +539,10 @@ function compareBasic(name, a, b) {
|
|
|
538
539
|
return Number.NaN;
|
|
539
540
|
}
|
|
540
541
|
if (kind === "string") {
|
|
541
|
-
return
|
|
542
|
+
return bytewise(a, b);
|
|
542
543
|
}
|
|
543
544
|
return a < b ? -1 : 1;
|
|
544
545
|
}
|
|
545
|
-
/**
|
|
546
|
-
* Two strings ordered by the bytes of their UTF-8 encodings, which is the order of their
|
|
547
|
-
* code points: the order of their UTF-16 code units differs above U+FFFF.
|
|
548
|
-
*/
|
|
549
|
-
function byCodePoints(a, b) {
|
|
550
|
-
let at = 0;
|
|
551
|
-
while (at < a.length && at < b.length) {
|
|
552
|
-
const x = a.codePointAt(at) ?? 0;
|
|
553
|
-
const y = b.codePointAt(at) ?? 0;
|
|
554
|
-
if (x !== y) {
|
|
555
|
-
return x < y ? -1 : 1;
|
|
556
|
-
}
|
|
557
|
-
at += x > 0xffff ? 2 : 1;
|
|
558
|
-
}
|
|
559
|
-
return a.length - b.length;
|
|
560
|
-
}
|
|
561
546
|
/** The escapes `%q` writes for the control characters that have one of their own. */
|
|
562
547
|
const QUOTED_ESCAPES = {
|
|
563
548
|
'"': '\\"',
|
|
@@ -903,7 +888,7 @@ class Execution {
|
|
|
903
888
|
}
|
|
904
889
|
else if (isObject(value)) {
|
|
905
890
|
entries = Object.keys(value)
|
|
906
|
-
.sort()
|
|
891
|
+
.sort(bytewise)
|
|
907
892
|
.map((key) => [key, value[key] ?? null]);
|
|
908
893
|
}
|
|
909
894
|
else {
|