@ttsc/evidence 0.25.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.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +279 -0
  3. package/lib/index.d.ts +65 -0
  4. package/lib/index.js +87 -0
  5. package/lib/internal/loadPrismaModels.d.ts +1 -0
  6. package/lib/internal/loadPrismaModels.js +197 -0
  7. package/lib/internal/loadSwaggerOperations.d.ts +1 -0
  8. package/lib/internal/loadSwaggerOperations.js +156 -0
  9. package/lib/internal/normalizeSwaggerDocument.d.ts +1 -0
  10. package/lib/internal/normalizeSwaggerDocument.js +7 -0
  11. package/lib/structures/ITtscEvidenceDocumentedConfig.d.ts +32 -0
  12. package/lib/structures/ITtscEvidenceDocumentedConfig.js +2 -0
  13. package/lib/structures/ITtscEvidenceGraphClaim.d.ts +14 -0
  14. package/lib/structures/ITtscEvidenceGraphClaim.js +2 -0
  15. package/lib/structures/ITtscEvidenceGraphClaimBase.d.ts +102 -0
  16. package/lib/structures/ITtscEvidenceGraphClaimBase.js +2 -0
  17. package/lib/structures/ITtscEvidenceGraphConfig.d.ts +19 -0
  18. package/lib/structures/ITtscEvidenceGraphConfig.js +2 -0
  19. package/lib/structures/ITtscEvidenceGraphMarkdownClaim.d.ts +40 -0
  20. package/lib/structures/ITtscEvidenceGraphMarkdownClaim.js +2 -0
  21. package/lib/structures/ITtscEvidenceGraphMarkdownReference.d.ts +76 -0
  22. package/lib/structures/ITtscEvidenceGraphMarkdownReference.js +2 -0
  23. package/lib/structures/ITtscEvidenceGraphPrismaClaim.d.ts +65 -0
  24. package/lib/structures/ITtscEvidenceGraphPrismaClaim.js +2 -0
  25. package/lib/structures/ITtscEvidenceGraphPrismaReference.d.ts +75 -0
  26. package/lib/structures/ITtscEvidenceGraphPrismaReference.js +2 -0
  27. package/lib/structures/ITtscEvidenceGraphReference.d.ts +14 -0
  28. package/lib/structures/ITtscEvidenceGraphReference.js +2 -0
  29. package/lib/structures/ITtscEvidenceGraphReferenceBase.d.ts +73 -0
  30. package/lib/structures/ITtscEvidenceGraphReferenceBase.js +2 -0
  31. package/lib/structures/ITtscEvidenceGraphSwaggerReference.d.ts +39 -0
  32. package/lib/structures/ITtscEvidenceGraphSwaggerReference.js +2 -0
  33. package/lib/structures/ITtscEvidenceGraphTypeScriptClaim.d.ts +54 -0
  34. package/lib/structures/ITtscEvidenceGraphTypeScriptClaim.js +2 -0
  35. package/lib/structures/ITtscEvidenceGraphTypeScriptReference.d.ts +83 -0
  36. package/lib/structures/ITtscEvidenceGraphTypeScriptReference.js +2 -0
  37. package/lib/structures/index.d.ts +13 -0
  38. package/lib/structures/index.js +29 -0
  39. package/lib/typings/ITtscLintContributorRules.d.ts +34 -0
  40. package/lib/typings/ITtscLintContributorRules.js +2 -0
  41. package/lib/typings/ITtscLintRuleOptionsMap.d.ts +20 -0
  42. package/lib/typings/ITtscLintRuleOptionsMap.js +2 -0
  43. package/lib/typings/TtscEvidenceGraphMarkdownSymbol.d.ts +32 -0
  44. package/lib/typings/TtscEvidenceGraphMarkdownSymbol.js +2 -0
  45. package/lib/typings/TtscEvidenceGraphPrismaSymbol.d.ts +38 -0
  46. package/lib/typings/TtscEvidenceGraphPrismaSymbol.js +2 -0
  47. package/lib/typings/TtscEvidenceGraphTypeScriptSymbol.d.ts +64 -0
  48. package/lib/typings/TtscEvidenceGraphTypeScriptSymbol.js +2 -0
  49. package/lib/typings/index.d.ts +5 -0
  50. package/lib/typings/index.js +21 -0
  51. package/native/base.go +298 -0
  52. package/native/config.go +798 -0
  53. package/native/declaration.go +240 -0
  54. package/native/documented.go +353 -0
  55. package/native/exports.go +484 -0
  56. package/native/glob.go +207 -0
  57. package/native/graph.go +1409 -0
  58. package/native/health.go +45 -0
  59. package/native/hints.go +261 -0
  60. package/native/imports.go +373 -0
  61. package/native/inputs.go +125 -0
  62. package/native/loader.go +424 -0
  63. package/native/markdown.go +423 -0
  64. package/native/model.go +296 -0
  65. package/native/prisma.go +719 -0
  66. package/native/prisma_cache.go +213 -0
  67. package/native/prisma_locator.go +417 -0
  68. package/native/singular.go +369 -0
  69. package/native/swagger.go +331 -0
  70. package/native/swagger_cache.go +274 -0
  71. package/native/todo.go +138 -0
  72. package/native/typescript.go +1199 -0
  73. package/native/typescript_cache.go +96 -0
  74. package/package.json +64 -0
