@fairfox/polly 0.11.0 → 0.12.1
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/dist/src/client/index.d.ts +33 -0
- package/dist/src/client/index.js +586 -0
- package/dist/src/client/index.js.map +13 -0
- package/dist/src/client/wrapper.d.ts +54 -0
- package/dist/src/core/clock.d.ts +63 -0
- package/dist/src/elysia/index.d.ts +43 -0
- package/dist/src/elysia/index.js +241 -0
- package/dist/src/elysia/index.js.map +12 -0
- package/dist/src/elysia/plugin.d.ts +85 -0
- package/dist/src/elysia/tla-generator.d.ts +16 -0
- package/dist/src/elysia/types.d.ts +137 -0
- package/dist/src/utils/function-serialization.d.ts +14 -0
- package/dist/tools/analysis/src/extract/adr.d.ts +37 -0
- package/dist/tools/analysis/src/extract/architecture.d.ts +42 -0
- package/dist/tools/analysis/src/extract/contexts.d.ts +74 -0
- package/dist/tools/analysis/src/extract/flows.d.ts +68 -0
- package/dist/tools/analysis/src/extract/handlers.d.ts +330 -0
- package/dist/tools/analysis/src/extract/index.d.ts +9 -0
- package/dist/tools/analysis/src/extract/integrations.d.ts +77 -0
- package/dist/tools/analysis/src/extract/manifest.d.ts +64 -0
- package/dist/tools/analysis/src/extract/project-detector.d.ts +103 -0
- package/dist/tools/analysis/src/extract/relationships.d.ts +119 -0
- package/dist/tools/analysis/src/extract/types.d.ts +139 -0
- package/dist/tools/analysis/src/index.d.ts +2 -0
- package/dist/tools/analysis/src/types/adr.d.ts +39 -0
- package/dist/tools/analysis/src/types/architecture.d.ts +198 -0
- package/dist/tools/analysis/src/types/core.d.ts +178 -0
- package/dist/tools/analysis/src/types/index.d.ts +4 -0
- package/dist/tools/teach/src/cli.js +140 -69
- package/dist/tools/teach/src/cli.js.map +12 -12
- package/dist/tools/teach/src/index.d.ts +28 -0
- package/dist/tools/teach/src/index.js +145 -72
- package/dist/tools/teach/src/index.js.map +13 -13
- package/dist/tools/verify/src/cli.js +33 -11
- package/dist/tools/verify/src/cli.js.map +5 -5
- package/dist/tools/visualize/src/cli.js +125 -66
- package/dist/tools/visualize/src/cli.js.map +11 -11
- package/dist/tools/visualize/src/codegen/structurizr.d.ts +343 -0
- package/dist/tools/visualize/src/types/structurizr.d.ts +235 -0
- package/package.json +10 -5
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
export type TypeKind = "boolean" | "string" | "number" | "enum" | "array" | "object" | "map" | "set" | "union" | "null" | "unknown";
|
|
2
|
+
export type TypeInfo = {
|
|
3
|
+
name: string;
|
|
4
|
+
kind: TypeKind;
|
|
5
|
+
nullable: boolean;
|
|
6
|
+
elementType?: TypeInfo;
|
|
7
|
+
valueType?: TypeInfo;
|
|
8
|
+
properties?: Record<string, TypeInfo>;
|
|
9
|
+
enumValues?: string[];
|
|
10
|
+
unionTypes?: TypeInfo[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A node represents an entity in the system that can send/receive messages.
|
|
14
|
+
*
|
|
15
|
+
* Examples:
|
|
16
|
+
* - Web extension: "background", "content", "popup"
|
|
17
|
+
* - Actor system: Individual actor instances
|
|
18
|
+
* - Event bus: Emitters/listeners
|
|
19
|
+
* - Worker threads: Main thread + worker instances
|
|
20
|
+
*/
|
|
21
|
+
export type NodeDefinition = {
|
|
22
|
+
/** Unique identifier for this node */
|
|
23
|
+
id: string;
|
|
24
|
+
/** Type of node (adapter-specific) */
|
|
25
|
+
type: string;
|
|
26
|
+
/** Which nodes can this send messages to? */
|
|
27
|
+
canSendTo: string[];
|
|
28
|
+
/** Which nodes can send messages to this? */
|
|
29
|
+
canReceiveFrom: string[];
|
|
30
|
+
/** Optional: Additional metadata */
|
|
31
|
+
metadata?: Record<string, unknown>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Defines a type of message that flows through the system
|
|
35
|
+
*/
|
|
36
|
+
export type MessageTypeDefinition = {
|
|
37
|
+
/** Name/identifier of the message type */
|
|
38
|
+
name: string;
|
|
39
|
+
/** Schema of the message payload */
|
|
40
|
+
payload: TypeInfo;
|
|
41
|
+
/** Routing constraints */
|
|
42
|
+
routing: {
|
|
43
|
+
/** Which node types can send this message? */
|
|
44
|
+
from: string[];
|
|
45
|
+
/** Which node types can receive this message? */
|
|
46
|
+
to: string[];
|
|
47
|
+
};
|
|
48
|
+
/** Optional: Expected response type */
|
|
49
|
+
response?: TypeInfo;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Configuration for a state field
|
|
53
|
+
*/
|
|
54
|
+
export type FieldConfig = {
|
|
55
|
+
maxLength: number | null;
|
|
56
|
+
} | {
|
|
57
|
+
min: number | null;
|
|
58
|
+
max: number | null;
|
|
59
|
+
} | {
|
|
60
|
+
type: "enum";
|
|
61
|
+
values: string[];
|
|
62
|
+
} | {
|
|
63
|
+
values: string[] | null;
|
|
64
|
+
abstract?: boolean;
|
|
65
|
+
} | {
|
|
66
|
+
maxSize: number | null;
|
|
67
|
+
valueType?: unknown;
|
|
68
|
+
} | {
|
|
69
|
+
abstract: boolean;
|
|
70
|
+
};
|
|
71
|
+
export type StateSchema = Record<string, FieldConfig>;
|
|
72
|
+
/**
|
|
73
|
+
* Represents an assignment to a state field
|
|
74
|
+
*/
|
|
75
|
+
export type StateAssignment = {
|
|
76
|
+
/** Field path (e.g., "user.loggedIn") */
|
|
77
|
+
field: string;
|
|
78
|
+
/** The assigned value */
|
|
79
|
+
value: string | boolean | number | null;
|
|
80
|
+
/** Optional condition guard */
|
|
81
|
+
conditional?: string;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* A verification condition (precondition or postcondition)
|
|
85
|
+
*/
|
|
86
|
+
export type VerificationCondition = {
|
|
87
|
+
/** The condition expression as a string */
|
|
88
|
+
expression: string;
|
|
89
|
+
/** Optional error message */
|
|
90
|
+
message?: string;
|
|
91
|
+
/** Source location */
|
|
92
|
+
location: {
|
|
93
|
+
line: number;
|
|
94
|
+
column: number;
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Constraint declared at the state level.
|
|
99
|
+
* These are automatically wired to message handlers by the parser.
|
|
100
|
+
*/
|
|
101
|
+
export type StateConstraint = {
|
|
102
|
+
/** State field this constraint applies to */
|
|
103
|
+
field: string;
|
|
104
|
+
/** Message type this constraint applies to */
|
|
105
|
+
messageType: string;
|
|
106
|
+
/** Precondition expression (e.g., "loggedIn === true") */
|
|
107
|
+
requires?: string;
|
|
108
|
+
/** Postcondition expression */
|
|
109
|
+
ensures?: string;
|
|
110
|
+
/** Optional error message */
|
|
111
|
+
message?: string;
|
|
112
|
+
/** Source location */
|
|
113
|
+
location: {
|
|
114
|
+
file: string;
|
|
115
|
+
line: number;
|
|
116
|
+
};
|
|
117
|
+
};
|
|
118
|
+
/**
|
|
119
|
+
* Component relationship detected from code analysis
|
|
120
|
+
*/
|
|
121
|
+
export type ComponentRelationship = {
|
|
122
|
+
/** Source component */
|
|
123
|
+
from: string;
|
|
124
|
+
/** Target component */
|
|
125
|
+
to: string;
|
|
126
|
+
/** Description of the relationship */
|
|
127
|
+
description: string;
|
|
128
|
+
/** Technology/method used */
|
|
129
|
+
technology?: string;
|
|
130
|
+
/** Confidence level */
|
|
131
|
+
confidence: "high" | "medium" | "low";
|
|
132
|
+
/** Evidence supporting this detection */
|
|
133
|
+
evidence: string[];
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Represents a message handler extracted from code
|
|
137
|
+
*/
|
|
138
|
+
export type MessageHandler = {
|
|
139
|
+
/** Which message type does this handle? */
|
|
140
|
+
messageType: string;
|
|
141
|
+
/** Which node handles this message? */
|
|
142
|
+
node: string;
|
|
143
|
+
/** State assignments made by this handler */
|
|
144
|
+
assignments: StateAssignment[];
|
|
145
|
+
/** Preconditions (requires() calls) */
|
|
146
|
+
preconditions: VerificationCondition[];
|
|
147
|
+
/** Postconditions (ensures() calls) */
|
|
148
|
+
postconditions: VerificationCondition[];
|
|
149
|
+
/** Source location */
|
|
150
|
+
location: {
|
|
151
|
+
file: string;
|
|
152
|
+
line: number;
|
|
153
|
+
};
|
|
154
|
+
/** Component relationships detected from this handler's code */
|
|
155
|
+
relationships?: ComponentRelationship[];
|
|
156
|
+
};
|
|
157
|
+
export type Confidence = "high" | "medium" | "low";
|
|
158
|
+
export type FieldAnalysis = {
|
|
159
|
+
path: string;
|
|
160
|
+
type: TypeInfo;
|
|
161
|
+
confidence: Confidence;
|
|
162
|
+
evidence: string[];
|
|
163
|
+
suggestions: string[];
|
|
164
|
+
bounds?: {
|
|
165
|
+
min?: number;
|
|
166
|
+
max?: number;
|
|
167
|
+
maxLength?: number;
|
|
168
|
+
maxSize?: number;
|
|
169
|
+
values?: string[];
|
|
170
|
+
};
|
|
171
|
+
};
|
|
172
|
+
export type CodebaseAnalysis = {
|
|
173
|
+
stateType: TypeInfo | null;
|
|
174
|
+
messageTypes: string[];
|
|
175
|
+
fields: FieldAnalysis[];
|
|
176
|
+
handlers: MessageHandler[];
|
|
177
|
+
stateConstraints: StateConstraint[];
|
|
178
|
+
};
|
|
@@ -94,25 +94,30 @@ class ProjectDetector {
|
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
96
|
detectBackgroundEntry(manifest, entryPoints) {
|
|
97
|
-
const background = manifest
|
|
97
|
+
const background = manifest["background"];
|
|
98
98
|
if (!background)
|
|
99
99
|
return;
|
|
100
|
-
const file = background
|
|
100
|
+
const file = background["service_worker"] || background["scripts"]?.[0] || background["page"];
|
|
101
101
|
if (file) {
|
|
102
102
|
entryPoints["background"] = this.findSourceFile(file);
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
detectContentScriptEntry(manifest, entryPoints) {
|
|
106
|
-
const contentScripts = manifest
|
|
106
|
+
const contentScripts = manifest["content_scripts"];
|
|
107
107
|
if (!contentScripts || contentScripts.length === 0)
|
|
108
108
|
return;
|
|
109
|
-
const
|
|
109
|
+
const firstScriptObj = contentScripts[0];
|
|
110
|
+
if (!firstScriptObj)
|
|
111
|
+
return;
|
|
112
|
+
const firstScript = firstScriptObj["js"]?.[0];
|
|
110
113
|
if (firstScript) {
|
|
111
114
|
entryPoints["content"] = this.findSourceFile(firstScript);
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
detectPopupEntry(manifest, entryPoints) {
|
|
115
|
-
const
|
|
118
|
+
const action = manifest["action"];
|
|
119
|
+
const browserAction = manifest["browser_action"];
|
|
120
|
+
const popup = action?.["default_popup"] || browserAction?.["default_popup"];
|
|
116
121
|
if (!popup)
|
|
117
122
|
return;
|
|
118
123
|
const jsFile = this.findAssociatedJS(path4.join(this.projectRoot, popup));
|
|
@@ -121,7 +126,8 @@ class ProjectDetector {
|
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
detectOptionsEntry(manifest, entryPoints) {
|
|
124
|
-
const
|
|
129
|
+
const optionsUi = manifest["options_ui"];
|
|
130
|
+
const options = optionsUi?.["page"] || manifest["options_page"];
|
|
125
131
|
if (!options)
|
|
126
132
|
return;
|
|
127
133
|
const jsFile = this.findAssociatedJS(path4.join(this.projectRoot, options));
|
|
@@ -176,7 +182,7 @@ class ProjectDetector {
|
|
|
176
182
|
detectElectron(packageJson) {
|
|
177
183
|
const entryPoints = {};
|
|
178
184
|
const mainCandidates = [
|
|
179
|
-
packageJson
|
|
185
|
+
packageJson["main"],
|
|
180
186
|
"src/main/index.ts",
|
|
181
187
|
"src/electron/main.ts",
|
|
182
188
|
"electron/main.ts",
|
|
@@ -210,9 +216,9 @@ class ProjectDetector {
|
|
|
210
216
|
renderer: "Renderer Process"
|
|
211
217
|
},
|
|
212
218
|
metadata: {
|
|
213
|
-
name: packageJson
|
|
214
|
-
version: packageJson
|
|
215
|
-
description: packageJson
|
|
219
|
+
name: packageJson["name"],
|
|
220
|
+
version: packageJson["version"],
|
|
221
|
+
description: packageJson["description"]
|
|
216
222
|
}
|
|
217
223
|
};
|
|
218
224
|
}
|
|
@@ -271,9 +277,9 @@ class ProjectDetector {
|
|
|
271
277
|
client: "Client"
|
|
272
278
|
},
|
|
273
279
|
metadata: {
|
|
274
|
-
name: packageJson
|
|
275
|
-
version: packageJson
|
|
276
|
-
description: packageJson
|
|
280
|
+
name: packageJson["name"],
|
|
281
|
+
version: packageJson["version"],
|
|
282
|
+
description: packageJson["description"]
|
|
277
283
|
}
|
|
278
284
|
};
|
|
279
285
|
}
|
|
@@ -4645,9 +4651,12 @@ class ContextAnalyzer {
|
|
|
4645
4651
|
const leadingComments = firstStatement.getLeadingCommentRanges();
|
|
4646
4652
|
if (leadingComments.length === 0)
|
|
4647
4653
|
return;
|
|
4648
|
-
const
|
|
4654
|
+
const firstComment = leadingComments[0];
|
|
4655
|
+
if (!firstComment)
|
|
4656
|
+
return;
|
|
4657
|
+
const comment = firstComment.getText();
|
|
4649
4658
|
const descMatch = comment.match(/@description\s+(.+?)(?:\n|$)/s);
|
|
4650
|
-
if (descMatch) {
|
|
4659
|
+
if (descMatch?.[1]) {
|
|
4651
4660
|
return descMatch[1].trim();
|
|
4652
4661
|
}
|
|
4653
4662
|
const lines = comment.split(`
|
|
@@ -4746,6 +4755,8 @@ class ContextAnalyzer {
|
|
|
4746
4755
|
if (params.length === 0)
|
|
4747
4756
|
return [];
|
|
4748
4757
|
const propsParam = params[0];
|
|
4758
|
+
if (!propsParam)
|
|
4759
|
+
return [];
|
|
4749
4760
|
const type = propsParam.getType();
|
|
4750
4761
|
const props = [];
|
|
4751
4762
|
for (const prop of type.getProperties()) {
|
|
@@ -4761,6 +4772,8 @@ class ContextAnalyzer {
|
|
|
4761
4772
|
if (typeArgs.length === 0)
|
|
4762
4773
|
return [];
|
|
4763
4774
|
const propsType = typeArgs[0];
|
|
4775
|
+
if (!propsType)
|
|
4776
|
+
return [];
|
|
4764
4777
|
const props = [];
|
|
4765
4778
|
for (const prop of propsType.getProperties()) {
|
|
4766
4779
|
props.push(prop.getName());
|
|
@@ -4768,10 +4781,15 @@ class ContextAnalyzer {
|
|
|
4768
4781
|
return props;
|
|
4769
4782
|
}
|
|
4770
4783
|
extractJSDocDescription(node) {
|
|
4784
|
+
if (!Node.isJSDocable(node))
|
|
4785
|
+
return;
|
|
4771
4786
|
const jsDocs = node.getJsDocs();
|
|
4772
4787
|
if (jsDocs.length === 0)
|
|
4773
4788
|
return;
|
|
4774
|
-
const
|
|
4789
|
+
const firstDoc = jsDocs[0];
|
|
4790
|
+
if (!firstDoc)
|
|
4791
|
+
return;
|
|
4792
|
+
const description = firstDoc.getDescription().trim();
|
|
4775
4793
|
return description || undefined;
|
|
4776
4794
|
}
|
|
4777
4795
|
isUIContext(contextType) {
|
|
@@ -4853,7 +4871,10 @@ class FlowAnalyzer {
|
|
|
4853
4871
|
if (args.length === 0) {
|
|
4854
4872
|
return;
|
|
4855
4873
|
}
|
|
4856
|
-
const
|
|
4874
|
+
const firstArg = args[0];
|
|
4875
|
+
if (!firstArg)
|
|
4876
|
+
return;
|
|
4877
|
+
const msgType = this.extractMessageTypeFromArg(firstArg);
|
|
4857
4878
|
if (msgType === messageType) {
|
|
4858
4879
|
senders.push({
|
|
4859
4880
|
context,
|
|
@@ -4873,7 +4894,10 @@ class FlowAnalyzer {
|
|
|
4873
4894
|
if (args.length === 0) {
|
|
4874
4895
|
return;
|
|
4875
4896
|
}
|
|
4876
|
-
const
|
|
4897
|
+
const firstArg = args[0];
|
|
4898
|
+
if (!firstArg)
|
|
4899
|
+
return;
|
|
4900
|
+
const msgType = this.extractMessageTypeFromArg(firstArg);
|
|
4877
4901
|
if (msgType === messageType) {
|
|
4878
4902
|
senders.push({
|
|
4879
4903
|
context,
|
|
@@ -4943,7 +4967,10 @@ class FlowAnalyzer {
|
|
|
4943
4967
|
if (args.length === 0) {
|
|
4944
4968
|
return;
|
|
4945
4969
|
}
|
|
4946
|
-
const
|
|
4970
|
+
const firstArg = args[0];
|
|
4971
|
+
if (!firstArg)
|
|
4972
|
+
return;
|
|
4973
|
+
const messageType = this.extractMessageTypeFromArg(firstArg);
|
|
4947
4974
|
if (messageType) {
|
|
4948
4975
|
sends.push({
|
|
4949
4976
|
messageType,
|
|
@@ -4996,10 +5023,17 @@ class FlowAnalyzer {
|
|
|
4996
5023
|
});
|
|
4997
5024
|
if (!targetNode)
|
|
4998
5025
|
return {};
|
|
4999
|
-
const
|
|
5026
|
+
const nodeAny = targetNode;
|
|
5027
|
+
if (!("getJsDocs" in nodeAny) || typeof nodeAny.getJsDocs !== "function") {
|
|
5028
|
+
return {};
|
|
5029
|
+
}
|
|
5030
|
+
const jsDocs = nodeAny.getJsDocs();
|
|
5000
5031
|
if (jsDocs.length === 0)
|
|
5001
5032
|
return {};
|
|
5002
|
-
const
|
|
5033
|
+
const firstDoc = jsDocs[0];
|
|
5034
|
+
if (!firstDoc)
|
|
5035
|
+
return {};
|
|
5036
|
+
const comment = firstDoc.getText();
|
|
5003
5037
|
const flowMatch = comment.match(/@flow\s+([^\s]+)/);
|
|
5004
5038
|
const flowName = flowMatch ? flowMatch[1] : undefined;
|
|
5005
5039
|
const triggerMatch = comment.match(/@trigger\s+(.+?)(?:\n|$)/);
|
|
@@ -5802,7 +5836,10 @@ class HandlerExtractor {
|
|
|
5802
5836
|
if (!body) {
|
|
5803
5837
|
return;
|
|
5804
5838
|
}
|
|
5805
|
-
const
|
|
5839
|
+
const firstAwait = awaitExpressions[0];
|
|
5840
|
+
if (!firstAwait)
|
|
5841
|
+
return;
|
|
5842
|
+
const firstAwaitPos = firstAwait.getStart();
|
|
5806
5843
|
funcNode.forEachDescendant((node) => {
|
|
5807
5844
|
if (Node4.isBinaryExpression(node)) {
|
|
5808
5845
|
this.checkBinaryExpressionMutation(node, firstAwaitPos, mutations);
|
|
@@ -5853,6 +5890,8 @@ class HandlerExtractor {
|
|
|
5853
5890
|
return null;
|
|
5854
5891
|
}
|
|
5855
5892
|
const conditionArg = args[0];
|
|
5893
|
+
if (!conditionArg)
|
|
5894
|
+
return null;
|
|
5856
5895
|
const expression = conditionArg.getText();
|
|
5857
5896
|
let message;
|
|
5858
5897
|
if (args.length >= 2 && Node4.isStringLiteral(args[1])) {
|
|
@@ -6158,12 +6197,17 @@ class HandlerExtractor {
|
|
|
6158
6197
|
return;
|
|
6159
6198
|
}
|
|
6160
6199
|
extractMessageTypeFromTypePredicateFunction(node, returnTypeNode) {
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6200
|
+
if (!Node4.isTypePredicate(returnTypeNode)) {
|
|
6201
|
+
return null;
|
|
6202
|
+
}
|
|
6203
|
+
if ("getTypeNode" in returnTypeNode && typeof returnTypeNode.getTypeNode === "function") {
|
|
6204
|
+
const typeNode = returnTypeNode.getTypeNode();
|
|
6205
|
+
if (typeNode) {
|
|
6206
|
+
const typeName = typeNode.getText();
|
|
6207
|
+
const messageType = this.extractMessageTypeFromTypeName(typeName);
|
|
6208
|
+
if (messageType) {
|
|
6209
|
+
return messageType;
|
|
6210
|
+
}
|
|
6167
6211
|
}
|
|
6168
6212
|
}
|
|
6169
6213
|
return this.extractMessageTypeFromFunctionBodyText(node);
|
|
@@ -6495,7 +6539,10 @@ class IntegrationAnalyzer {
|
|
|
6495
6539
|
if (args.length === 0) {
|
|
6496
6540
|
return;
|
|
6497
6541
|
}
|
|
6498
|
-
const
|
|
6542
|
+
const firstArg = args[0];
|
|
6543
|
+
if (!firstArg)
|
|
6544
|
+
return;
|
|
6545
|
+
const url = this.extractURLFromArg(firstArg);
|
|
6499
6546
|
if (!url) {
|
|
6500
6547
|
return;
|
|
6501
6548
|
}
|
|
@@ -6676,10 +6723,15 @@ class IntegrationAnalyzer {
|
|
|
6676
6723
|
}
|
|
6677
6724
|
}
|
|
6678
6725
|
extractJSDocDescription(node) {
|
|
6679
|
-
|
|
6726
|
+
if (!Node5.isJSDocable(node))
|
|
6727
|
+
return;
|
|
6728
|
+
const jsDocs = node.getJsDocs();
|
|
6680
6729
|
if (jsDocs.length === 0)
|
|
6681
6730
|
return;
|
|
6682
|
-
const
|
|
6731
|
+
const firstDoc = jsDocs[0];
|
|
6732
|
+
if (!firstDoc)
|
|
6733
|
+
return;
|
|
6734
|
+
const comment = firstDoc.getDescription().trim();
|
|
6683
6735
|
return comment || undefined;
|
|
6684
6736
|
}
|
|
6685
6737
|
}
|
|
@@ -6718,17 +6770,17 @@ class ManifestParser {
|
|
|
6718
6770
|
}
|
|
6719
6771
|
const manifest = this.manifestData;
|
|
6720
6772
|
return {
|
|
6721
|
-
name: manifest
|
|
6722
|
-
version: manifest
|
|
6723
|
-
description: manifest
|
|
6724
|
-
manifestVersion: manifest
|
|
6773
|
+
name: manifest["name"] || "Unknown Extension",
|
|
6774
|
+
version: manifest["version"] || "0.0.0",
|
|
6775
|
+
description: manifest["description"],
|
|
6776
|
+
manifestVersion: manifest["manifest_version"] || 2,
|
|
6725
6777
|
background: this.parseBackground(),
|
|
6726
6778
|
contentScripts: this.parseContentScripts(),
|
|
6727
6779
|
popup: this.parsePopup(),
|
|
6728
6780
|
options: this.parseOptions(),
|
|
6729
6781
|
devtools: this.parseDevtools(),
|
|
6730
|
-
permissions: manifest
|
|
6731
|
-
hostPermissions: manifest
|
|
6782
|
+
permissions: manifest["permissions"] || [],
|
|
6783
|
+
hostPermissions: manifest["host_permissions"] || []
|
|
6732
6784
|
};
|
|
6733
6785
|
}
|
|
6734
6786
|
getContextEntryPoints() {
|
|
@@ -6794,25 +6846,25 @@ class ManifestParser {
|
|
|
6794
6846
|
parseBackground() {
|
|
6795
6847
|
if (!this.manifestData)
|
|
6796
6848
|
return;
|
|
6797
|
-
const bg = this.manifestData
|
|
6849
|
+
const bg = this.manifestData["background"];
|
|
6798
6850
|
if (!bg)
|
|
6799
6851
|
return;
|
|
6800
|
-
if (bg
|
|
6852
|
+
if (bg["service_worker"]) {
|
|
6801
6853
|
return {
|
|
6802
6854
|
type: "service_worker",
|
|
6803
|
-
files: [bg
|
|
6855
|
+
files: [bg["service_worker"]]
|
|
6804
6856
|
};
|
|
6805
6857
|
}
|
|
6806
|
-
if (bg
|
|
6858
|
+
if (bg["scripts"]) {
|
|
6807
6859
|
return {
|
|
6808
6860
|
type: "script",
|
|
6809
|
-
files: bg
|
|
6861
|
+
files: bg["scripts"]
|
|
6810
6862
|
};
|
|
6811
6863
|
}
|
|
6812
|
-
if (bg
|
|
6864
|
+
if (bg["page"]) {
|
|
6813
6865
|
return {
|
|
6814
6866
|
type: "script",
|
|
6815
|
-
files: [bg
|
|
6867
|
+
files: [bg["page"]]
|
|
6816
6868
|
};
|
|
6817
6869
|
}
|
|
6818
6870
|
return;
|
|
@@ -6820,24 +6872,24 @@ class ManifestParser {
|
|
|
6820
6872
|
parseContentScripts() {
|
|
6821
6873
|
if (!this.manifestData)
|
|
6822
6874
|
return;
|
|
6823
|
-
const cs = this.manifestData
|
|
6875
|
+
const cs = this.manifestData["content_scripts"];
|
|
6824
6876
|
if (!cs || !Array.isArray(cs))
|
|
6825
6877
|
return;
|
|
6826
6878
|
return cs.map((script) => ({
|
|
6827
|
-
matches: script
|
|
6828
|
-
js: script
|
|
6829
|
-
css: script
|
|
6879
|
+
matches: script["matches"] || [],
|
|
6880
|
+
js: script["js"] || [],
|
|
6881
|
+
css: script["css"]
|
|
6830
6882
|
}));
|
|
6831
6883
|
}
|
|
6832
6884
|
parsePopup() {
|
|
6833
6885
|
if (!this.manifestData)
|
|
6834
6886
|
return;
|
|
6835
|
-
const action = this.manifestData
|
|
6887
|
+
const action = this.manifestData["action"] || this.manifestData["browser_action"];
|
|
6836
6888
|
if (!action)
|
|
6837
6889
|
return;
|
|
6838
|
-
if (action
|
|
6890
|
+
if (action["default_popup"]) {
|
|
6839
6891
|
return {
|
|
6840
|
-
html: action
|
|
6892
|
+
html: action["default_popup"],
|
|
6841
6893
|
default: true
|
|
6842
6894
|
};
|
|
6843
6895
|
}
|
|
@@ -6846,7 +6898,7 @@ class ManifestParser {
|
|
|
6846
6898
|
parseOptions() {
|
|
6847
6899
|
if (!this.manifestData)
|
|
6848
6900
|
return;
|
|
6849
|
-
const options = this.manifestData
|
|
6901
|
+
const options = this.manifestData["options_ui"] || this.manifestData["options_page"];
|
|
6850
6902
|
if (!options)
|
|
6851
6903
|
return;
|
|
6852
6904
|
if (typeof options === "string") {
|
|
@@ -6855,15 +6907,16 @@ class ManifestParser {
|
|
|
6855
6907
|
openInTab: false
|
|
6856
6908
|
};
|
|
6857
6909
|
}
|
|
6910
|
+
const optionsObj = options;
|
|
6858
6911
|
return {
|
|
6859
|
-
page:
|
|
6860
|
-
openInTab:
|
|
6912
|
+
page: optionsObj["page"],
|
|
6913
|
+
openInTab: optionsObj["open_in_tab"]
|
|
6861
6914
|
};
|
|
6862
6915
|
}
|
|
6863
6916
|
parseDevtools() {
|
|
6864
6917
|
if (!this.manifestData)
|
|
6865
6918
|
return;
|
|
6866
|
-
const devtools = this.manifestData
|
|
6919
|
+
const devtools = this.manifestData["devtools_page"];
|
|
6867
6920
|
if (!devtools)
|
|
6868
6921
|
return;
|
|
6869
6922
|
return {
|
|
@@ -7060,11 +7113,20 @@ class TypeExtractor {
|
|
|
7060
7113
|
const handlerAnalysis = this.extractHandlerAnalysis();
|
|
7061
7114
|
const validMessageTypes = this.filterAndLogMessageTypes(messageTypes, handlerAnalysis.messageTypes);
|
|
7062
7115
|
const validHandlers = this.filterAndLogHandlers(handlerAnalysis.handlers);
|
|
7116
|
+
const completeHandlers = validHandlers.map((h) => ({
|
|
7117
|
+
messageType: h.messageType,
|
|
7118
|
+
node: h.node || "unknown",
|
|
7119
|
+
assignments: h.assignments || [],
|
|
7120
|
+
preconditions: h.preconditions || [],
|
|
7121
|
+
postconditions: h.postconditions || [],
|
|
7122
|
+
location: h.location,
|
|
7123
|
+
relationships: h.relationships
|
|
7124
|
+
}));
|
|
7063
7125
|
return {
|
|
7064
7126
|
stateType,
|
|
7065
7127
|
messageTypes: validMessageTypes,
|
|
7066
7128
|
fields,
|
|
7067
|
-
handlers:
|
|
7129
|
+
handlers: completeHandlers,
|
|
7068
7130
|
stateConstraints: handlerAnalysis.stateConstraints
|
|
7069
7131
|
};
|
|
7070
7132
|
}
|
|
@@ -7166,7 +7228,7 @@ class TypeExtractor {
|
|
|
7166
7228
|
if (type.getAliasSymbol()) {
|
|
7167
7229
|
return this.extractFromTypeAlias(type, typeName, sourceFile, warnings);
|
|
7168
7230
|
}
|
|
7169
|
-
if (type.isConditionalType
|
|
7231
|
+
if (typeof type.isConditionalType === "function" && type.isConditionalType()) {
|
|
7170
7232
|
return this.extractFromConditionalType(type, warnings);
|
|
7171
7233
|
}
|
|
7172
7234
|
if (type.getText().includes("[K in ")) {
|
|
@@ -7231,7 +7293,10 @@ class TypeExtractor {
|
|
|
7231
7293
|
if (parts.length < 2) {
|
|
7232
7294
|
return messageTypes;
|
|
7233
7295
|
}
|
|
7234
|
-
const
|
|
7296
|
+
const secondPart = parts[1];
|
|
7297
|
+
if (!secondPart)
|
|
7298
|
+
return messageTypes;
|
|
7299
|
+
const branches = secondPart.split(":");
|
|
7235
7300
|
for (const branch of branches) {
|
|
7236
7301
|
const extracted = this.extractStringLiteralFromBranch(branch);
|
|
7237
7302
|
if (extracted) {
|
|
@@ -7693,9 +7758,12 @@ class StructurizrDSLGenerator {
|
|
|
7693
7758
|
}
|
|
7694
7759
|
for (const [messageType, handlers2] of handlersByType) {
|
|
7695
7760
|
const componentName = this.toComponentName(messageType);
|
|
7696
|
-
const
|
|
7697
|
-
|
|
7698
|
-
|
|
7761
|
+
const firstHandler = handlers2[0];
|
|
7762
|
+
if (!firstHandler)
|
|
7763
|
+
continue;
|
|
7764
|
+
const description = this.generateComponentDescription(messageType, firstHandler);
|
|
7765
|
+
const tags = this.getComponentTags(messageType, firstHandler);
|
|
7766
|
+
const properties = this.getComponentProperties(messageType, firstHandler, contextType);
|
|
7699
7767
|
componentDefs.push({
|
|
7700
7768
|
id: this.toId(componentName),
|
|
7701
7769
|
name: componentName,
|
|
@@ -8226,7 +8294,8 @@ class StructurizrDSLGenerator {
|
|
|
8226
8294
|
let stepCount = 0;
|
|
8227
8295
|
for (const { handler, contextName: _contextName } of handlers2) {
|
|
8228
8296
|
const handlerComponentId = this.toId(`${handler.messageType}_handler`);
|
|
8229
|
-
|
|
8297
|
+
const relationships = handler.relationships || [];
|
|
8298
|
+
for (const rel of relationships) {
|
|
8230
8299
|
const toComponent = this.toId(rel.to);
|
|
8231
8300
|
parts.push(` ${handlerComponentId} -> ${toComponent} "${rel.description}"`);
|
|
8232
8301
|
stepCount++;
|
|
@@ -8307,7 +8376,7 @@ class StructurizrDSLGenerator {
|
|
|
8307
8376
|
state: "Application state synchronization",
|
|
8308
8377
|
general: "Message flow through the system"
|
|
8309
8378
|
};
|
|
8310
|
-
return descriptions[domain] || descriptions
|
|
8379
|
+
return descriptions[domain] || descriptions["general"] || "Message flow through the system";
|
|
8311
8380
|
}
|
|
8312
8381
|
getUserAction(domain) {
|
|
8313
8382
|
const actions = {
|
|
@@ -8316,7 +8385,7 @@ class StructurizrDSLGenerator {
|
|
|
8316
8385
|
state: "Requests state",
|
|
8317
8386
|
general: "Interacts"
|
|
8318
8387
|
};
|
|
8319
|
-
return actions[domain] || actions
|
|
8388
|
+
return actions[domain] || actions["general"] || "Interacts";
|
|
8320
8389
|
}
|
|
8321
8390
|
getMessageDescription(messageType) {
|
|
8322
8391
|
const type = messageType.toLowerCase();
|
|
@@ -8555,11 +8624,13 @@ class StructurizrDSLGenerator {
|
|
|
8555
8624
|
}
|
|
8556
8625
|
if (this.options.perspectives?.[comp.id]) {
|
|
8557
8626
|
const perspectives = this.options.perspectives[comp.id];
|
|
8558
|
-
|
|
8559
|
-
|
|
8560
|
-
|
|
8627
|
+
if (perspectives) {
|
|
8628
|
+
parts.push(`${indent} perspectives {`);
|
|
8629
|
+
for (const perspective of perspectives) {
|
|
8630
|
+
parts.push(`${indent} "${this.escape(perspective.name)}" "${this.escape(perspective.description)}"`);
|
|
8631
|
+
}
|
|
8632
|
+
parts.push(`${indent} }`);
|
|
8561
8633
|
}
|
|
8562
|
-
parts.push(`${indent} }`);
|
|
8563
8634
|
}
|
|
8564
8635
|
parts.push(`${indent}}`);
|
|
8565
8636
|
return parts.join(`
|
|
@@ -9508,4 +9579,4 @@ Goodbye!`);
|
|
|
9508
9579
|
}
|
|
9509
9580
|
main();
|
|
9510
9581
|
|
|
9511
|
-
//# debugId=
|
|
9582
|
+
//# debugId=770FFA3847E6590364756E2164756E21
|