@goodbones/core 0.1.0-beta.10 → 0.1.0-beta.12
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/build/dts/core/structure.d.ts.map +1 -1
- package/build/dts/domain/architecture-config.d.ts +3 -310
- package/build/dts/domain/architecture-config.d.ts.map +1 -1
- package/build/dts/domain/snapshot.d.ts +150 -18
- package/build/dts/domain/snapshot.d.ts.map +1 -1
- package/build/dts/index.d.ts +11 -14
- package/build/dts/index.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -1
- package/build/dts/infrastructure/file-system-live.d.ts.map +1 -1
- package/build/dts/infrastructure/walk.d.ts +6 -1
- package/build/dts/infrastructure/walk.d.ts.map +1 -1
- package/build/dts/load/extension.d.ts +33 -0
- package/build/dts/load/extension.d.ts.map +1 -0
- package/build/dts/load/policy.d.ts +4 -10
- package/build/dts/load/policy.d.ts.map +1 -1
- package/build/dts/manifest/compile.d.ts +7 -2
- package/build/dts/manifest/compile.d.ts.map +1 -1
- package/build/dts/manifest/extension.d.ts +8 -0
- package/build/dts/manifest/extension.d.ts.map +1 -0
- package/build/dts/manifest/glob.d.ts +1 -0
- package/build/dts/manifest/glob.d.ts.map +1 -1
- package/build/dts/manifest/json-schema.d.ts +6 -2
- package/build/dts/manifest/json-schema.d.ts.map +1 -1
- package/build/dts/manifest/manifest.d.ts +7 -362
- package/build/dts/manifest/manifest.d.ts.map +1 -1
- package/build/dts/ports/file-system.d.ts +1 -0
- package/build/dts/ports/file-system.d.ts.map +1 -1
- package/build/dts/testing.d.ts +0 -1
- package/build/dts/testing.d.ts.map +1 -1
- package/build/esm/core/structure.js +1 -1
- package/build/esm/core/structure.js.map +1 -1
- package/build/esm/domain/architecture-config.js +3 -136
- package/build/esm/domain/architecture-config.js.map +1 -1
- package/build/esm/domain/snapshot.js +55 -15
- package/build/esm/domain/snapshot.js.map +1 -1
- package/build/esm/index.js +16 -10
- package/build/esm/index.js.map +1 -1
- package/build/esm/infrastructure/file-system-fake.js +10 -0
- package/build/esm/infrastructure/file-system-fake.js.map +1 -1
- package/build/esm/infrastructure/file-system-live.js +9 -1
- package/build/esm/infrastructure/file-system-live.js.map +1 -1
- package/build/esm/infrastructure/walk.js +50 -4
- package/build/esm/infrastructure/walk.js.map +1 -1
- package/build/esm/load/extension.js +2 -0
- package/build/esm/load/extension.js.map +1 -0
- package/build/esm/load/policy.js +43 -116
- package/build/esm/load/policy.js.map +1 -1
- package/build/esm/manifest/compile.js +3 -182
- package/build/esm/manifest/compile.js.map +1 -1
- package/build/esm/manifest/extension.js +2 -0
- package/build/esm/manifest/extension.js.map +1 -0
- package/build/esm/manifest/glob.js +3 -0
- package/build/esm/manifest/glob.js.map +1 -1
- package/build/esm/manifest/json-schema.js +45 -11
- package/build/esm/manifest/json-schema.js.map +1 -1
- package/build/esm/manifest/manifest.js +56 -172
- package/build/esm/manifest/manifest.js.map +1 -1
- package/build/esm/testing.js +0 -1
- package/build/esm/testing.js.map +1 -1
- package/package.json +1 -1
- package/schema/architecture-node.schema.json +0 -887
- package/schema/architecture.schema.json +3264 -1591
- package/schema/conformance.schema.json +291 -47
- package/src/core/structure.ts +5 -3
- package/src/domain/architecture-config.ts +3 -180
- package/src/domain/snapshot.ts +125 -25
- package/src/index.ts +51 -78
- package/src/infrastructure/file-system-fake.ts +12 -0
- package/src/infrastructure/file-system-live.ts +8 -1
- package/src/infrastructure/walk.ts +58 -3
- package/src/load/extension.ts +66 -0
- package/src/load/policy.ts +60 -175
- package/src/manifest/compile.ts +2 -213
- package/src/manifest/extension.ts +41 -0
- package/src/manifest/glob.ts +5 -0
- package/src/manifest/json-schema.ts +53 -11
- package/src/manifest/manifest.ts +82 -214
- package/src/ports/file-system.ts +3 -0
- package/src/testing.ts +0 -1
- package/build/dts/core/campaigns.d.ts +0 -141
- package/build/dts/core/campaigns.d.ts.map +0 -1
- package/build/dts/core/ledger.d.ts +0 -61
- package/build/dts/core/ledger.d.ts.map +0 -1
- package/build/dts/domain/report.d.ts +0 -16
- package/build/dts/domain/report.d.ts.map +0 -1
- package/build/dts/infrastructure/campaign-functions.d.ts +0 -7
- package/build/dts/infrastructure/campaign-functions.d.ts.map +0 -1
- package/build/dts/infrastructure/report-source-fake.d.ts +0 -4
- package/build/dts/infrastructure/report-source-fake.d.ts.map +0 -1
- package/build/dts/infrastructure/report-source-live.d.ts +0 -3
- package/build/dts/infrastructure/report-source-live.d.ts.map +0 -1
- package/build/dts/ports/campaign-predicate.d.ts +0 -24
- package/build/dts/ports/campaign-predicate.d.ts.map +0 -1
- package/build/dts/ports/report-source.d.ts +0 -14
- package/build/dts/ports/report-source.d.ts.map +0 -1
- package/build/esm/core/campaigns.js +0 -778
- package/build/esm/core/campaigns.js.map +0 -1
- package/build/esm/core/ledger.js +0 -171
- package/build/esm/core/ledger.js.map +0 -1
- package/build/esm/domain/report.js +0 -168
- package/build/esm/domain/report.js.map +0 -1
- package/build/esm/infrastructure/campaign-functions.js +0 -67
- package/build/esm/infrastructure/campaign-functions.js.map +0 -1
- package/build/esm/infrastructure/report-source-fake.js +0 -6
- package/build/esm/infrastructure/report-source-fake.js.map +0 -1
- package/build/esm/infrastructure/report-source-live.js +0 -165
- package/build/esm/infrastructure/report-source-live.js.map +0 -1
- package/build/esm/ports/campaign-predicate.js +0 -2
- package/build/esm/ports/campaign-predicate.js.map +0 -1
- package/build/esm/ports/report-source.js +0 -7
- package/build/esm/ports/report-source.js.map +0 -1
- package/src/core/campaigns.ts +0 -1056
- package/src/core/ledger.ts +0 -242
- package/src/domain/report.ts +0 -203
- package/src/infrastructure/campaign-functions.ts +0 -98
- package/src/infrastructure/report-source-fake.ts +0 -10
- package/src/infrastructure/report-source-live.ts +0 -192
- package/src/ports/campaign-predicate.ts +0 -30
- package/src/ports/report-source.ts +0 -35
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"version": {
|
|
9
9
|
"type": "number",
|
|
10
10
|
"enum": [
|
|
11
|
-
|
|
11
|
+
2
|
|
12
12
|
],
|
|
13
13
|
"description": "The shape of this document."
|
|
14
14
|
},
|
|
@@ -450,7 +450,19 @@
|
|
|
450
450
|
},
|
|
451
451
|
"ledgered": {
|
|
452
452
|
"type": "boolean",
|
|
453
|
-
"description": "For a campaign hit: carried by the
|
|
453
|
+
"description": "For a campaign hit: carried by the objective's ledger, so `check` does not fail on it."
|
|
454
|
+
},
|
|
455
|
+
"objective": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"description": "For a campaign hit: the objective that fired."
|
|
458
|
+
},
|
|
459
|
+
"sector": {
|
|
460
|
+
"type": "string",
|
|
461
|
+
"description": "For a campaign hit: the sector the hit falls in."
|
|
462
|
+
},
|
|
463
|
+
"entry": {
|
|
464
|
+
"type": "string",
|
|
465
|
+
"description": "For a campaign hit: its ledger entry, relative to the sector's root."
|
|
454
466
|
}
|
|
455
467
|
},
|
|
456
468
|
"required": [
|
|
@@ -649,7 +661,7 @@
|
|
|
649
661
|
"properties": {
|
|
650
662
|
"id": {
|
|
651
663
|
"type": "string",
|
|
652
|
-
"description": "The campaign's id; its
|
|
664
|
+
"description": "The campaign's id; its ledgers are under `<ledger>/<id>/`."
|
|
653
665
|
},
|
|
654
666
|
"title": {
|
|
655
667
|
"type": "string",
|
|
@@ -659,35 +671,11 @@
|
|
|
659
671
|
"type": "string",
|
|
660
672
|
"description": "Who is running the campaign, as the manifest names them."
|
|
661
673
|
},
|
|
662
|
-
"initial": {
|
|
663
|
-
"type": "number",
|
|
664
|
-
"allOf": [
|
|
665
|
-
{
|
|
666
|
-
"description": "Entries the day the ledger was written."
|
|
667
|
-
}
|
|
668
|
-
]
|
|
669
|
-
},
|
|
670
|
-
"allowed": {
|
|
671
|
-
"type": "number",
|
|
672
|
-
"allOf": [
|
|
673
|
-
{
|
|
674
|
-
"description": "Entries added since by `campaigns allow`, each with a regression record."
|
|
675
|
-
}
|
|
676
|
-
]
|
|
677
|
-
},
|
|
678
674
|
"count": {
|
|
679
675
|
"type": "number",
|
|
680
676
|
"allOf": [
|
|
681
677
|
{
|
|
682
|
-
"description": "
|
|
683
|
-
}
|
|
684
|
-
]
|
|
685
|
-
},
|
|
686
|
-
"fixed": {
|
|
687
|
-
"type": "number",
|
|
688
|
-
"allOf": [
|
|
689
|
-
{
|
|
690
|
-
"description": "Entries removed by `campaigns prune` since the ledger was written."
|
|
678
|
+
"description": "Holdouts across every objective and sector."
|
|
691
679
|
}
|
|
692
680
|
]
|
|
693
681
|
},
|
|
@@ -695,29 +683,285 @@
|
|
|
695
683
|
"type": "number",
|
|
696
684
|
"allOf": [
|
|
697
685
|
{
|
|
698
|
-
"description": "
|
|
686
|
+
"description": "Cleared over everything ever ledgered, across the campaign's objectives."
|
|
699
687
|
}
|
|
700
688
|
]
|
|
701
689
|
},
|
|
702
|
-
"
|
|
703
|
-
"type": "
|
|
704
|
-
"
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
690
|
+
"objectives": {
|
|
691
|
+
"type": "array",
|
|
692
|
+
"items": {
|
|
693
|
+
"type": "object",
|
|
694
|
+
"properties": {
|
|
695
|
+
"id": {
|
|
696
|
+
"type": "string",
|
|
697
|
+
"description": "The objective's id; its ledger is `<ledger>/<campaign>/<objective>.json`."
|
|
698
|
+
},
|
|
699
|
+
"phase": {
|
|
700
|
+
"anyOf": [
|
|
701
|
+
{
|
|
702
|
+
"type": "string"
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
"type": "null"
|
|
706
|
+
}
|
|
707
|
+
],
|
|
708
|
+
"description": "The phase naming the objective, or `null` for one no phase names — in window everywhere."
|
|
709
|
+
},
|
|
710
|
+
"initial": {
|
|
711
|
+
"type": "number",
|
|
712
|
+
"allOf": [
|
|
713
|
+
{
|
|
714
|
+
"description": "Holdouts recorded as each sector entered the window, summed."
|
|
715
|
+
}
|
|
716
|
+
]
|
|
717
|
+
},
|
|
718
|
+
"allowed": {
|
|
719
|
+
"type": "number",
|
|
720
|
+
"allOf": [
|
|
721
|
+
{
|
|
722
|
+
"description": "Holdouts added since by `objectives concede` or a re-baseline, each with a concession."
|
|
723
|
+
}
|
|
724
|
+
]
|
|
725
|
+
},
|
|
726
|
+
"count": {
|
|
727
|
+
"type": "number",
|
|
728
|
+
"allOf": [
|
|
729
|
+
{
|
|
730
|
+
"description": "Holdouts in the ledger now, every sector summed."
|
|
731
|
+
}
|
|
732
|
+
]
|
|
733
|
+
},
|
|
734
|
+
"cleared": {
|
|
735
|
+
"type": "number",
|
|
736
|
+
"allOf": [
|
|
737
|
+
{
|
|
738
|
+
"description": "Holdouts removed by `objectives clear` because they stopped firing."
|
|
739
|
+
}
|
|
740
|
+
]
|
|
741
|
+
},
|
|
742
|
+
"closed": {
|
|
743
|
+
"type": "number",
|
|
744
|
+
"allOf": [
|
|
745
|
+
{
|
|
746
|
+
"description": "Holdouts still firing when a sector left the window — not progress."
|
|
747
|
+
}
|
|
748
|
+
]
|
|
749
|
+
},
|
|
750
|
+
"progress": {
|
|
751
|
+
"type": "number",
|
|
752
|
+
"allOf": [
|
|
753
|
+
{
|
|
754
|
+
"description": "`1 - count / (initial + allowed - closed)`: how much of everything ever ledgered has been paid down."
|
|
755
|
+
}
|
|
756
|
+
]
|
|
757
|
+
},
|
|
758
|
+
"lastCleared": {
|
|
759
|
+
"anyOf": [
|
|
760
|
+
{
|
|
761
|
+
"type": "string"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
"type": "null"
|
|
765
|
+
}
|
|
766
|
+
],
|
|
767
|
+
"description": "When a holdout last left the ledger, ISO 8601 — the stall clock's reading; `null` with no ledger."
|
|
768
|
+
},
|
|
769
|
+
"concessions": {
|
|
770
|
+
"type": "number",
|
|
771
|
+
"allOf": [
|
|
772
|
+
{
|
|
773
|
+
"description": "How many times a count was allowed to go up."
|
|
774
|
+
}
|
|
775
|
+
]
|
|
776
|
+
},
|
|
777
|
+
"complete": {
|
|
778
|
+
"type": "boolean",
|
|
779
|
+
"description": "No holdouts remain."
|
|
780
|
+
},
|
|
781
|
+
"ledgered": {
|
|
782
|
+
"type": "boolean",
|
|
783
|
+
"description": "Whether a ledger exists. An objective with none has been declared and not yet cleared."
|
|
784
|
+
}
|
|
785
|
+
},
|
|
786
|
+
"required": [
|
|
787
|
+
"id",
|
|
788
|
+
"phase",
|
|
789
|
+
"initial",
|
|
790
|
+
"allowed",
|
|
791
|
+
"count",
|
|
792
|
+
"cleared",
|
|
793
|
+
"closed",
|
|
794
|
+
"progress",
|
|
795
|
+
"lastCleared",
|
|
796
|
+
"concessions",
|
|
797
|
+
"complete",
|
|
798
|
+
"ledgered"
|
|
799
|
+
],
|
|
800
|
+
"additionalProperties": false
|
|
801
|
+
},
|
|
802
|
+
"description": "Every objective, in manifest order."
|
|
803
|
+
},
|
|
804
|
+
"phases": {
|
|
805
|
+
"type": "array",
|
|
806
|
+
"items": {
|
|
807
|
+
"type": "object",
|
|
808
|
+
"properties": {
|
|
809
|
+
"id": {
|
|
810
|
+
"type": "string",
|
|
811
|
+
"description": "The phase's id."
|
|
812
|
+
},
|
|
813
|
+
"defined": {
|
|
814
|
+
"type": "boolean",
|
|
815
|
+
"description": "Whether the phase names criteria. An open phase has only an intent, and is last."
|
|
816
|
+
},
|
|
817
|
+
"sectors": {
|
|
818
|
+
"type": "number",
|
|
819
|
+
"allOf": [
|
|
820
|
+
{
|
|
821
|
+
"description": "How many sectors are derived to stand at this phase."
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
}
|
|
825
|
+
},
|
|
826
|
+
"required": [
|
|
827
|
+
"id",
|
|
828
|
+
"defined",
|
|
829
|
+
"sectors"
|
|
830
|
+
],
|
|
831
|
+
"additionalProperties": false
|
|
832
|
+
},
|
|
833
|
+
"description": "The ladder, in order, with how many sectors stand at each phase."
|
|
834
|
+
},
|
|
835
|
+
"sectors": {
|
|
836
|
+
"type": "array",
|
|
837
|
+
"items": {
|
|
838
|
+
"type": "object",
|
|
839
|
+
"properties": {
|
|
840
|
+
"name": {
|
|
841
|
+
"type": "string",
|
|
842
|
+
"description": "The sector's identity, as its perimeter names it."
|
|
843
|
+
},
|
|
844
|
+
"phase": {
|
|
845
|
+
"anyOf": [
|
|
846
|
+
{
|
|
847
|
+
"type": "string"
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"type": "null"
|
|
851
|
+
}
|
|
852
|
+
],
|
|
853
|
+
"description": "The phase the sector is derived to stand at, or `null` when it is past the last one."
|
|
854
|
+
},
|
|
855
|
+
"reached": {
|
|
856
|
+
"anyOf": [
|
|
857
|
+
{
|
|
858
|
+
"type": "string"
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"type": "null"
|
|
862
|
+
}
|
|
863
|
+
],
|
|
864
|
+
"description": "The furthest phase the sector's record says it has reached; `null` before its first `clear`."
|
|
865
|
+
},
|
|
866
|
+
"files": {
|
|
867
|
+
"type": "number",
|
|
868
|
+
"allOf": [
|
|
869
|
+
{
|
|
870
|
+
"description": "How many files the sector claims."
|
|
871
|
+
}
|
|
872
|
+
]
|
|
873
|
+
},
|
|
874
|
+
"residue": {
|
|
875
|
+
"type": "object",
|
|
876
|
+
"additionalProperties": {
|
|
877
|
+
"type": "number"
|
|
878
|
+
},
|
|
879
|
+
"description": "One dimension per objective in window for the sector: its holdouts there, never summed."
|
|
880
|
+
},
|
|
881
|
+
"stalled": {
|
|
882
|
+
"type": "boolean",
|
|
883
|
+
"description": "Holdouts remain for the sector and nothing has been cleared, attested or noted within `staleAfter`."
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
"required": [
|
|
887
|
+
"name",
|
|
888
|
+
"phase",
|
|
889
|
+
"reached",
|
|
890
|
+
"files",
|
|
891
|
+
"residue",
|
|
892
|
+
"stalled"
|
|
893
|
+
],
|
|
894
|
+
"additionalProperties": false
|
|
895
|
+
},
|
|
896
|
+
"description": "Every sector the perimeter births, by name."
|
|
897
|
+
},
|
|
898
|
+
"legacy": {
|
|
899
|
+
"type": "object",
|
|
900
|
+
"properties": {
|
|
901
|
+
"files": {
|
|
902
|
+
"type": "number",
|
|
903
|
+
"allOf": [
|
|
904
|
+
{
|
|
905
|
+
"description": "Files in the scope no sector claims."
|
|
906
|
+
}
|
|
907
|
+
]
|
|
908
|
+
},
|
|
909
|
+
"holdouts": {
|
|
910
|
+
"type": "number",
|
|
911
|
+
"allOf": [
|
|
912
|
+
{
|
|
913
|
+
"description": "Holdouts in the legacy, under the first phase's objectives — where a holdout moved out of a sector lands."
|
|
914
|
+
}
|
|
915
|
+
]
|
|
711
916
|
}
|
|
712
|
-
|
|
917
|
+
},
|
|
918
|
+
"required": [
|
|
919
|
+
"files",
|
|
920
|
+
"holdouts"
|
|
921
|
+
],
|
|
922
|
+
"additionalProperties": false,
|
|
923
|
+
"description": "The unclaimed remainder of the scope, which stands at the first phase and is not a sink."
|
|
924
|
+
},
|
|
925
|
+
"plan": {
|
|
926
|
+
"type": "object",
|
|
927
|
+
"properties": {
|
|
928
|
+
"refined": {
|
|
929
|
+
"type": "array",
|
|
930
|
+
"items": {
|
|
931
|
+
"type": "string"
|
|
932
|
+
},
|
|
933
|
+
"description": "Phases refined since the last `clear`: an open phase that gained criteria, or a new one. Free."
|
|
934
|
+
},
|
|
935
|
+
"changed": {
|
|
936
|
+
"type": "array",
|
|
937
|
+
"items": {
|
|
938
|
+
"type": "string"
|
|
939
|
+
},
|
|
940
|
+
"description": "Defined phases whose definition changed since the last `clear` — what a reviewer reads every time."
|
|
941
|
+
},
|
|
942
|
+
"unreceipted": {
|
|
943
|
+
"type": "array",
|
|
944
|
+
"items": {
|
|
945
|
+
"type": "string"
|
|
946
|
+
},
|
|
947
|
+
"description": "Changed phases carrying no new concession; `check` fails on them."
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
"required": [
|
|
951
|
+
"refined",
|
|
952
|
+
"changed",
|
|
953
|
+
"unreceipted"
|
|
954
|
+
],
|
|
955
|
+
"additionalProperties": false,
|
|
956
|
+
"description": "What changed in the plan, refinements and changes apart."
|
|
713
957
|
},
|
|
714
958
|
"stalled": {
|
|
715
959
|
"type": "boolean",
|
|
716
|
-
"description": "
|
|
960
|
+
"description": "Holdouts remain and nothing has been cleared, attested or noted within the campaign's `staleAfter`."
|
|
717
961
|
},
|
|
718
962
|
"complete": {
|
|
719
963
|
"type": "boolean",
|
|
720
|
-
"description": "No
|
|
964
|
+
"description": "No holdouts remain in any objective."
|
|
721
965
|
},
|
|
722
966
|
"onComplete": {
|
|
723
967
|
"type": "string",
|
|
@@ -729,18 +973,18 @@
|
|
|
729
973
|
},
|
|
730
974
|
"ledgered": {
|
|
731
975
|
"type": "boolean",
|
|
732
|
-
"description": "Whether
|
|
976
|
+
"description": "Whether every objective has a ledger."
|
|
733
977
|
}
|
|
734
978
|
},
|
|
735
979
|
"required": [
|
|
736
980
|
"id",
|
|
737
|
-
"initial",
|
|
738
|
-
"allowed",
|
|
739
981
|
"count",
|
|
740
|
-
"fixed",
|
|
741
982
|
"progress",
|
|
742
|
-
"
|
|
743
|
-
"
|
|
983
|
+
"objectives",
|
|
984
|
+
"phases",
|
|
985
|
+
"sectors",
|
|
986
|
+
"legacy",
|
|
987
|
+
"plan",
|
|
744
988
|
"stalled",
|
|
745
989
|
"complete",
|
|
746
990
|
"onComplete",
|
package/src/core/structure.ts
CHANGED
|
@@ -333,9 +333,11 @@ export const structureRulesFailingTheirProbe = (
|
|
|
333
333
|
|
|
334
334
|
const layoutOnly = { ...structure, parity: [] };
|
|
335
335
|
const reported = (file: string): ReadonlyArray<string> =>
|
|
336
|
-
evaluateStructure(
|
|
337
|
-
|
|
338
|
-
|
|
336
|
+
evaluateStructure(
|
|
337
|
+
layoutOnly,
|
|
338
|
+
{ exists: () => true, readText: () => null, list: () => [] },
|
|
339
|
+
file,
|
|
340
|
+
).map((violation) => violation.ruleName);
|
|
339
341
|
|
|
340
342
|
for (const rule of structure.folders) {
|
|
341
343
|
// A folder that admits any name claims its folder but states no policy, so
|
|
@@ -4,7 +4,7 @@ import * as Schema from "effect/Schema";
|
|
|
4
4
|
// matched against a repo-relative, forward-slash path — the same vocabulary
|
|
5
5
|
// dependency-cruiser rules are written in, so a rule ported from there keeps its
|
|
6
6
|
// pattern character-for-character. A list matches when ANY member matches.
|
|
7
|
-
const PatternList = Schema.Union([Schema.String, Schema.Array(Schema.String)]);
|
|
7
|
+
export const PatternList = Schema.Union([Schema.String, Schema.Array(Schema.String)]);
|
|
8
8
|
|
|
9
9
|
// An import edge is a violation when the importer matches `from` (and not
|
|
10
10
|
// `fromNot`) AND the resolved target matches `to` (and not `toNot`). Omitting
|
|
@@ -99,7 +99,7 @@ export const ExportFix = Schema.Literals(["subpath-namespace-import"]);
|
|
|
99
99
|
// Which binding form an import site used. A rule that fences off a factory
|
|
100
100
|
// function cares about `named`; one steering people to namespace subpath imports
|
|
101
101
|
// cares that `named` was used at all.
|
|
102
|
-
const BindingKind = Schema.Literals(["named", "default", "namespace"]);
|
|
102
|
+
export const BindingKind = Schema.Literals(["named", "default", "namespace"]);
|
|
103
103
|
|
|
104
104
|
// `source`, when present, is a snippet the loading adapter parses: the probe
|
|
105
105
|
// then holds only if a binding named `symbol` comes out of the parser and the
|
|
@@ -164,7 +164,7 @@ export const DeclarationKind = Schema.Literals([
|
|
|
164
164
|
// identifiers (the hooks a tier may reach for). Which declarations a `members`
|
|
165
165
|
// rule speaks to is `declares`' to say, so the vocabulary carries no language's
|
|
166
166
|
// split between types and values.
|
|
167
|
-
const MemberSubject = Schema.Literals(["members", "calls"]);
|
|
167
|
+
export const MemberSubject = Schema.Literals(["members", "calls"]);
|
|
168
168
|
|
|
169
169
|
// `source`, when present, is a snippet the loading adapter parses: the probe
|
|
170
170
|
// then holds only if a site named `name` comes out of the parser and the rule
|
|
@@ -295,177 +295,6 @@ export const GraphConfig = Schema.Struct({
|
|
|
295
295
|
reach: Schema.optionalKey(Schema.Array(GraphReachRule)),
|
|
296
296
|
});
|
|
297
297
|
|
|
298
|
-
// A campaign: a migration tracked as an object in the repository. Where a
|
|
299
|
-
// rule says what may never happen, a campaign names a pattern the code is
|
|
300
|
-
// moving away from, ledgers every place it still occurs, and refuses to let
|
|
301
|
-
// the count go up unrecorded. Lowered from the manifest's `campaigns` list
|
|
302
|
-
// with its globs resolved; the detector below is what the evaluator compiles.
|
|
303
|
-
|
|
304
|
-
// What a hit is: a whole file, a named declaration in it, or one matched
|
|
305
|
-
// expression. The unit decides what a term from another level means (a
|
|
306
|
-
// file-level term in a declaration campaign is a filter; a declaration-level
|
|
307
|
-
// term in a file campaign is existential) and what the fingerprint anchors on.
|
|
308
|
-
export const CampaignUnit = Schema.Literals(["file", "declaration", "match"]);
|
|
309
|
-
|
|
310
|
-
// The detector's leaf terms. Every pattern is a regular-expression source,
|
|
311
|
-
// as everywhere else in this config; the manifest writes globs and lowering
|
|
312
|
-
// translates them. Each term answers at one level — `path`, `imports`,
|
|
313
|
-
// `requires`, `content` and a boolean `fn` about the file; `exports` and
|
|
314
|
-
// `members` about a declaration; `syntax` and a listing `fn` about a match.
|
|
315
|
-
const PathTerm = Schema.Struct({
|
|
316
|
-
file: PatternList,
|
|
317
|
-
fileNot: Schema.optionalKey(PatternList),
|
|
318
|
-
// With `convention`: which capture group of `file` holds the name being
|
|
319
|
-
// judged, and the shape it must have for the term to hold.
|
|
320
|
-
subject: Schema.optionalKey(Schema.Finite),
|
|
321
|
-
convention: Schema.optionalKey(Schema.String),
|
|
322
|
-
});
|
|
323
|
-
export type PathTerm = (typeof PathTerm)["Type"];
|
|
324
|
-
|
|
325
|
-
const ImportsTerm = Schema.Struct({
|
|
326
|
-
// Where an edge of the file must resolve to: a path pattern, a package
|
|
327
|
-
// name, or a builtin. Holds when at least one edge does.
|
|
328
|
-
resolves: ImportProbeTarget,
|
|
329
|
-
// Names that must be pulled across that edge; omit for any binding.
|
|
330
|
-
symbols: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
331
|
-
});
|
|
332
|
-
export type ImportsTerm = (typeof ImportsTerm)["Type"];
|
|
333
|
-
|
|
334
|
-
const ExportsTerm = Schema.Struct({
|
|
335
|
-
name: Schema.optionalKey(PatternList),
|
|
336
|
-
kinds: Schema.optionalKey(Schema.Array(BindingKind)),
|
|
337
|
-
declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
|
|
338
|
-
reexport: Schema.optionalKey(Schema.Boolean),
|
|
339
|
-
});
|
|
340
|
-
export type ExportsTerm = (typeof ExportsTerm)["Type"];
|
|
341
|
-
|
|
342
|
-
const MembersTerm = Schema.Struct({
|
|
343
|
-
subject: MemberSubject,
|
|
344
|
-
name: Schema.optionalKey(PatternList),
|
|
345
|
-
in: Schema.optionalKey(PatternList),
|
|
346
|
-
declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
|
|
347
|
-
});
|
|
348
|
-
export type MembersTerm = (typeof MembersTerm)["Type"];
|
|
349
|
-
|
|
350
|
-
const ContentTerm = Schema.Struct({ regex: Schema.String });
|
|
351
|
-
type ContentTerm = (typeof ContentTerm)["Type"];
|
|
352
|
-
|
|
353
|
-
// How a metavariable of a syntax rule is narrowed: by the text it captured,
|
|
354
|
-
// or by what the identifier at its root is bound to — the module it was
|
|
355
|
-
// imported from and the name it was imported as.
|
|
356
|
-
const BindingNarrowing = Schema.Struct({
|
|
357
|
-
resolves: ImportProbeTarget,
|
|
358
|
-
member: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
359
|
-
});
|
|
360
|
-
|
|
361
|
-
const CaptureNarrowing = Schema.Struct({
|
|
362
|
-
regex: Schema.optionalKey(Schema.String),
|
|
363
|
-
binding: Schema.optionalKey(BindingNarrowing),
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
const SyntaxTerm = Schema.Struct({
|
|
367
|
-
// The engine's rule object, carried opaquely: the matcher validates it.
|
|
368
|
-
rule: Schema.Unknown,
|
|
369
|
-
where: Schema.optionalKey(Schema.Record(Schema.String, CaptureNarrowing)),
|
|
370
|
-
});
|
|
371
|
-
export type SyntaxTerm = (typeof SyntaxTerm)["Type"];
|
|
372
|
-
|
|
373
|
-
// A pattern no parser of ours sees, reported by another program: a type
|
|
374
|
-
// error, another linter's finding. Exactly one of `command` (run from the
|
|
375
|
-
// repository root, once per process) and `file` (written by an earlier
|
|
376
|
-
// step), each a list — the manifest's one string lowered to a list of one —
|
|
377
|
-
// read as one report. Each diagnostic on a file is a match anchored on the
|
|
378
|
-
// declaration at its position, keyed by its code and a hash of its message.
|
|
379
|
-
export const ReportFormat = Schema.Literals(["tsc", "eslint", "oxlint", "regex"]);
|
|
380
|
-
|
|
381
|
-
const ReportTerm = Schema.Struct({
|
|
382
|
-
command: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
383
|
-
file: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
384
|
-
format: ReportFormat,
|
|
385
|
-
// `regex` only: named groups `file`, `line`, and optionally `column`,
|
|
386
|
-
// `code`, `message`.
|
|
387
|
-
pattern: Schema.optionalKey(Schema.String),
|
|
388
|
-
// The codes the term speaks to; omit for every one.
|
|
389
|
-
codes: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
390
|
-
codesNot: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
391
|
-
});
|
|
392
|
-
export type ReportTerm = (typeof ReportTerm)["Type"];
|
|
393
|
-
|
|
394
|
-
export type Detector =
|
|
395
|
-
| { readonly all: ReadonlyArray<Detector> }
|
|
396
|
-
| { readonly any: ReadonlyArray<Detector> }
|
|
397
|
-
| { readonly not: Detector }
|
|
398
|
-
| { readonly path: PathTerm }
|
|
399
|
-
| { readonly imports: ImportsTerm }
|
|
400
|
-
| { readonly exports: ExportsTerm }
|
|
401
|
-
| { readonly members: MembersTerm }
|
|
402
|
-
| { readonly requires: ReadonlyArray<string> }
|
|
403
|
-
| { readonly content: ContentTerm }
|
|
404
|
-
| { readonly syntax: SyntaxTerm }
|
|
405
|
-
| { readonly report: ReportTerm }
|
|
406
|
-
// `module#export`, resolved by the host before the policy loads.
|
|
407
|
-
| { readonly fn: string };
|
|
408
|
-
|
|
409
|
-
const DetectorRef = Schema.suspend((): Schema.Codec<Detector> => Detector);
|
|
410
|
-
|
|
411
|
-
export const Detector = Schema.Union([
|
|
412
|
-
Schema.Struct({ all: Schema.Array(DetectorRef) }),
|
|
413
|
-
Schema.Struct({ any: Schema.Array(DetectorRef) }),
|
|
414
|
-
Schema.Struct({ not: DetectorRef }),
|
|
415
|
-
Schema.Struct({ path: PathTerm }),
|
|
416
|
-
Schema.Struct({ imports: ImportsTerm }),
|
|
417
|
-
Schema.Struct({ exports: ExportsTerm }),
|
|
418
|
-
Schema.Struct({ members: MembersTerm }),
|
|
419
|
-
Schema.Struct({ requires: Schema.Array(Schema.String) }),
|
|
420
|
-
Schema.Struct({ content: ContentTerm }),
|
|
421
|
-
Schema.Struct({ syntax: SyntaxTerm }),
|
|
422
|
-
Schema.Struct({ report: ReportTerm }),
|
|
423
|
-
Schema.Struct({ fn: Schema.String }),
|
|
424
|
-
]);
|
|
425
|
-
|
|
426
|
-
// One diagnostic a probe stands in for, positions one-based as a tool
|
|
427
|
-
// prints them.
|
|
428
|
-
export const ProbeDiagnostic = Schema.Struct({
|
|
429
|
-
line: Schema.Finite,
|
|
430
|
-
column: Schema.optionalKey(Schema.Finite),
|
|
431
|
-
code: Schema.optionalKey(Schema.String),
|
|
432
|
-
message: Schema.optionalKey(Schema.String),
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
// A source the campaign is proven against: the path it would have, its text
|
|
436
|
-
// when a term needs one, the target of each of its edges (in place of the live
|
|
437
|
-
// resolver), the files beside it (in place of the file system) and the
|
|
438
|
-
// diagnostics reported on it (in place of the report source).
|
|
439
|
-
export const CampaignProbe = Schema.Struct({
|
|
440
|
-
path: Schema.String,
|
|
441
|
-
source: Schema.optionalKey(Schema.String),
|
|
442
|
-
edges: Schema.optionalKey(Schema.Record(Schema.String, ImportProbeTarget)),
|
|
443
|
-
files: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
444
|
-
report: Schema.optionalKey(Schema.Array(ProbeDiagnostic)),
|
|
445
|
-
});
|
|
446
|
-
|
|
447
|
-
export const CampaignRule = Schema.Struct({
|
|
448
|
-
// `campaign/<id>`, the rule name a violation carries.
|
|
449
|
-
name: Schema.String,
|
|
450
|
-
id: Schema.String,
|
|
451
|
-
title: Schema.optionalKey(Schema.String),
|
|
452
|
-
// The `how`: what a reader at a hit does about it.
|
|
453
|
-
message: Schema.String,
|
|
454
|
-
why: Schema.String,
|
|
455
|
-
owner: Schema.optionalKey(Schema.String),
|
|
456
|
-
scope: PatternList,
|
|
457
|
-
unit: CampaignUnit,
|
|
458
|
-
detect: Detector,
|
|
459
|
-
probes: Schema.Struct({
|
|
460
|
-
fires: Schema.Array(CampaignProbe),
|
|
461
|
-
ignores: Schema.Array(CampaignProbe),
|
|
462
|
-
}),
|
|
463
|
-
// Milliseconds without progress after which the campaign is stalled.
|
|
464
|
-
staleAfter: Schema.Finite,
|
|
465
|
-
// What `check` demands once the count is zero: keep the campaign as a
|
|
466
|
-
// guard against recurrence, or remove it from the manifest.
|
|
467
|
-
onComplete: Schema.Literals(["keep", "remove"]),
|
|
468
|
-
});
|
|
469
298
|
|
|
470
299
|
const PathProbe = Schema.Struct({ path: Schema.String });
|
|
471
300
|
|
|
@@ -559,12 +388,6 @@ export type StructureRoot = (typeof StructureRoot)["Type"];
|
|
|
559
388
|
export type StructureFolder = (typeof StructureFolder)["Type"];
|
|
560
389
|
export type StructureParity = (typeof StructureParity)["Type"];
|
|
561
390
|
export type StructureNaming = (typeof StructureNaming)["Type"];
|
|
562
|
-
export type CampaignUnit = (typeof CampaignUnit)["Type"];
|
|
563
|
-
export type CampaignProbe = (typeof CampaignProbe)["Type"];
|
|
564
|
-
export type ProbeDiagnostic = (typeof ProbeDiagnostic)["Type"];
|
|
565
|
-
export type ReportFormat = (typeof ReportFormat)["Type"];
|
|
566
|
-
export type CampaignRule = (typeof CampaignRule)["Type"];
|
|
567
|
-
export type CaptureNarrowing = (typeof CaptureNarrowing)["Type"];
|
|
568
391
|
|
|
569
392
|
// The file pattern an open folder's layout rule carries: it admits any name,
|
|
570
393
|
// so it claims the folder without policing it. Coverage counts it apart.
|