@saptools/service-flow 0.1.69 → 0.1.72

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 (144) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +9 -5
  3. package/TECHNICAL-NOTE.md +17 -0
  4. package/dist/{chunk-3N3B5KHV.js → chunk-Z6D433R5.js} +8766 -6546
  5. package/dist/chunk-Z6D433R5.js.map +1 -0
  6. package/dist/cli.js +703 -160
  7. package/dist/cli.js.map +1 -1
  8. package/dist/index.d.ts +53 -14
  9. package/dist/index.js +2 -23
  10. package/dist/index.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/cli/doctor-event-quality.ts +371 -0
  13. package/src/cli/{002-doctor-lifecycle.ts → doctor-lifecycle.ts} +1 -1
  14. package/src/cli/{001-doctor-projection.ts → doctor-projection.ts} +1 -1
  15. package/src/cli/doctor.ts +9 -11
  16. package/src/cli.ts +6 -6
  17. package/src/db/{009-binding-fact-semantics.ts → binding-fact-semantics.ts} +2 -2
  18. package/src/db/{000-call-fact-repository.ts → call-fact-repository.ts} +12 -9
  19. package/src/db/{003-current-fact-semantics.ts → current-fact-semantics.ts} +8 -8
  20. package/src/db/event-fact-semantics.ts +347 -0
  21. package/src/db/event-surface-invalidation.ts +38 -0
  22. package/src/db/{002-fact-json-inventory.ts → fact-json-inventory.ts} +16 -0
  23. package/src/db/{001-fact-lifecycle.ts → fact-lifecycle.ts} +3 -3
  24. package/src/db/migrations.ts +12 -1
  25. package/src/db/{007-package-fact-semantics.ts → package-fact-semantics.ts} +6 -6
  26. package/src/db/{010-package-symbol-surface-semantics.ts → package-symbol-surface-semantics.ts} +2 -2
  27. package/src/db/{004-package-target-invalidation.ts → package-target-invalidation.ts} +80 -1
  28. package/src/db/{008-relative-fact-semantics.ts → relative-fact-semantics.ts} +3 -3
  29. package/src/db/{006-relative-symbol-resolution.ts → relative-symbol-resolution.ts} +1 -1
  30. package/src/db/repositories.ts +31 -5
  31. package/src/db/{005-schema-structure.ts → schema-structure.ts} +41 -1
  32. package/src/db/schema.ts +6 -2
  33. package/src/db/{011-symbol-call-semantics.ts → symbol-call-semantics.ts} +1 -1
  34. package/src/index.ts +3 -3
  35. package/src/indexer/repository-indexer.ts +50 -11
  36. package/src/indexer/workspace-indexer.ts +3 -3
  37. package/src/linker/{007-call-edge-insertion.ts → call-edge-insertion.ts} +2 -2
  38. package/src/linker/{002-call-evidence.ts → call-evidence.ts} +2 -2
  39. package/src/linker/cross-repo-linker.ts +30 -8
  40. package/src/linker/dynamic-edge-resolver.ts +1 -1
  41. package/src/linker/event-environment-link.ts +211 -0
  42. package/src/linker/event-shape-candidate-linker.ts +161 -0
  43. package/src/linker/{004-event-subscription-handler-linker.ts → event-subscription-handler-linker.ts} +124 -20
  44. package/src/linker/{006-event-template-link.ts → event-template-link.ts} +40 -6
  45. package/src/linker/external-http-target.ts +1 -1
  46. package/src/linker/helper-package-linker.ts +1 -1
  47. package/src/linker/{000-implementation-candidates.ts → implementation-candidates.ts} +1 -1
  48. package/src/linker/{001-implementation-evidence-projection.ts → implementation-evidence-projection.ts} +1 -1
  49. package/src/linker/odata-path-normalizer.ts +1 -1
  50. package/src/linker/{005-odata-path-structure.ts → odata-path-structure.ts} +1 -1
  51. package/src/linker/package-event-constant-resolver.ts +298 -0
  52. package/src/linker/{003-package-import-symbol-resolver.ts → package-import-symbol-resolver.ts} +3 -3
  53. package/src/linker/service-resolver.ts +2 -2
  54. package/src/output/{001-compact-json-output.ts → compact-json-output.ts} +1 -1
  55. package/src/output/table-output.ts +13 -1
  56. package/src/parsers/{006-binding-identity.ts → binding-identity.ts} +3 -3
  57. package/src/parsers/{011-binding-lexical-scope.ts → binding-lexical-scope.ts} +1 -1
  58. package/src/parsers/{021-binding-visibility.ts → binding-visibility.ts} +1 -1
  59. package/src/parsers/decorator-parser.ts +9 -53
  60. package/src/parsers/environment-declarations.ts +327 -0
  61. package/src/parsers/event-call-analysis.ts +242 -0
  62. package/src/parsers/event-environment-reference.ts +231 -0
  63. package/src/parsers/event-loop-registration.ts +132 -0
  64. package/src/parsers/event-name-import-resolution.ts +243 -0
  65. package/src/parsers/event-receiver-analysis.ts +404 -0
  66. package/src/parsers/{005-event-subscription-facts.ts → event-subscription-facts.ts} +6 -2
  67. package/src/parsers/generated-constants-parser.ts +80 -14
  68. package/src/parsers/{016-local-symbol-reference.ts → local-symbol-reference.ts} +2 -2
  69. package/src/parsers/operation-path-analysis.ts +1 -1
  70. package/src/parsers/{023-outbound-call-classifier.ts → outbound-call-classifier.ts} +30 -127
  71. package/src/parsers/outbound-call-parser.ts +15 -3
  72. package/src/parsers/{022-outbound-expression-analysis.ts → outbound-expression-analysis.ts} +4 -4
  73. package/src/parsers/{018-package-commonjs-syntax.ts → package-commonjs-syntax.ts} +1 -1
  74. package/src/parsers/{012-package-fact-contract.ts → package-fact-contract.ts} +3 -3
  75. package/src/parsers/{010-package-public-surface-analysis.ts → package-public-surface-analysis.ts} +2 -2
  76. package/src/parsers/{003-package-public-surface.ts → package-public-surface.ts} +3 -3
  77. package/src/parsers/{008-package-surface-publication.ts → package-surface-publication.ts} +1 -1
  78. package/src/parsers/{001-query-entity-resolution.ts → query-entity-resolution.ts} +1 -1
  79. package/src/parsers/{015-service-binding-collector.ts → service-binding-collector.ts} +3 -3
  80. package/src/parsers/{014-service-binding-helper-flow.ts → service-binding-helper-flow.ts} +2 -2
  81. package/src/parsers/service-binding-parser-helpers.ts +1 -1
  82. package/src/parsers/service-binding-parser.ts +2 -2
  83. package/src/parsers/{007-source-fact-reconciliation.ts → source-fact-reconciliation.ts} +3 -3
  84. package/src/parsers/{020-stable-local-value.ts → stable-local-value.ts} +32 -11
  85. package/src/parsers/string-constant-lookups.ts +358 -0
  86. package/src/parsers/{009-symbol-call-facts.ts → symbol-call-facts.ts} +3 -3
  87. package/src/parsers/{017-symbol-derived-contexts.ts → symbol-derived-contexts.ts} +2 -2
  88. package/src/parsers/symbol-parser.ts +6 -6
  89. package/src/trace/{021-compact-decision-normalization.ts → compact-decision-normalization.ts} +2 -2
  90. package/src/trace/{020-compact-field-projection.ts → compact-field-projection.ts} +3 -3
  91. package/src/trace/{024-compact-observation-decision.ts → compact-observation-decision.ts} +3 -3
  92. package/src/trace/{016-compact-projector.ts → compact-projector.ts} +4 -4
  93. package/src/trace/{018-compact-trace.ts → compact-trace.ts} +3 -3
  94. package/src/trace/{006-contextual-projection.ts → contextual-projection.ts} +1 -1
  95. package/src/trace/{008-contextual-runtime-state.ts → contextual-runtime-state.ts} +1 -1
  96. package/src/trace/{001-dynamic-identity.ts → dynamic-identity.ts} +2 -2
  97. package/src/trace/{003-dynamic-references.ts → dynamic-references.ts} +2 -2
  98. package/src/trace/dynamic-targets.ts +6 -6
  99. package/src/trace/{030-event-runtime-resolution.ts → event-runtime-resolution.ts} +26 -5
  100. package/src/trace/event-shape-candidate-trace.ts +172 -0
  101. package/src/trace/{011-event-subscriber-traversal.ts → event-subscriber-traversal.ts} +20 -8
  102. package/src/trace/evidence.ts +9 -2
  103. package/src/trace/implementation-hints.ts +2 -2
  104. package/src/trace/{005-implementation-selection.ts → implementation-selection.ts} +2 -2
  105. package/src/trace/{031-local-call-expansion.ts → local-call-expansion.ts} +3 -3
  106. package/src/trace/{009-selected-handler-provenance.ts → selected-handler-provenance.ts} +1 -1
  107. package/src/trace/selectors.ts +1 -1
  108. package/src/trace/{017-trace-context.ts → trace-context.ts} +2 -2
  109. package/src/trace/{015-trace-edge-recorder.ts → trace-edge-recorder.ts} +2 -2
  110. package/src/trace/{019-trace-edge-semantics.ts → trace-edge-semantics.ts} +3 -3
  111. package/src/trace/trace-engine.ts +10 -10
  112. package/src/trace/{022-trace-fact-preflight.ts → trace-fact-preflight.ts} +2 -2
  113. package/src/trace/{025-trace-implementation-scope.ts → trace-implementation-scope.ts} +1 -1
  114. package/src/trace/{028-trace-operation-execution.ts → trace-operation-execution.ts} +10 -10
  115. package/src/trace/{013-trace-root-scopes.ts → trace-root-scopes.ts} +3 -3
  116. package/src/trace/{027-trace-scope-execution.ts → trace-scope-execution.ts} +35 -43
  117. package/src/trace/{029-trace-start-implementation.ts → trace-start-implementation.ts} +7 -7
  118. package/src/trace/{026-trace-start-scope.ts → trace-start-scope.ts} +5 -5
  119. package/src/trace/{010-traversal-scope.ts → traversal-scope.ts} +1 -1
  120. package/src/types.ts +17 -1
  121. package/src/utils/event-skeleton.ts +207 -0
  122. package/src/version.ts +1 -1
  123. package/dist/chunk-3N3B5KHV.js.map +0 -1
  124. /package/src/cli/{000-clean.ts → clean.ts} +0 -0
  125. /package/src/cli/{003-doctor-package-resolution.ts → doctor-package-resolution.ts} +0 -0
  126. /package/src/cli/{001-index-summary.ts → index-summary.ts} +0 -0
  127. /package/src/db/{014-binding-helper-provenance.ts → binding-helper-provenance.ts} +0 -0
  128. /package/src/db/{012-binding-reference-proof.ts → binding-reference-proof.ts} +0 -0
  129. /package/src/db/{013-index-publication-failure.ts → index-publication-failure.ts} +0 -0
  130. /package/src/output/{000-stdout-policy.ts → stdout-policy.ts} +0 -0
  131. /package/src/parsers/{019-binding-assignment-targets.ts → binding-assignment-targets.ts} +0 -0
  132. /package/src/parsers/{000-direct-query-execution.ts → direct-query-execution.ts} +0 -0
  133. /package/src/parsers/{013-executable-body-eligibility.ts → executable-body-eligibility.ts} +0 -0
  134. /package/src/parsers/{004-fact-identity.ts → fact-identity.ts} +0 -0
  135. /package/src/parsers/{002-symbol-import-bindings.ts → symbol-import-bindings.ts} +0 -0
  136. /package/src/trace/{014-compact-contract.ts → compact-contract.ts} +0 -0
  137. /package/src/trace/{004-dynamic-candidate-sources.ts → dynamic-candidate-sources.ts} +0 -0
  138. /package/src/trace/{000-dynamic-target-types.ts → dynamic-target-types.ts} +0 -0
  139. /package/src/trace/{007-implementation-start-diagnostic.ts → implementation-start-diagnostic.ts} +0 -0
  140. /package/src/trace/{023-nested-event-scopes.ts → nested-event-scopes.ts} +0 -0
  141. /package/src/trace/{002-trace-diagnostics.ts → trace-diagnostics.ts} +0 -0
  142. /package/src/trace/{012-trace-graph-lookups.ts → trace-graph-lookups.ts} +0 -0
  143. /package/src/utils/{000-bounded-projection.ts → bounded-projection.ts} +0 -0
  144. /package/src/utils/{001-placeholders.ts → placeholders.ts} +0 -0
