@fairfox/polly 0.19.0 → 0.20.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 +125 -948
- package/dist/cli/polly.js +25 -4
- package/dist/cli/polly.js.map +3 -3
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +46 -3
- package/dist/src/index.js.map +6 -5
- package/dist/src/shared/lib/resource.d.ts +54 -0
- package/dist/src/shared/lib/resource.js +583 -0
- package/dist/src/shared/lib/resource.js.map +13 -0
- package/dist/src/shared/lib/state.d.ts +1 -0
- package/dist/src/shared/lib/state.js +2 -1
- package/dist/src/shared/lib/state.js.map +3 -3
- package/dist/src/shared/state/app-state.js.map +2 -2
- package/dist/tools/init/templates/pwa/package.json.template +1 -2
- package/dist/tools/verify/specs/docker-compose.yml +1 -1
- package/dist/tools/verify/src/cli.js +176 -9
- package/dist/tools/verify/src/cli.js.map +6 -6
- package/dist/tools/visualize/src/cli.js +139 -4
- package/dist/tools/visualize/src/cli.js.map +3 -3
- package/package.json +5 -5
- package/dist/src/elysia/tla-generator.d.ts +0 -16
- package/dist/tools/verify/specs/verification.config.ts +0 -64
|
@@ -1784,12 +1784,13 @@ class HandlerExtractor {
|
|
|
1784
1784
|
const stateConstraints = [];
|
|
1785
1785
|
const globalStateConstraints = [];
|
|
1786
1786
|
const verifiedStates = [];
|
|
1787
|
+
const resources = [];
|
|
1787
1788
|
this.warnings = [];
|
|
1788
1789
|
const allSourceFiles = this.project.getSourceFiles();
|
|
1789
1790
|
const entryPoints = allSourceFiles.filter((f) => this.isWithinPackage(f.getFilePath()));
|
|
1790
1791
|
this.debugLogSourceFiles(allSourceFiles, entryPoints);
|
|
1791
1792
|
for (const entryPoint of entryPoints) {
|
|
1792
|
-
this.analyzeFileAndImports(entryPoint, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates);
|
|
1793
|
+
this.analyzeFileAndImports(entryPoint, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates, resources);
|
|
1793
1794
|
}
|
|
1794
1795
|
if (verifiedStates.length > 0) {
|
|
1795
1796
|
if (process.env["POLLY_DEBUG"]) {
|
|
@@ -1821,10 +1822,11 @@ class HandlerExtractor {
|
|
|
1821
1822
|
stateConstraints,
|
|
1822
1823
|
globalStateConstraints,
|
|
1823
1824
|
verifiedStates,
|
|
1825
|
+
resources,
|
|
1824
1826
|
warnings: this.warnings
|
|
1825
1827
|
};
|
|
1826
1828
|
}
|
|
1827
|
-
analyzeFileAndImports(sourceFile, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates) {
|
|
1829
|
+
analyzeFileAndImports(sourceFile, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates, resources) {
|
|
1828
1830
|
const filePath = sourceFile.getFilePath();
|
|
1829
1831
|
if (this.analyzedFiles.has(filePath)) {
|
|
1830
1832
|
return;
|
|
@@ -1842,6 +1844,20 @@ class HandlerExtractor {
|
|
|
1842
1844
|
globalStateConstraints.push(...fileGlobalConstraints);
|
|
1843
1845
|
const fileVerifiedStates = this.extractVerifiedStatesFromFile(sourceFile);
|
|
1844
1846
|
verifiedStates.push(...fileVerifiedStates);
|
|
1847
|
+
const fileResources = this.extractResourcesFromFile(sourceFile, filePath);
|
|
1848
|
+
for (const resource of fileResources) {
|
|
1849
|
+
resources.push(resource);
|
|
1850
|
+
const context = this.inferContext(filePath);
|
|
1851
|
+
const syntheticHandlers = this.createResourceHandlers(resource, context);
|
|
1852
|
+
for (const handler of syntheticHandlers) {
|
|
1853
|
+
handlers.push(handler);
|
|
1854
|
+
if (this.isValidTLAIdentifier(handler.messageType)) {
|
|
1855
|
+
messageTypes.add(handler.messageType);
|
|
1856
|
+
} else {
|
|
1857
|
+
invalidMessageTypes.add(handler.messageType);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1845
1861
|
const importDeclarations = sourceFile.getImportDeclarations();
|
|
1846
1862
|
for (const importDecl of importDeclarations) {
|
|
1847
1863
|
const importedFile = importDecl.getModuleSpecifierSourceFile();
|
|
@@ -1853,7 +1869,7 @@ class HandlerExtractor {
|
|
|
1853
1869
|
}
|
|
1854
1870
|
continue;
|
|
1855
1871
|
}
|
|
1856
|
-
this.analyzeFileAndImports(importedFile, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates);
|
|
1872
|
+
this.analyzeFileAndImports(importedFile, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates, resources);
|
|
1857
1873
|
} else if (process.env["POLLY_DEBUG"]) {
|
|
1858
1874
|
const specifier = importDecl.getModuleSpecifierValue();
|
|
1859
1875
|
if (!specifier.startsWith("node:") && !this.isNodeModuleImport(specifier)) {
|
|
@@ -3743,6 +3759,125 @@ class HandlerExtractor {
|
|
|
3743
3759
|
}
|
|
3744
3760
|
return name || funcName;
|
|
3745
3761
|
}
|
|
3762
|
+
extractResourcesFromFile(sourceFile, filePath) {
|
|
3763
|
+
const resources = [];
|
|
3764
|
+
sourceFile.forEachDescendant((node) => {
|
|
3765
|
+
if (!Node4.isCallExpression(node))
|
|
3766
|
+
return;
|
|
3767
|
+
const resource = this.extractResourcePattern(node, filePath);
|
|
3768
|
+
if (resource) {
|
|
3769
|
+
resources.push(resource);
|
|
3770
|
+
}
|
|
3771
|
+
});
|
|
3772
|
+
return resources;
|
|
3773
|
+
}
|
|
3774
|
+
extractResourcePattern(node, filePath) {
|
|
3775
|
+
const expression = node.getExpression();
|
|
3776
|
+
if (!Node4.isIdentifier(expression))
|
|
3777
|
+
return null;
|
|
3778
|
+
if (expression.getText() !== "$resource")
|
|
3779
|
+
return null;
|
|
3780
|
+
const args = node.getArguments();
|
|
3781
|
+
if (args.length < 2)
|
|
3782
|
+
return null;
|
|
3783
|
+
const nameArg = args[0];
|
|
3784
|
+
if (!nameArg || !Node4.isStringLiteral(nameArg))
|
|
3785
|
+
return null;
|
|
3786
|
+
const name = nameArg.getLiteralValue();
|
|
3787
|
+
const optionsArg = args[1];
|
|
3788
|
+
if (!optionsArg || !Node4.isObjectLiteralExpression(optionsArg))
|
|
3789
|
+
return null;
|
|
3790
|
+
const sourceSignals = this.extractResourceSourceReads(optionsArg);
|
|
3791
|
+
const variableName = this.getVariableNameFromParent(node) || name;
|
|
3792
|
+
if (process.env["POLLY_DEBUG"]) {
|
|
3793
|
+
console.log(`[DEBUG] Found $resource: ${variableName} (name: "${name}") with source signals: [${sourceSignals.join(", ")}]`);
|
|
3794
|
+
}
|
|
3795
|
+
return {
|
|
3796
|
+
name,
|
|
3797
|
+
variableName,
|
|
3798
|
+
filePath,
|
|
3799
|
+
line: node.getStartLineNumber(),
|
|
3800
|
+
sourceSignals
|
|
3801
|
+
};
|
|
3802
|
+
}
|
|
3803
|
+
extractResourceSourceReads(optionsObj) {
|
|
3804
|
+
const signals = [];
|
|
3805
|
+
const sourceProp = optionsObj.getProperty("source");
|
|
3806
|
+
if (!sourceProp || !Node4.isPropertyAssignment(sourceProp))
|
|
3807
|
+
return signals;
|
|
3808
|
+
const sourceInit = sourceProp.getInitializer();
|
|
3809
|
+
if (!sourceInit)
|
|
3810
|
+
return signals;
|
|
3811
|
+
sourceInit.forEachDescendant((node) => {
|
|
3812
|
+
if (!Node4.isPropertyAccessExpression(node))
|
|
3813
|
+
return;
|
|
3814
|
+
const text = node.getText();
|
|
3815
|
+
const match = text.match(/^(\w+)\.value(?:\.(\w+))?$/);
|
|
3816
|
+
if (match) {
|
|
3817
|
+
const signalName = match[1];
|
|
3818
|
+
const fieldName = match[2];
|
|
3819
|
+
if (fieldName) {
|
|
3820
|
+
signals.push(`${signalName}_${fieldName}`);
|
|
3821
|
+
} else {
|
|
3822
|
+
signals.push(signalName);
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
});
|
|
3826
|
+
return signals;
|
|
3827
|
+
}
|
|
3828
|
+
createResourceHandlers(resource, context) {
|
|
3829
|
+
const { name, filePath, line } = resource;
|
|
3830
|
+
const location = { file: filePath, line };
|
|
3831
|
+
const fetchStart = {
|
|
3832
|
+
messageType: `${name}_FetchStart`,
|
|
3833
|
+
node: context,
|
|
3834
|
+
assignments: [
|
|
3835
|
+
{ field: `${name}_status`, value: "loading" },
|
|
3836
|
+
{ field: `${name}_error`, value: false }
|
|
3837
|
+
],
|
|
3838
|
+
preconditions: [
|
|
3839
|
+
{
|
|
3840
|
+
expression: `${name}_status !== "loading"`,
|
|
3841
|
+
location: { line, column: 0 }
|
|
3842
|
+
}
|
|
3843
|
+
],
|
|
3844
|
+
postconditions: [],
|
|
3845
|
+
location
|
|
3846
|
+
};
|
|
3847
|
+
const fetchSuccess = {
|
|
3848
|
+
messageType: `${name}_FetchSuccess`,
|
|
3849
|
+
node: context,
|
|
3850
|
+
assignments: [
|
|
3851
|
+
{ field: `${name}_status`, value: "success" },
|
|
3852
|
+
{ field: `${name}_error`, value: false }
|
|
3853
|
+
],
|
|
3854
|
+
preconditions: [
|
|
3855
|
+
{
|
|
3856
|
+
expression: `${name}_status === "loading"`,
|
|
3857
|
+
location: { line, column: 0 }
|
|
3858
|
+
}
|
|
3859
|
+
],
|
|
3860
|
+
postconditions: [],
|
|
3861
|
+
location
|
|
3862
|
+
};
|
|
3863
|
+
const fetchError = {
|
|
3864
|
+
messageType: `${name}_FetchError`,
|
|
3865
|
+
node: context,
|
|
3866
|
+
assignments: [
|
|
3867
|
+
{ field: `${name}_status`, value: "error" },
|
|
3868
|
+
{ field: `${name}_error`, value: true }
|
|
3869
|
+
],
|
|
3870
|
+
preconditions: [
|
|
3871
|
+
{
|
|
3872
|
+
expression: `${name}_status === "loading"`,
|
|
3873
|
+
location: { line, column: 0 }
|
|
3874
|
+
}
|
|
3875
|
+
],
|
|
3876
|
+
postconditions: [],
|
|
3877
|
+
location
|
|
3878
|
+
};
|
|
3879
|
+
return [fetchStart, fetchSuccess, fetchError];
|
|
3880
|
+
}
|
|
3746
3881
|
}
|
|
3747
3882
|
|
|
3748
3883
|
// tools/analysis/src/extract/integrations.ts
|
|
@@ -6073,4 +6208,4 @@ main().catch((_error) => {
|
|
|
6073
6208
|
process.exit(1);
|
|
6074
6209
|
});
|
|
6075
6210
|
|
|
6076
|
-
//# debugId=
|
|
6211
|
+
//# debugId=877A170E241AB38F64756E2164756E21
|