@@ -0,0 +1,296 @@
1
+ package evidence
2
+
3
+ import (
4
+ "sort"
5
+ "strings"
6
+
7
+ shimast "github.com/microsoft/typescript-go/shim/ast"
8
+ )
9
+
10
+ const graphRuleName = "evidence/graph"
11
+
12
+ const singularRuleName = "evidence/singular"
13
+
14
+ const documentedRuleName = "evidence/documented"
15
+
16
+ const todoRuleName = "evidence/todo"
17
+
18
+ type artifactKind string
19
+
20
+ const (
21
+ artifactMarkdown artifactKind = "markdown"
22
+ artifactPrisma artifactKind = "prisma"
23
+ artifactSwagger artifactKind = "swagger"
24
+ artifactTypeScript artifactKind = "typescript"
25
+ )
26
+
27
+ type tagKind string
28
+
29
+ const (
30
+ tagEvidence tagKind = "evidence"
31
+ tagExclude tagKind = "evidenceExclude"
32
+ )
33
+
34
+ type graphConfig struct {
35
+ Claims []claimSpec
36
+ }
37
+
38
+ type claimSpec struct {
39
+ Index int
40
+ Type artifactKind
41
+ Name string
42
+ Disabled bool
43
+ // Root is the author's spelling of the directory this population resolves
44
+ // against, empty when the ttsc project root is the base. It is kept beside
45
+ // the resolved Base because the two are produced at different times: the
46
+ // spelling decodes from options alone, while the resolution needs a project
47
+ // identity the decoder never sees.
48
+ Root string
49
+ Base populationBase
50
+ Files globSet
51
+ // ExclusionCarriers narrows where this claim's @evidenceExclude may sit.
52
+ // Empty keeps the historical behavior, where an exclusion is eligible
53
+ // anywhere in Files. Declared, only a carrier file hosts one, so every
54
+ // exclusion a claim owns is read by opening one file.
55
+ ExclusionCarriers globSet
56
+ Symbols symbolSet
57
+ References []referenceSpec
58
+ }
59
+
60
+ type referenceSpec struct {
61
+ Index int
62
+ Type artifactKind
63
+ Policy referencePolicy
64
+ Root string
65
+ Base populationBase
66
+ Files globSet
67
+ Source string
68
+ // Package moves the base that Files resolves against from the project to an
69
+ // installed package. With no globs it also becomes the selection itself: the
70
+ // package's declaration entry defines the population by reachability, while
71
+ // identity still belongs to the file that declares each symbol.
72
+ Package string
73
+ Symbols symbolSet
74
+ }
75
+
76
+ // referencePolicy is a reference-local strengthening of the ordinary
77
+ // acknowledgement contract, declared flat on the public reference object. Its
78
+ // zero value preserves every previous graph behavior, so a reference written
79
+ // before these options existed decodes into the same model it always did.
80
+ type referencePolicy struct {
81
+ // NoExclude refuses @evidenceExclude as an acknowledgement of this
82
+ // population, leaving its targets owing positive evidence.
83
+ NoExclude bool
84
+ // UniqueEvidence allows at most one positive semantic claim host per
85
+ // selected unit.
86
+ UniqueEvidence bool
87
+ // SingleEvidencePerSymbol requires exactly one distinct selected unit from
88
+ // every selected semantic claim host, including the hosts carrying no tag.
89
+ SingleEvidencePerSymbol bool
90
+ }
91
+
92
+ // entrySelected reports whether this reference materializes by traversal.
93
+ func (reference referenceSpec) entrySelected() bool {
94
+ return reference.Package != "" && len(reference.Files.Patterns) == 0
95
+ }
96
+
97
+ type symbolSet map[string]bool
98
+
99
+ func (set symbolSet) contains(symbol string) bool {
100
+ return set[symbol]
101
+ }
102
+
103
+ func (set symbolSet) intersects(other symbolSet) bool {
104
+ for symbol := range set {
105
+ if other[symbol] {
106
+ return true
107
+ }
108
+ }
109
+ return false
110
+ }
111
+
112
+ func (set symbolSet) names() string {
113
+ order := []string{"file", "h1", "h2", "h3", "h4", "operation", "model", "column", "relation", "type", "function", "property"}
114
+ names := make([]string, 0, len(set))
115
+ known := map[string]bool{}
116
+ for _, name := range order {
117
+ known[name] = true
118
+ if set[name] {
119
+ names = append(names, name)
120
+ }
121
+ }
122
+ other := []string{}
123
+ for name := range set {
124
+ if !known[name] {
125
+ other = append(other, name)
126
+ }
127
+ }
128
+ sort.Strings(other)
129
+ names = append(names, other...)
130
+ return strings.Join(names, ", ")
131
+ }
132
+
133
+ type evidenceUnit struct {
134
+ ID string
135
+ ParentID string
136
+ Target string
137
+ // Identity is Target before joining, kept so an entry-relative address can
138
+ // be rebuilt segment by segment. Rewriting the joined string instead would
139
+ // let a literal dot inside a name collapse into qualification.
140
+ Identity []string
141
+ // Aliases are the additional addresses this unit answers to when an entry
142
+ // exposes it by more than one path. They resolve to this same unit, so a
143
+ // symbol reachable twice is still one coverage obligation.
144
+ Aliases []string
145
+ Type artifactKind
146
+ Symbol string
147
+ Path string
148
+ Line int
149
+ Readable string
150
+ // Hidden names the documentation tag by which this declaration withdrew
151
+ // itself from the public surface, empty when it did not. Such a unit is
152
+ // never selected and never hosts a declaration; it is retained only so a
153
+ // citation of it can be told why the target it names is not there.
154
+ Hidden string
155
+ }
156
+
157
+ func (unit *evidenceUnit) location() string {
158
+ if unit.Line <= 0 {
159
+ return unit.Path
160
+ }
161
+ return unit.Path + ":" + decimal(unit.Line)
162
+ }
163
+
164
+ type evidenceDeclaration struct {
165
+ ID string
166
+ HostID string
167
+ // SemanticHostIDs names the selected graph identities that physically host
168
+ // this declaration. HostID remains the source-position identity used only
169
+ // for same-block duplicate detection; policy cardinality must not confuse a
170
+ // declaration position with the public symbol identity it represents.
171
+ SemanticHostIDs []string
172
+ Type artifactKind
173
+ Tag tagKind
174
+ Target string
175
+ Reason string
176
+ Hosts symbolSet
177
+ // ExclusionCarrier permits only @evidenceExclude to participate without a
178
+ // selected host kind. File matching, target resolution, and claim-reference
179
+ // ownership still decide the obligations it can discharge.
180
+ ExclusionCarrier bool
181
+ Path string
182
+ Line int
183
+ Sequence int
184
+ }
185
+
186
+ func (declaration *evidenceDeclaration) location() string {
187
+ return declaration.Path + ":" + decimal(declaration.Line)
188
+ }
189
+
190
+ func (declaration *evidenceDeclaration) valid() bool {
191
+ return declaration.Target != "" && declaration.Reason != ""
192
+ }
193
+
194
+ type artifactInventory struct {
195
+ // Address is the population-relative identity used for units and
196
+ // declarations. It differs from Path when a configured root moves the
197
+ // address space while diagnostics remain project-relative.
198
+ Address string
199
+ // Path is the location a diagnostic names: project-relative, ascending with
200
+ // `..` when the file sits above the project root. It is not the key this
201
+ // inventory is filed under — that key carries the population base as well,
202
+ // because one file reached through two roots owns two sets of targets.
203
+ Path string
204
+ Type artifactKind
205
+ Units []*evidenceUnit
206
+ Declarations []*evidenceDeclaration
207
+ Problems []inventoryProblem
208
+ // LoadFailed distinguishes an unreadable or rejected artifact from a
209
+ // healthy artifact that legitimately materializes no selected units.
210
+ // Coverage is a completeness claim, so a failed inventory cannot be used
211
+ // to derive missing acknowledgements or an empty-population diagnostic.
212
+ LoadFailed bool
213
+ // FailureBase is set only on a synthetic health marker for a population
214
+ // whose root or walk could not be inspected completely. The marker never
215
+ // participates in glob matching; it carries loader health across the same
216
+ // immutable inventory boundary as the artifacts the loader did reach.
217
+ FailureBase string
218
+ // Imports indexes the local names a TypeScript module brings into scope, so
219
+ // an inline-link target can be resolved the way TypeScript resolves a name:
220
+ // from the citing file's own bindings rather than from a global table.
221
+ Imports map[string]importBinding
222
+ // Exports is the module's public surface as importers see it, which is what
223
+ // an entry traversal follows. It records reachability only; a re-export
224
+ // still creates no unit of its own.
225
+ Exports []moduleExport
226
+ // UnitNodes maps a unit ID to every declaration node that spells it.
227
+ //
228
+ // A unit is an identity, not a declaration: declaration merging and overload
229
+ // sets give one identity several nodes. Which of them a rule then cares
230
+ // about is the rule's own business — this records only that they belong to
231
+ // one identity. The graph scanner uses the association transiently to bind a
232
+ // physical JSDoc declaration to semantic claim-host identities, then releases
233
+ // it; callers with no such use leave it nil.
234
+ UnitNodes map[string][]*shimast.Node
235
+ }
236
+
237
+ func (inventory *artifactInventory) recordUnitNode(id string, node *shimast.Node) {
238
+ if inventory == nil || inventory.UnitNodes == nil || node == nil {
239
+ return
240
+ }
241
+ inventory.UnitNodes[id] = append(inventory.UnitNodes[id], node)
242
+ }
243
+
244
+ type inventoryProblem struct {
245
+ Symbol string
246
+ Message string
247
+ }
248
+
249
+ type claimState struct {
250
+ Spec claimSpec
251
+ Paths []string
252
+ Hosts []*evidenceUnit
253
+ Declarations []*evidenceDeclaration
254
+ References []referenceState
255
+ Healthy bool
256
+ // OutsideCarrier names declarations this claim selected from a file its
257
+ // ExclusionCarriers does not match. Only exclusions are judged by it, and
258
+ // it stays empty when the claim declares no carrier.
259
+ OutsideCarrier map[string]bool
260
+ }
261
+
262
+ type referenceState struct {
263
+ Spec referenceSpec
264
+ Paths []string
265
+ Units []*evidenceUnit
266
+ Scopes []*evidenceUnit
267
+ // Published names the module-and-address pairs a citation may use, for a
268
+ // population selected by walking module exports. Left empty when the
269
+ // population's addresses belong to the files that declare them.
270
+ Published []publishedAddress
271
+ // Hidden are the units this reference would have selected had their
272
+ // declarations not withdrawn themselves from the public surface. They carry
273
+ // no obligation; they exist so a citation of one names its cause.
274
+ Hidden []*evidenceUnit
275
+ UnitsByScope map[string][]*evidenceUnit
276
+ Healthy bool
277
+ }
278
+
279
+ func decimal(value int) string {
280
+ if value == 0 {
281
+ return "0"
282
+ }
283
+ negative := value < 0
284
+ if negative {
285
+ value = -value
286
+ }
287
+ digits := make([]byte, 0, 12)
288
+ for value > 0 {
289
+ digits = append([]byte{byte('0' + value%10)}, digits...)
290
+ value /= 10
291
+ }
292
+ if negative {
293
+ return "-" + string(digits)
294
+ }
295
+ return string(digits)
296
+ }