@veraxhq/verax 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -20
- package/bin/verax.js +11 -18
- package/package.json +28 -7
- package/src/cli/commands/baseline.js +1 -2
- package/src/cli/commands/default.js +72 -81
- package/src/cli/commands/doctor.js +29 -0
- package/src/cli/commands/ga.js +3 -0
- package/src/cli/commands/gates.js +1 -1
- package/src/cli/commands/inspect.js +6 -133
- package/src/cli/commands/release-check.js +2 -0
- package/src/cli/commands/run.js +74 -246
- package/src/cli/commands/security-check.js +2 -1
- package/src/cli/commands/truth.js +0 -1
- package/src/cli/entry.js +82 -309
- package/src/cli/util/angular-component-extractor.js +2 -2
- package/src/cli/util/angular-navigation-detector.js +2 -2
- package/src/cli/util/ast-interactive-detector.js +4 -6
- package/src/cli/util/ast-network-detector.js +3 -3
- package/src/cli/util/ast-promise-extractor.js +581 -0
- package/src/cli/util/ast-usestate-detector.js +3 -3
- package/src/cli/util/atomic-write.js +12 -1
- package/src/cli/util/console-reporter.js +72 -0
- package/src/cli/util/detection-engine.js +105 -41
- package/src/cli/util/determinism-runner.js +2 -1
- package/src/cli/util/determinism-writer.js +1 -1
- package/src/cli/util/digest-engine.js +359 -0
- package/src/cli/util/dom-diff.js +226 -0
- package/src/cli/util/env-url.js +0 -4
- package/src/cli/util/evidence-engine.js +287 -0
- package/src/cli/util/expectation-extractor.js +217 -367
- package/src/cli/util/findings-writer.js +19 -126
- package/src/cli/util/framework-detector.js +572 -0
- package/src/cli/util/idgen.js +1 -1
- package/src/cli/util/interaction-planner.js +529 -0
- package/src/cli/util/learn-writer.js +2 -2
- package/src/cli/util/ledger-writer.js +110 -0
- package/src/cli/util/monorepo-resolver.js +162 -0
- package/src/cli/util/observation-engine.js +127 -278
- package/src/cli/util/observe-writer.js +2 -2
- package/src/cli/util/paths.js +12 -3
- package/src/cli/util/project-discovery.js +284 -3
- package/src/cli/util/project-writer.js +2 -2
- package/src/cli/util/run-id.js +23 -27
- package/src/cli/util/run-result.js +778 -0
- package/src/cli/util/selector-resolver.js +235 -0
- package/src/cli/util/summary-writer.js +2 -1
- package/src/cli/util/svelte-navigation-detector.js +3 -3
- package/src/cli/util/svelte-sfc-extractor.js +0 -1
- package/src/cli/util/svelte-state-detector.js +1 -2
- package/src/cli/util/trust-activation-integration.js +496 -0
- package/src/cli/util/trust-activation-wrapper.js +85 -0
- package/src/cli/util/trust-integration-hooks.js +164 -0
- package/src/cli/util/types.js +153 -0
- package/src/cli/util/url-validation.js +40 -0
- package/src/cli/util/vue-navigation-detector.js +4 -3
- package/src/cli/util/vue-sfc-extractor.js +1 -2
- package/src/cli/util/vue-state-detector.js +1 -1
- package/src/types/fs-augment.d.ts +23 -0
- package/src/types/global.d.ts +137 -0
- package/src/types/internal-types.d.ts +35 -0
- package/src/verax/cli/finding-explainer.js +3 -56
- package/src/verax/cli/init.js +4 -18
- package/src/verax/core/action-classifier.js +4 -3
- package/src/verax/core/artifacts/registry.js +0 -15
- package/src/verax/core/artifacts/verifier.js +18 -8
- package/src/verax/core/baseline/baseline.snapshot.js +2 -0
- package/src/verax/core/capabilities/gates.js +7 -1
- package/src/verax/core/confidence/confidence-compute.js +14 -7
- package/src/verax/core/confidence/confidence.loader.js +1 -0
- package/src/verax/core/confidence-engine-refactor.js +8 -3
- package/src/verax/core/confidence-engine.js +162 -23
- package/src/verax/core/contracts/types.js +1 -0
- package/src/verax/core/contracts/validators.js +79 -4
- package/src/verax/core/decision-snapshot.js +3 -30
- package/src/verax/core/decisions/decision.trace.js +2 -0
- package/src/verax/core/determinism/contract-writer.js +2 -2
- package/src/verax/core/determinism/contract.js +1 -1
- package/src/verax/core/determinism/diff.js +42 -1
- package/src/verax/core/determinism/engine.js +7 -6
- package/src/verax/core/determinism/finding-identity.js +3 -2
- package/src/verax/core/determinism/normalize.js +32 -4
- package/src/verax/core/determinism/report-writer.js +1 -0
- package/src/verax/core/determinism/run-fingerprint.js +7 -2
- package/src/verax/core/dynamic-route-intelligence.js +8 -7
- package/src/verax/core/evidence/evidence-capture-service.js +1 -0
- package/src/verax/core/evidence/evidence-intent-ledger.js +2 -1
- package/src/verax/core/evidence-builder.js +2 -2
- package/src/verax/core/execution-mode-context.js +1 -1
- package/src/verax/core/execution-mode-detector.js +5 -3
- package/src/verax/core/failures/exit-codes.js +39 -37
- package/src/verax/core/failures/failure-summary.js +1 -1
- package/src/verax/core/failures/failure.factory.js +3 -3
- package/src/verax/core/failures/failure.ledger.js +3 -2
- package/src/verax/core/ga/ga.artifact.js +1 -1
- package/src/verax/core/ga/ga.contract.js +3 -2
- package/src/verax/core/ga/ga.enforcer.js +1 -0
- package/src/verax/core/guardrails/policy.loader.js +1 -0
- package/src/verax/core/guardrails/truth-reconciliation.js +1 -1
- package/src/verax/core/guardrails-engine.js +2 -2
- package/src/verax/core/incremental-store.js +1 -0
- package/src/verax/core/integrity/budget.js +138 -0
- package/src/verax/core/integrity/determinism.js +342 -0
- package/src/verax/core/integrity/integrity.js +208 -0
- package/src/verax/core/integrity/poisoning.js +108 -0
- package/src/verax/core/integrity/transaction.js +140 -0
- package/src/verax/core/observe/run-timeline.js +2 -0
- package/src/verax/core/perf/perf.report.js +2 -0
- package/src/verax/core/pipeline-tracker.js +5 -0
- package/src/verax/core/release/provenance.builder.js +73 -214
- package/src/verax/core/release/release.enforcer.js +14 -9
- package/src/verax/core/release/reproducibility.check.js +1 -0
- package/src/verax/core/release/sbom.builder.js +32 -23
- package/src/verax/core/replay-validator.js +2 -0
- package/src/verax/core/replay.js +4 -0
- package/src/verax/core/report/cross-index.js +6 -3
- package/src/verax/core/report/human-summary.js +141 -1
- package/src/verax/core/route-intelligence.js +4 -3
- package/src/verax/core/run-id.js +6 -3
- package/src/verax/core/run-manifest.js +4 -3
- package/src/verax/core/security/secrets.scan.js +10 -7
- package/src/verax/core/security/security.enforcer.js +4 -0
- package/src/verax/core/security/supplychain.policy.js +9 -1
- package/src/verax/core/security/vuln.scan.js +2 -2
- package/src/verax/core/truth/truth.certificate.js +3 -1
- package/src/verax/core/ui-feedback-intelligence.js +12 -46
- package/src/verax/detect/conditional-ui-silent-failure.js +84 -0
- package/src/verax/detect/confidence-engine.js +100 -660
- package/src/verax/detect/confidence-helper.js +1 -0
- package/src/verax/detect/detection-engine.js +1 -18
- package/src/verax/detect/dynamic-route-findings.js +17 -14
- package/src/verax/detect/expectation-chain-detector.js +1 -1
- package/src/verax/detect/expectation-model.js +3 -5
- package/src/verax/detect/failure-cause-inference.js +293 -0
- package/src/verax/detect/findings-writer.js +126 -166
- package/src/verax/detect/flow-detector.js +2 -2
- package/src/verax/detect/form-silent-failure.js +98 -0
- package/src/verax/detect/index.js +51 -234
- package/src/verax/detect/invariants-enforcer.js +147 -0
- package/src/verax/detect/journey-stall-detector.js +4 -4
- package/src/verax/detect/navigation-silent-failure.js +82 -0
- package/src/verax/detect/problem-aggregator.js +361 -0
- package/src/verax/detect/route-findings.js +7 -6
- package/src/verax/detect/summary-writer.js +477 -0
- package/src/verax/detect/test-failure-cause-inference.js +314 -0
- package/src/verax/detect/ui-feedback-findings.js +18 -18
- package/src/verax/detect/verdict-engine.js +3 -57
- package/src/verax/detect/view-switch-correlator.js +2 -2
- package/src/verax/flow/flow-engine.js +2 -1
- package/src/verax/flow/flow-spec.js +0 -6
- package/src/verax/index.js +48 -412
- package/src/verax/intel/ts-program.js +1 -0
- package/src/verax/intel/vue-navigation-extractor.js +3 -0
- package/src/verax/learn/action-contract-extractor.js +67 -682
- package/src/verax/learn/ast-contract-extractor.js +1 -1
- package/src/verax/learn/flow-extractor.js +1 -0
- package/src/verax/learn/project-detector.js +5 -0
- package/src/verax/learn/react-router-extractor.js +2 -0
- package/src/verax/learn/route-validator.js +1 -4
- package/src/verax/learn/source-instrumenter.js +1 -0
- package/src/verax/learn/state-extractor.js +2 -1
- package/src/verax/learn/static-extractor.js +1 -0
- package/src/verax/observe/coverage-gaps.js +132 -0
- package/src/verax/observe/expectation-handler.js +126 -0
- package/src/verax/observe/incremental-skip.js +46 -0
- package/src/verax/observe/index.js +735 -84
- package/src/verax/observe/interaction-executor.js +192 -0
- package/src/verax/observe/interaction-runner.js +782 -530
- package/src/verax/observe/network-firewall.js +86 -0
- package/src/verax/observe/observation-builder.js +169 -0
- package/src/verax/observe/observe-context.js +1 -1
- package/src/verax/observe/observe-helpers.js +2 -1
- package/src/verax/observe/observe-runner.js +28 -24
- package/src/verax/observe/observers/budget-observer.js +3 -3
- package/src/verax/observe/observers/console-observer.js +4 -4
- package/src/verax/observe/observers/coverage-observer.js +4 -4
- package/src/verax/observe/observers/interaction-observer.js +3 -3
- package/src/verax/observe/observers/navigation-observer.js +4 -4
- package/src/verax/observe/observers/network-observer.js +4 -4
- package/src/verax/observe/observers/safety-observer.js +1 -1
- package/src/verax/observe/observers/ui-feedback-observer.js +4 -4
- package/src/verax/observe/page-traversal.js +138 -0
- package/src/verax/observe/snapshot-ops.js +94 -0
- package/src/verax/observe/ui-signal-sensor.js +2 -148
- package/src/verax/scan-summary-writer.js +10 -42
- package/src/verax/shared/artifact-manager.js +30 -13
- package/src/verax/shared/caching.js +1 -0
- package/src/verax/shared/expectation-tracker.js +1 -0
- package/src/verax/shared/zip-artifacts.js +6 -0
- package/src/verax/core/confidence-engine.js.backup +0 -471
- package/src/verax/shared/config-loader.js +0 -169
- /package/src/verax/shared/{expectation-proof.js → expectation-validation.js} +0 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Selector Resolver
|
|
3
|
+
* Finds and validates selectors for extracted promises
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a selector to an actual element
|
|
8
|
+
* Returns {found: boolean, selector: string, reason?: string}
|
|
9
|
+
*/
|
|
10
|
+
export async function resolveSelector(page, promise) {
|
|
11
|
+
// Try promise.selector first if it exists
|
|
12
|
+
if (promise.selector) {
|
|
13
|
+
const resolved = await trySelectorVariants(page, promise.selector);
|
|
14
|
+
if (resolved.found) {
|
|
15
|
+
return resolved;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Try to derive selector from promise details
|
|
20
|
+
if (promise.category === 'button') {
|
|
21
|
+
return await resolveButtonSelector(page, promise);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (promise.category === 'form') {
|
|
25
|
+
return await resolveFormSelector(page, promise);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (promise.category === 'validation') {
|
|
29
|
+
return await resolveValidationSelector(page, promise);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (promise.type === 'navigation') {
|
|
33
|
+
return await resolveNavigationSelector(page, promise);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
found: false,
|
|
38
|
+
selector: null,
|
|
39
|
+
reason: 'unsupported-promise-type',
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Try multiple selector variants
|
|
45
|
+
*/
|
|
46
|
+
async function trySelectorVariants(page, baseSelector) {
|
|
47
|
+
const variants = [
|
|
48
|
+
baseSelector,
|
|
49
|
+
baseSelector.replace(/button:contains/, 'button:has-text'),
|
|
50
|
+
baseSelector.replace(/"/g, "'"),
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const selector of variants) {
|
|
54
|
+
try {
|
|
55
|
+
const count = await page.locator(selector).count();
|
|
56
|
+
if (count === 1) {
|
|
57
|
+
return { found: true, selector };
|
|
58
|
+
}
|
|
59
|
+
if (count > 1) {
|
|
60
|
+
return { found: false, selector, reason: 'ambiguous-selector' };
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
// Try next variant
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return { found: false, selector: baseSelector, reason: 'not-found' };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Resolve button selector
|
|
72
|
+
*/
|
|
73
|
+
async function resolveButtonSelector(page, promise) {
|
|
74
|
+
// First try the provided selector
|
|
75
|
+
if (promise.selector) {
|
|
76
|
+
const result = await trySelectorVariants(page, promise.selector);
|
|
77
|
+
if (result.found) return result;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Try all button variants
|
|
81
|
+
const selectors = [
|
|
82
|
+
'button[onClick]',
|
|
83
|
+
'button',
|
|
84
|
+
'[role="button"][onClick]',
|
|
85
|
+
'[role="button"]',
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
for (const selector of selectors) {
|
|
89
|
+
try {
|
|
90
|
+
const count = await page.locator(selector).count();
|
|
91
|
+
if (count === 1) {
|
|
92
|
+
return { found: true, selector };
|
|
93
|
+
}
|
|
94
|
+
if (count > 0) {
|
|
95
|
+
// Multiple buttons - try to narrow down by content
|
|
96
|
+
const buttons = await page.locator(selector).all();
|
|
97
|
+
for (const btn of buttons) {
|
|
98
|
+
const text = await btn.textContent();
|
|
99
|
+
if (text && (text.includes('Save') || text.includes('Submit') || text.includes('Click'))) {
|
|
100
|
+
const specific = `${selector}:has-text("${text.trim()}")`;
|
|
101
|
+
const count = await page.locator(specific).count();
|
|
102
|
+
if (count === 1) {
|
|
103
|
+
return { found: true, selector: specific };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} catch (e) {
|
|
109
|
+
// Try next
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return { found: false, selector: null, reason: 'not-found' };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Resolve form selector
|
|
118
|
+
*/
|
|
119
|
+
async function resolveFormSelector(page, promise) {
|
|
120
|
+
if (promise.selector) {
|
|
121
|
+
const result = await trySelectorVariants(page, promise.selector);
|
|
122
|
+
if (result.found) return result;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const selectors = [
|
|
126
|
+
'form[onSubmit]',
|
|
127
|
+
'form',
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
for (const selector of selectors) {
|
|
131
|
+
try {
|
|
132
|
+
const count = await page.locator(selector).count();
|
|
133
|
+
if (count === 1) {
|
|
134
|
+
return { found: true, selector };
|
|
135
|
+
}
|
|
136
|
+
} catch (e) {
|
|
137
|
+
// Try next
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return { found: false, selector: null, reason: 'not-found' };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Resolve validation selector (for required inputs)
|
|
146
|
+
*/
|
|
147
|
+
async function resolveValidationSelector(page, promise) {
|
|
148
|
+
if (promise.selector) {
|
|
149
|
+
const result = await trySelectorVariants(page, promise.selector);
|
|
150
|
+
if (result.found) return result;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Look for required inputs
|
|
154
|
+
const selectors = [
|
|
155
|
+
'input[required]',
|
|
156
|
+
'textarea[required]',
|
|
157
|
+
'select[required]',
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
for (const selector of selectors) {
|
|
161
|
+
try {
|
|
162
|
+
const count = await page.locator(selector).count();
|
|
163
|
+
if (count >= 1) {
|
|
164
|
+
return { found: true, selector };
|
|
165
|
+
}
|
|
166
|
+
} catch (e) {
|
|
167
|
+
// Try next
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return { found: false, selector: null, reason: 'not-found' };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Resolve navigation selector (for anchor tags)
|
|
176
|
+
*/
|
|
177
|
+
async function resolveNavigationSelector(page, promise) {
|
|
178
|
+
const targetPath = promise.promise.value;
|
|
179
|
+
|
|
180
|
+
const selectors = [
|
|
181
|
+
`a[href="${targetPath}"]`,
|
|
182
|
+
`a[href*="${targetPath}"]`,
|
|
183
|
+
];
|
|
184
|
+
|
|
185
|
+
for (const selector of selectors) {
|
|
186
|
+
try {
|
|
187
|
+
const count = await page.locator(selector).count();
|
|
188
|
+
if (count === 1) {
|
|
189
|
+
return { found: true, selector };
|
|
190
|
+
}
|
|
191
|
+
} catch (e) {
|
|
192
|
+
// Try next
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return { found: false, selector: null, reason: 'not-found' };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Find submit button in form
|
|
201
|
+
*/
|
|
202
|
+
export async function findSubmitButton(page, formSelector) {
|
|
203
|
+
try {
|
|
204
|
+
// Look for explicit submit button in form
|
|
205
|
+
const submitBtn = await page.locator(`${formSelector} button[type="submit"]`).first();
|
|
206
|
+
const count = await submitBtn.count();
|
|
207
|
+
if (count > 0) {
|
|
208
|
+
return submitBtn;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Look for any button in form
|
|
212
|
+
const btn = await page.locator(`${formSelector} button`).first();
|
|
213
|
+
if (await btn.count() > 0) {
|
|
214
|
+
return btn;
|
|
215
|
+
}
|
|
216
|
+
} catch (e) {
|
|
217
|
+
// Fall through
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Check if element is clickable/visible
|
|
225
|
+
*/
|
|
226
|
+
export async function isElementInteractable(page, selector) {
|
|
227
|
+
try {
|
|
228
|
+
const element = page.locator(selector).first();
|
|
229
|
+
const isVisible = await element.isVisible();
|
|
230
|
+
const isEnabled = await element.isEnabled();
|
|
231
|
+
return isVisible && isEnabled;
|
|
232
|
+
} catch (e) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { atomicWriteJson } from './atomic-write.js';
|
|
2
|
+
import { ARTIFACT_REGISTRY } from '../../verax/core/artifacts/registry.js';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Write summary.json with deterministic digest
|
|
@@ -7,7 +8,7 @@ import { atomicWriteJson } from './atomic-write.js';
|
|
|
7
8
|
*/
|
|
8
9
|
export function writeSummaryJson(summaryPath, summaryData, stats = {}) {
|
|
9
10
|
const payload = {
|
|
10
|
-
contractVersion:
|
|
11
|
+
contractVersion: ARTIFACT_REGISTRY.summary.contractVersion,
|
|
11
12
|
runId: summaryData.runId,
|
|
12
13
|
status: summaryData.status,
|
|
13
14
|
startedAt: summaryData.startedAt,
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - programmatic navigation
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { extractSvelteSFC, extractTemplateBindings, mapTemplateHandlersToScript } from './svelte-sfc-extractor.js';
|
|
10
|
+
import { extractSvelteSFC, extractTemplateBindings as _extractTemplateBindings, mapTemplateHandlersToScript as _mapTemplateHandlersToScript } from './svelte-sfc-extractor.js';
|
|
11
11
|
import { parse } from '@babel/parser';
|
|
12
12
|
import traverse from '@babel/traverse';
|
|
13
13
|
|
|
@@ -16,10 +16,10 @@ import traverse from '@babel/traverse';
|
|
|
16
16
|
*
|
|
17
17
|
* @param {string} filePath - Path to .svelte file
|
|
18
18
|
* @param {string} content - Full file content
|
|
19
|
-
* @param {string}
|
|
19
|
+
* @param {string} _projectRoot - Project root directory (unused)
|
|
20
20
|
* @returns {Array} Array of navigation expectations
|
|
21
21
|
*/
|
|
22
|
-
export function detectSvelteNavigation(filePath, content,
|
|
22
|
+
export function detectSvelteNavigation(filePath, content, _projectRoot) {
|
|
23
23
|
const expectations = [];
|
|
24
24
|
|
|
25
25
|
try {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* PHASE 20: Extract Svelte SFC blocks
|
|
10
10
|
*
|
|
11
11
|
* @param {string} content - Full .svelte file content
|
|
12
|
-
* @param {string} filePath - Path to the .svelte file (for context)
|
|
13
12
|
* @returns {Object} { scriptBlocks: [{content, lang, startLine, isModule}], markup: {content, startLine} }
|
|
14
13
|
*/
|
|
15
14
|
export function extractSvelteSFC(content) {
|
|
@@ -14,10 +14,9 @@ import traverse from '@babel/traverse';
|
|
|
14
14
|
*
|
|
15
15
|
* @param {string} filePath - Path to .svelte file
|
|
16
16
|
* @param {string} content - Full file content
|
|
17
|
-
* @param {string} projectRoot - Project root directory
|
|
18
17
|
* @returns {Array} Array of state expectations
|
|
19
18
|
*/
|
|
20
|
-
export function detectSvelteState(filePath, content
|
|
19
|
+
export function detectSvelteState(filePath, content) {
|
|
21
20
|
const expectations = [];
|
|
22
21
|
|
|
23
22
|
try {
|