@@ -1,22 +1,22 @@
1
1
  import type { Db } from '../db/connection.js';
2
2
  import type { TraceEdge } from '../types.js';
3
- import { hintedImplementationSelection } from './005-implementation-selection.js';
3
+ import { hintedImplementationSelection } from './implementation-selection.js';
4
4
  import {
5
5
  handlerMethodNode,
6
6
  withSelectedHandlerProvenance,
7
7
  type SelectedHandlerEvidence,
8
- } from './009-selected-handler-provenance.js';
8
+ } from './selected-handler-provenance.js';
9
9
  import {
10
10
  operationNode,
11
11
  type TraceGraphEdgeRow,
12
- } from './012-trace-graph-lookups.js';
13
- import { parseTraceEvidence } from './017-trace-context.js';
14
- import { recordImplementationObservation } from './019-trace-edge-semantics.js';
12
+ } from './trace-graph-lookups.js';
13
+ import { parseTraceEvidence } from './trace-context.js';
14
+ import { recordImplementationObservation } from './trace-edge-semantics.js';
15
15
  import {
16
16
  handlerScope,
17
17
  implementationScope,
18
- } from './025-trace-implementation-scope.js';
19
- import type { TraceExecutionRuntime } from './027-trace-scope-execution.js';
18
+ } from './trace-implementation-scope.js';
19
+ import type { TraceExecutionRuntime } from './trace-scope-execution.js';
20
20
 
21
21
  interface StartImplementationSelection {
22
22
  edge: TraceGraphEdgeRow;
@@ -1,15 +1,15 @@
1
1
  import type { Db } from '../db/connection.js';
2
2
  import type { TraceStart } from '../types.js';
3
3
  import { implementationHintDiagnostic } from './implementation-hints.js';
4
- import { hintedImplementationSelection } from './005-implementation-selection.js';
5
- import { implementationStartDiagnostic } from './007-implementation-start-diagnostic.js';
6
- import { parseTraceEvidence } from './017-trace-context.js';
7
- import { shouldDeferTraceStartSelection } from './022-trace-fact-preflight.js';
4
+ import { hintedImplementationSelection } from './implementation-selection.js';
5
+ import { implementationStartDiagnostic } from './implementation-start-diagnostic.js';
6
+ import { parseTraceEvidence } from './trace-context.js';
7
+ import { shouldDeferTraceStartSelection } from './trace-fact-preflight.js';
8
8
  import {
9
9
  handlerScope,
10
10
  implementationScope,
11
11
  type ImplementationHintOptions,
12
- } from './025-trace-implementation-scope.js';
12
+ } from './trace-implementation-scope.js';
13
13
  import {
14
14
  ambiguousStartDiagnostic,
15
15
  selectorRepoAmbiguousDiagnostic,
@@ -1,6 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import type { Db } from '../db/connection.js';
3
- import type { ContextBinding } from './008-contextual-runtime-state.js';
3
+ import type { ContextBinding } from './contextual-runtime-state.js';
4
4
 
5
5
  export interface TraversalScopeIdentity {
6
6
  workspaceId?: number;
package/src/types.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import type { EventSkeletonFact } from './utils/event-skeleton.js';
2
+
1
3
  export type RepoKind =
2
4
  | 'cap-service'
3
5
  | 'cap-db-model'
@@ -36,6 +38,7 @@ export type EdgeType =
36
38
  | 'HANDLER_EMITS_EVENT'
37
39
  | 'EVENT_CONSUMED_BY_HANDLER'
38
40
  | 'EVENT_SUBSCRIPTION_HANDLED_BY'
41
+ | 'EVENT_SHAPE_CANDIDATE_SUBSCRIBER'
39
42
  | 'REPO_IMPORTS_HELPER_PACKAGE'
40
43
  | 'HELPER_PACKAGE_PROVIDES_HANDLER'
41
44
  | 'DYNAMIC_EDGE_CANDIDATE'
@@ -229,6 +232,7 @@ export interface OutboundCallFact {
229
232
  operationPathExpr?: string;
230
233
  queryEntity?: string;
231
234
  eventNameExpr?: string;
235
+ eventSkeleton?: EventSkeletonFact;
232
236
  payloadSummary?: string;
233
237
  sourceFile: string;
234
238
  sourceLine: number;
@@ -272,9 +276,21 @@ export interface SymbolCallFact {
272
276
  }
273
277
  export interface GeneratedConstantFact {
274
278
  name: string;
275
- value: string;
279
+ value?: string;
276
280
  sourceFile: string;
277
281
  sourceLine: number;
282
+ containerName?: string;
283
+ memberName?: string;
284
+ constantKind: 'const_identifier' | 'enum_member' | 'const_object_property';
285
+ exported: boolean;
286
+ stable: boolean;
287
+ resolutionStatus: 'resolved' | 'refused';
288
+ unresolvedReason?: 'event_name_constant_member_not_string'
289
+ | 'event_name_constant_container_mutable';
290
+ declarationStartOffset: number;
291
+ declarationEndOffset: number;
292
+ valueStartOffset: number;
293
+ valueEndOffset: number;
278
294
  }
279
295
  export interface TraceStart {
280
296
  repo?: string;
@@ -0,0 +1,207 @@
1
+ import { sha256Text } from './hashing.js';
2
+ import { scanPlaceholderStructure } from './placeholders.js';
3
+ import type {
4
+ EventEnvironmentReference,
5
+ } from '../parsers/event-environment-reference.js';
6
+
7
+ export const EVENT_SKELETON_SCHEMA = 'service-flow/event-skeleton@1';
8
+ export const EVENT_SKELETON_LITERAL_THRESHOLD = 8;
9
+ export const EVENT_SKELETON_TEXT_LIMIT = 512;
10
+
11
+ export interface EventSkeletonFact {
12
+ schema: typeof EVENT_SKELETON_SCHEMA;
13
+ status: 'complete' | 'malformed' | 'too_large';
14
+ signature: string | null;
15
+ literalSpans: string[];
16
+ holeCount: number;
17
+ sourceKeys: string[];
18
+ canonicalKeys: string[];
19
+ candidateEligible: boolean;
20
+ environmentBindings: EventEnvironmentReference[];
21
+ reason?: string;
22
+ }
23
+
24
+ function record(value: unknown): Record<string, unknown> | undefined {
25
+ return value && typeof value === 'object' && !Array.isArray(value)
26
+ ? value as Record<string, unknown> : undefined;
27
+ }
28
+
29
+ function parseJson(value: unknown): unknown {
30
+ if (typeof value !== 'string') return value;
31
+ try {
32
+ return JSON.parse(value) as unknown;
33
+ } catch {
34
+ return undefined;
35
+ }
36
+ }
37
+
38
+ function stringArray(value: unknown): string[] | undefined {
39
+ return Array.isArray(value) && value.every((item) =>
40
+ typeof item === 'string')
41
+ ? value as string[] : undefined;
42
+ }
43
+
44
+ function canonicalKey(signature: string, index: number): string {
45
+ return `event.${signature.slice(0, 16)}.hole${index + 1}`;
46
+ }
47
+
48
+ function skeletonSignature(
49
+ literalSpans: readonly string[],
50
+ holeCount: number,
51
+ ): string {
52
+ return sha256Text(JSON.stringify({ literalSpans, holeCount }));
53
+ }
54
+
55
+ function completeSkeleton(
56
+ template: string,
57
+ ): EventSkeletonFact {
58
+ const scan = scanPlaceholderStructure(template);
59
+ if (scan.status === 'malformed') return {
60
+ schema: EVENT_SKELETON_SCHEMA,
61
+ status: 'malformed',
62
+ signature: null,
63
+ literalSpans: [],
64
+ holeCount: 0,
65
+ sourceKeys: [],
66
+ canonicalKeys: [],
67
+ candidateEligible: false,
68
+ environmentBindings: [],
69
+ reason: scan.reason,
70
+ };
71
+ const literals: string[] = [];
72
+ let cursor = 0;
73
+ for (const span of scan.spans) {
74
+ literals.push(template.slice(cursor, span.start));
75
+ cursor = span.end;
76
+ }
77
+ literals.push(template.slice(cursor));
78
+ const signature = skeletonSignature(literals, scan.spans.length);
79
+ return {
80
+ schema: EVENT_SKELETON_SCHEMA,
81
+ status: 'complete',
82
+ signature,
83
+ literalSpans: literals,
84
+ holeCount: scan.spans.length,
85
+ sourceKeys: scan.spans.map((span) => span.key.trim()),
86
+ canonicalKeys: scan.spans.map((_, index) =>
87
+ canonicalKey(signature, index)),
88
+ candidateEligible: scan.spans.length > 0
89
+ && literals.some((literal) =>
90
+ literal.length >= EVENT_SKELETON_LITERAL_THRESHOLD),
91
+ environmentBindings: [],
92
+ };
93
+ }
94
+
95
+ function validCompleteSkeleton(
96
+ item: Record<string, unknown>,
97
+ literals: string[],
98
+ sourceKeys: string[],
99
+ canonicalKeys: string[],
100
+ ): boolean {
101
+ const holes = item.holeCount;
102
+ const signature = item.signature;
103
+ if (!Number.isInteger(holes) || Number(holes) < 1
104
+ || typeof signature !== 'string'
105
+ || !/^[a-f0-9]{64}$/.test(signature)) return false;
106
+ const count = Number(holes);
107
+ return literals.length === count + 1
108
+ && sourceKeys.length === count
109
+ && canonicalKeys.length === count
110
+ && sourceKeys.every((key) => key.length > 0 && key === key.trim())
111
+ && canonicalKeys.every((key, index) =>
112
+ key === canonicalKey(signature, index))
113
+ && new Set(canonicalKeys).size === canonicalKeys.length
114
+ && signature === skeletonSignature(literals, count)
115
+ && item.candidateEligible === literals.some((literal) =>
116
+ literal.length >= EVENT_SKELETON_LITERAL_THRESHOLD)
117
+ && item.reason === undefined;
118
+ }
119
+
120
+ function validClosedSkeleton(
121
+ item: Record<string, unknown>,
122
+ literals: string[],
123
+ sourceKeys: string[],
124
+ canonicalKeys: string[],
125
+ ): boolean {
126
+ const reason = item.reason;
127
+ if (item.signature !== null || item.holeCount !== 0
128
+ || item.candidateEligible !== false
129
+ || literals.length > 0 || sourceKeys.length > 0
130
+ || canonicalKeys.length > 0
131
+ || !Array.isArray(item.environmentBindings)
132
+ || item.environmentBindings.length > 0) return false;
133
+ if (item.status === 'too_large')
134
+ return reason === 'event_skeleton_text_limit_exceeded';
135
+ return item.status === 'malformed'
136
+ && typeof reason === 'string' && reason.length > 0;
137
+ }
138
+
139
+ export function parseEventSkeletonFact(
140
+ value: unknown,
141
+ ): EventSkeletonFact | undefined {
142
+ const item = record(parseJson(value));
143
+ if (!item || item.schema !== EVENT_SKELETON_SCHEMA
144
+ || !['complete', 'malformed', 'too_large'].includes(String(item.status))
145
+ || !Array.isArray(item.environmentBindings)) return undefined;
146
+ const literals = stringArray(item.literalSpans);
147
+ const sourceKeys = stringArray(item.sourceKeys);
148
+ const canonicalKeys = stringArray(item.canonicalKeys);
149
+ if (!literals || !sourceKeys || !canonicalKeys) return undefined;
150
+ const valid = item.status === 'complete'
151
+ ? validCompleteSkeleton(item, literals, sourceKeys, canonicalKeys)
152
+ : validClosedSkeleton(item, literals, sourceKeys, canonicalKeys);
153
+ return valid ? item as unknown as EventSkeletonFact : undefined;
154
+ }
155
+
156
+ export function deriveEventSkeleton(
157
+ template: string | undefined,
158
+ ): EventSkeletonFact | undefined {
159
+ if (!template || !template.includes('${')) return undefined;
160
+ if (template.length <= EVENT_SKELETON_TEXT_LIMIT)
161
+ return completeSkeleton(template);
162
+ return {
163
+ schema: EVENT_SKELETON_SCHEMA,
164
+ status: 'too_large',
165
+ signature: null,
166
+ literalSpans: [],
167
+ holeCount: 0,
168
+ sourceKeys: [],
169
+ canonicalKeys: [],
170
+ candidateEligible: false,
171
+ environmentBindings: [],
172
+ reason: 'event_skeleton_text_limit_exceeded',
173
+ };
174
+ }
175
+
176
+ export function eventTemplateVariables(
177
+ skeleton: EventSkeletonFact | undefined,
178
+ variables: Record<string, string>,
179
+ ): Record<string, string> {
180
+ if (!skeleton || skeleton.status !== 'complete') return variables;
181
+ const expanded = { ...variables };
182
+ for (let index = 0; index < skeleton.sourceKeys.length; index += 1) {
183
+ const sourceKey = skeleton.sourceKeys[index];
184
+ const canonicalKeyValue = skeleton.canonicalKeys[index];
185
+ if (!sourceKey || !canonicalKeyValue
186
+ || Object.hasOwn(expanded, sourceKey)
187
+ || !Object.hasOwn(expanded, canonicalKeyValue)) continue;
188
+ expanded[sourceKey] = expanded[canonicalKeyValue] ?? '';
189
+ }
190
+ return expanded;
191
+ }
192
+
193
+ export function eventMissingVariableNames(
194
+ skeleton: EventSkeletonFact | undefined,
195
+ missingSourceKeys: readonly string[],
196
+ ): string[] {
197
+ const names = new Set(missingSourceKeys);
198
+ if (skeleton?.status === 'complete')
199
+ for (let index = 0; index < skeleton.sourceKeys.length; index += 1) {
200
+ const sourceKey = skeleton.sourceKeys[index];
201
+ const canonical = skeleton.canonicalKeys[index];
202
+ if (sourceKey && canonical && names.has(sourceKey))
203
+ names.add(canonical);
204
+ }
205
+ return [...names].sort((left, right) =>
206
+ left < right ? -1 : left > right ? 1 : 0);
207
+ }
package/src/version.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import packageJson from '../package.json' with { type: 'json' };
2
2
 
3
3
  export const VERSION = packageJson.version;
4
- export const ANALYZER_VERSION = '0.1.69-facts.1';
4
+ export const ANALYZER_VERSION = '0.1.71-facts.1';