donobu 2.18.5 → 2.19.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/apis/FlowsApi.d.ts +4 -0
- package/dist/apis/FlowsApi.d.ts.map +1 -1
- package/dist/apis/FlowsApi.js +15 -1
- package/dist/apis/FlowsApi.js.map +1 -1
- package/dist/apis/SpecialFlowsApi.d.ts.map +1 -1
- package/dist/apis/SpecialFlowsApi.js +11 -9
- package/dist/apis/SpecialFlowsApi.js.map +1 -1
- package/dist/assets/generated/version +1 -1
- package/dist/esm/apis/FlowsApi.d.ts +4 -0
- package/dist/esm/apis/FlowsApi.d.ts.map +1 -1
- package/dist/esm/apis/FlowsApi.js +15 -1
- package/dist/esm/apis/FlowsApi.js.map +1 -1
- package/dist/esm/apis/SpecialFlowsApi.d.ts.map +1 -1
- package/dist/esm/apis/SpecialFlowsApi.js +11 -9
- package/dist/esm/apis/SpecialFlowsApi.js.map +1 -1
- package/dist/esm/assets/generated/version +1 -1
- package/dist/esm/lib/testExtension.d.ts.map +1 -1
- package/dist/esm/lib/testExtension.js +11 -10
- package/dist/esm/lib/testExtension.js.map +1 -1
- package/dist/esm/managers/AdminApiController.d.ts.map +1 -1
- package/dist/esm/managers/AdminApiController.js +1 -0
- package/dist/esm/managers/AdminApiController.js.map +1 -1
- package/dist/esm/managers/CodeGenerator.d.ts +47 -1
- package/dist/esm/managers/CodeGenerator.d.ts.map +1 -1
- package/dist/esm/managers/CodeGenerator.js +177 -18
- package/dist/esm/managers/CodeGenerator.js.map +1 -1
- package/dist/esm/managers/DonobuFlow.d.ts.map +1 -1
- package/dist/esm/managers/DonobuFlow.js +0 -2
- package/dist/esm/managers/DonobuFlow.js.map +1 -1
- package/dist/esm/managers/DonobuFlowsManager.d.ts +58 -34
- package/dist/esm/managers/DonobuFlowsManager.d.ts.map +1 -1
- package/dist/esm/managers/DonobuFlowsManager.js +205 -52
- package/dist/esm/managers/DonobuFlowsManager.js.map +1 -1
- package/dist/esm/managers/FlowDependencyAnalyzer.d.ts +40 -0
- package/dist/esm/managers/FlowDependencyAnalyzer.d.ts.map +1 -0
- package/dist/esm/managers/FlowDependencyAnalyzer.js +236 -0
- package/dist/esm/managers/FlowDependencyAnalyzer.js.map +1 -0
- package/dist/esm/managers/ProjectStructureGenerator.d.ts +62 -0
- package/dist/esm/managers/ProjectStructureGenerator.d.ts.map +1 -0
- package/dist/esm/managers/ProjectStructureGenerator.js +234 -0
- package/dist/esm/managers/ProjectStructureGenerator.js.map +1 -0
- package/dist/esm/tools/ExtractPaymentProviderKeyTool.d.ts +47 -1
- package/dist/esm/tools/ExtractPaymentProviderKeyTool.d.ts.map +1 -1
- package/dist/esm/tools/ExtractPaymentProviderKeyTool.js +160 -25
- package/dist/esm/tools/ExtractPaymentProviderKeyTool.js.map +1 -1
- package/dist/esm/utils/PlaywrightUtils.d.ts +3 -3
- package/dist/esm/utils/PlaywrightUtils.d.ts.map +1 -1
- package/dist/esm/utils/PlaywrightUtils.js +39 -8
- package/dist/esm/utils/PlaywrightUtils.js.map +1 -1
- package/dist/lib/testExtension.d.ts.map +1 -1
- package/dist/lib/testExtension.js +11 -10
- package/dist/lib/testExtension.js.map +1 -1
- package/dist/managers/AdminApiController.d.ts.map +1 -1
- package/dist/managers/AdminApiController.js +1 -0
- package/dist/managers/AdminApiController.js.map +1 -1
- package/dist/managers/CodeGenerator.d.ts +47 -1
- package/dist/managers/CodeGenerator.d.ts.map +1 -1
- package/dist/managers/CodeGenerator.js +177 -18
- package/dist/managers/CodeGenerator.js.map +1 -1
- package/dist/managers/DonobuFlow.d.ts.map +1 -1
- package/dist/managers/DonobuFlow.js +0 -2
- package/dist/managers/DonobuFlow.js.map +1 -1
- package/dist/managers/DonobuFlowsManager.d.ts +58 -34
- package/dist/managers/DonobuFlowsManager.d.ts.map +1 -1
- package/dist/managers/DonobuFlowsManager.js +205 -52
- package/dist/managers/DonobuFlowsManager.js.map +1 -1
- package/dist/managers/FlowDependencyAnalyzer.d.ts +40 -0
- package/dist/managers/FlowDependencyAnalyzer.d.ts.map +1 -0
- package/dist/managers/FlowDependencyAnalyzer.js +236 -0
- package/dist/managers/FlowDependencyAnalyzer.js.map +1 -0
- package/dist/managers/ProjectStructureGenerator.d.ts +62 -0
- package/dist/managers/ProjectStructureGenerator.d.ts.map +1 -0
- package/dist/managers/ProjectStructureGenerator.js +234 -0
- package/dist/managers/ProjectStructureGenerator.js.map +1 -0
- package/dist/tools/ExtractPaymentProviderKeyTool.d.ts +47 -1
- package/dist/tools/ExtractPaymentProviderKeyTool.d.ts.map +1 -1
- package/dist/tools/ExtractPaymentProviderKeyTool.js +160 -25
- package/dist/tools/ExtractPaymentProviderKeyTool.js.map +1 -1
- package/dist/utils/PlaywrightUtils.d.ts +3 -3
- package/dist/utils/PlaywrightUtils.d.ts.map +1 -1
- package/dist/utils/PlaywrightUtils.js +39 -8
- package/dist/utils/PlaywrightUtils.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/managers/FlowDependencyAnalyzer.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.FlowDependencyAnalyzer = void 0;
|
|
5
|
+
class FlowDependencyAnalyzer {
|
|
6
|
+
/**
|
|
7
|
+
* Analyzes a collection of flows and builds a dependency graph based on browser state references.
|
|
8
|
+
*/
|
|
9
|
+
static analyzeDependencies(flows) {
|
|
10
|
+
const flowsMap = new Map(flows.map((flow) => [flow.id, flow]));
|
|
11
|
+
const nameToIdMap = new Map();
|
|
12
|
+
// Build name-to-ID mapping for flows that have names
|
|
13
|
+
// When multiple flows have the same name, prefer the one with the latest completedAt
|
|
14
|
+
flows.forEach((flow) => {
|
|
15
|
+
if (flow.name) {
|
|
16
|
+
const existingFlowId = nameToIdMap.get(flow.name);
|
|
17
|
+
if (!existingFlowId) {
|
|
18
|
+
// First flow with this name
|
|
19
|
+
nameToIdMap.set(flow.name, flow.id);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Compare with existing flow to determine which one to keep
|
|
23
|
+
const existingFlow = flowsMap.get(existingFlowId);
|
|
24
|
+
const shouldReplace = this.shouldReplaceFlow(existingFlow, flow);
|
|
25
|
+
if (shouldReplace) {
|
|
26
|
+
nameToIdMap.set(flow.name, flow.id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const dependencies = new Map();
|
|
32
|
+
const dependents = new Map();
|
|
33
|
+
// Initialize maps
|
|
34
|
+
flows.forEach((flow) => {
|
|
35
|
+
dependencies.set(flow.id, []);
|
|
36
|
+
dependents.set(flow.id, []);
|
|
37
|
+
});
|
|
38
|
+
// Analyze each flow's browser.initialState to determine dependencies
|
|
39
|
+
flows.forEach((flow) => {
|
|
40
|
+
const deps = this.extractDependencies(flow, nameToIdMap, flowsMap);
|
|
41
|
+
dependencies.set(flow.id, deps);
|
|
42
|
+
// Update dependents map
|
|
43
|
+
deps.forEach((depId) => {
|
|
44
|
+
const currentDependents = dependents.get(depId) || [];
|
|
45
|
+
currentDependents.push(flow.id);
|
|
46
|
+
dependents.set(depId, currentDependents);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
// Detect circular dependencies
|
|
50
|
+
this.detectCircularDependencies(dependencies);
|
|
51
|
+
// Find independent flows (no dependencies)
|
|
52
|
+
const independentFlows = flows
|
|
53
|
+
.filter((flow) => (dependencies.get(flow.id) || []).length === 0)
|
|
54
|
+
.map((flow) => flow.id);
|
|
55
|
+
// Calculate execution order using topological sort
|
|
56
|
+
const executionOrder = this.calculateExecutionOrder(dependencies);
|
|
57
|
+
return {
|
|
58
|
+
flows: flowsMap,
|
|
59
|
+
dependencies,
|
|
60
|
+
dependents,
|
|
61
|
+
independentFlows,
|
|
62
|
+
executionOrder,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Extracts dependencies for a single flow by analyzing its browser.initialState
|
|
67
|
+
*/
|
|
68
|
+
static extractDependencies(flow, nameToIdMap, flowsMap) {
|
|
69
|
+
const initialState = flow.browser?.initialState;
|
|
70
|
+
if (!initialState) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
switch (initialState.type) {
|
|
74
|
+
case 'id':
|
|
75
|
+
// Direct flow ID reference
|
|
76
|
+
if (flowsMap.has(initialState.value)) {
|
|
77
|
+
return [initialState.value];
|
|
78
|
+
}
|
|
79
|
+
throw new Error(`Flow dependency not found: flow with ID "${initialState.value}" does not exist`);
|
|
80
|
+
case 'name':
|
|
81
|
+
// Flow name reference - resolve to ID
|
|
82
|
+
const flowId = nameToIdMap.get(initialState.value);
|
|
83
|
+
if (flowId) {
|
|
84
|
+
return [flowId];
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`Flow dependency not found: flow with name "${initialState.value}" does not exist`);
|
|
87
|
+
case 'json':
|
|
88
|
+
// Direct JSON state - no dependencies
|
|
89
|
+
return [];
|
|
90
|
+
default:
|
|
91
|
+
throw new Error(`Unknown browser state reference type: ${initialState.type}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Determines if a new flow should replace an existing flow when they have the same name.
|
|
96
|
+
* Prefers flows with later completedAt times, treating null completedAt as "never completed".
|
|
97
|
+
*/
|
|
98
|
+
static shouldReplaceFlow(existingFlow, newFlow) {
|
|
99
|
+
// If both flows have completedAt values, prefer the later one
|
|
100
|
+
if (existingFlow.completedAt !== null && newFlow.completedAt !== null) {
|
|
101
|
+
return newFlow.completedAt > existingFlow.completedAt;
|
|
102
|
+
}
|
|
103
|
+
// If only the new flow has a completedAt value, prefer it
|
|
104
|
+
if (existingFlow.completedAt === null && newFlow.completedAt !== null) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
// If only the existing flow has a completedAt value, keep it
|
|
108
|
+
if (existingFlow.completedAt !== null && newFlow.completedAt === null) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
// If neither has completedAt, prefer the one with the later startedAt
|
|
112
|
+
// (this handles flows that are still running or were interrupted)
|
|
113
|
+
if (existingFlow.startedAt !== null && newFlow.startedAt !== null) {
|
|
114
|
+
return newFlow.startedAt > existingFlow.startedAt;
|
|
115
|
+
}
|
|
116
|
+
// If only the new flow has startedAt, prefer it
|
|
117
|
+
if (existingFlow.startedAt === null && newFlow.startedAt !== null) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
// If only the existing flow has startedAt, keep it
|
|
121
|
+
if (existingFlow.startedAt !== null && newFlow.startedAt === null) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
// If we can't determine based on timestamps, keep the existing flow
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Detects circular dependencies using DFS
|
|
129
|
+
*/
|
|
130
|
+
static detectCircularDependencies(dependencies) {
|
|
131
|
+
const visiting = new Set();
|
|
132
|
+
const visited = new Set();
|
|
133
|
+
const visit = (flowId, path) => {
|
|
134
|
+
if (visiting.has(flowId)) {
|
|
135
|
+
const cycleStart = path.indexOf(flowId);
|
|
136
|
+
const cycle = [...path.slice(cycleStart), flowId];
|
|
137
|
+
throw new Error(`Circular dependency detected: ${cycle.join(' -> ')}`);
|
|
138
|
+
}
|
|
139
|
+
if (visited.has(flowId)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
visiting.add(flowId);
|
|
143
|
+
const deps = dependencies.get(flowId) || [];
|
|
144
|
+
deps.forEach((depId) => {
|
|
145
|
+
visit(depId, [...path, flowId]);
|
|
146
|
+
});
|
|
147
|
+
visiting.delete(flowId);
|
|
148
|
+
visited.add(flowId);
|
|
149
|
+
};
|
|
150
|
+
// Check each flow for cycles
|
|
151
|
+
dependencies.forEach((_, flowId) => {
|
|
152
|
+
if (!visited.has(flowId)) {
|
|
153
|
+
visit(flowId, []);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Calculates execution order using topological sort with parallel execution support
|
|
159
|
+
*/
|
|
160
|
+
static calculateExecutionOrder(dependencies) {
|
|
161
|
+
const executionOrder = [];
|
|
162
|
+
const remainingFlows = new Set(dependencies.keys());
|
|
163
|
+
const completedFlows = new Set();
|
|
164
|
+
// Process flows in waves - each wave can execute in parallel
|
|
165
|
+
while (remainingFlows.size > 0) {
|
|
166
|
+
const currentWave = [];
|
|
167
|
+
// Find flows that can execute now (all dependencies completed)
|
|
168
|
+
for (const flowId of remainingFlows) {
|
|
169
|
+
const deps = dependencies.get(flowId) || [];
|
|
170
|
+
const canExecute = deps.every((depId) => completedFlows.has(depId));
|
|
171
|
+
if (canExecute) {
|
|
172
|
+
currentWave.push(flowId);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (currentWave.length === 0) {
|
|
176
|
+
// This should not happen if circular dependency detection worked correctly
|
|
177
|
+
const remaining = Array.from(remainingFlows);
|
|
178
|
+
throw new Error(`Unable to resolve execution order. Remaining flows: ${remaining.join(', ')}`);
|
|
179
|
+
}
|
|
180
|
+
// Add current wave to execution order
|
|
181
|
+
executionOrder.push(currentWave);
|
|
182
|
+
// Mark these flows as completed and remove from remaining
|
|
183
|
+
currentWave.forEach((flowId) => {
|
|
184
|
+
completedFlows.add(flowId);
|
|
185
|
+
remainingFlows.delete(flowId);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return executionOrder;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Validates that all flow dependencies can be resolved
|
|
192
|
+
*/
|
|
193
|
+
static validateDependencies(flows) {
|
|
194
|
+
try {
|
|
195
|
+
this.analyzeDependencies(flows);
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
throw new Error(`Flow dependency validation failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Gets a human-readable summary of the dependency graph
|
|
203
|
+
*/
|
|
204
|
+
static getDependencySummary(graph) {
|
|
205
|
+
const lines = [];
|
|
206
|
+
lines.push(`Flow Dependency Analysis:`);
|
|
207
|
+
lines.push(`- Total flows: ${graph.flows.size}`);
|
|
208
|
+
lines.push(`- Independent flows: ${graph.independentFlows.length}`);
|
|
209
|
+
lines.push(`- Execution waves: ${graph.executionOrder.length}`);
|
|
210
|
+
lines.push('');
|
|
211
|
+
lines.push('Execution Order:');
|
|
212
|
+
graph.executionOrder.forEach((wave, index) => {
|
|
213
|
+
const waveNames = wave.map((flowId) => {
|
|
214
|
+
const flow = graph.flows.get(flowId);
|
|
215
|
+
return flow?.name || flowId;
|
|
216
|
+
});
|
|
217
|
+
lines.push(` Wave ${index + 1}: ${waveNames.join(', ')}`);
|
|
218
|
+
});
|
|
219
|
+
lines.push('');
|
|
220
|
+
lines.push('Dependencies:');
|
|
221
|
+
graph.dependencies.forEach((deps, flowId) => {
|
|
222
|
+
if (deps.length > 0) {
|
|
223
|
+
const flow = graph.flows.get(flowId);
|
|
224
|
+
const flowName = flow?.name || flowId;
|
|
225
|
+
const depNames = deps.map((depId) => {
|
|
226
|
+
const depFlow = graph.flows.get(depId);
|
|
227
|
+
return depFlow?.name || depId;
|
|
228
|
+
});
|
|
229
|
+
lines.push(` ${flowName} depends on: ${depNames.join(', ')}`);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
return lines.join('\n');
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
exports.FlowDependencyAnalyzer = FlowDependencyAnalyzer;
|
|
236
|
+
//# sourceMappingURL=FlowDependencyAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlowDependencyAnalyzer.js","sourceRoot":"","sources":["../../src/managers/FlowDependencyAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FlowMetadata } from '../models/FlowMetadata';
|
|
2
|
+
import { ProposedToolCall } from '../models/ProposedToolCall';
|
|
3
|
+
export interface ProjectFile {
|
|
4
|
+
path: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
export interface GeneratedProject {
|
|
8
|
+
files: ProjectFile[];
|
|
9
|
+
summary: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class ProjectStructureGenerator {
|
|
12
|
+
private readonly codeGenerator;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Generates a complete Playwright project structure with dependency management
|
|
16
|
+
*/
|
|
17
|
+
generateProject(flowsWithToolCalls: Array<{
|
|
18
|
+
metadata: FlowMetadata;
|
|
19
|
+
toolCalls: ProposedToolCall<any>[];
|
|
20
|
+
}>): Promise<GeneratedProject>;
|
|
21
|
+
/**
|
|
22
|
+
* Generates the playwright.config.ts file with project dependencies
|
|
23
|
+
*/
|
|
24
|
+
private generatePlaywrightConfig;
|
|
25
|
+
/**
|
|
26
|
+
* Generates a single project configuration
|
|
27
|
+
*/
|
|
28
|
+
private generateProjectConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Gets project dependencies for a given flow
|
|
31
|
+
*/
|
|
32
|
+
private getProjectDependencies;
|
|
33
|
+
/**
|
|
34
|
+
* Generates test files for all flows
|
|
35
|
+
*/
|
|
36
|
+
private generateTestFiles;
|
|
37
|
+
/**
|
|
38
|
+
* Generates package.json
|
|
39
|
+
*/
|
|
40
|
+
private generatePackageJson;
|
|
41
|
+
/**
|
|
42
|
+
* Generates README.md
|
|
43
|
+
*/
|
|
44
|
+
private generateReadme;
|
|
45
|
+
/**
|
|
46
|
+
* Generates a summary of the generated project
|
|
47
|
+
*/
|
|
48
|
+
private generateProjectSummary;
|
|
49
|
+
/**
|
|
50
|
+
* Gets a project name for a flow
|
|
51
|
+
*/
|
|
52
|
+
private getProjectName;
|
|
53
|
+
/**
|
|
54
|
+
* Gets a test file name for a flow
|
|
55
|
+
*/
|
|
56
|
+
private getTestFileName;
|
|
57
|
+
/**
|
|
58
|
+
* Prettifies generated code
|
|
59
|
+
*/
|
|
60
|
+
private prettifyCode;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=ProjectStructureGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectStructureGenerator.d.ts","sourceRoot":"","sources":["../../src/managers/ProjectStructureGenerator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAQ9D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgB;;IAM9C;;OAEG;IACU,eAAe,CAC1B,kBAAkB,EAAE,KAAK,CAAC;QACxB,QAAQ,EAAE,YAAY,CAAC;QACvB,SAAS,EAAE,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;KACpC,CAAC,GACD,OAAO,CAAC,gBAAgB,CAAC;IAmC5B;;OAEG;YACW,wBAAwB;IAkCtC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAwB7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAW9B;;OAEG;YACW,iBAAiB;IAwB/B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAqB3B;;OAEG;IACH,OAAO,CAAC,cAAc;IA+CtB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAsB9B;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;YACW,YAAY;CAe3B"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// src/managers/ProjectStructureGenerator.ts
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.ProjectStructureGenerator = void 0;
|
|
5
|
+
const FlowDependencyAnalyzer_1 = require("./FlowDependencyAnalyzer");
|
|
6
|
+
const CodeGenerator_1 = require("./CodeGenerator");
|
|
7
|
+
const main_1 = require("../main");
|
|
8
|
+
class ProjectStructureGenerator {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.codeGenerator = new CodeGenerator_1.CodeGenerator();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generates a complete Playwright project structure with dependency management
|
|
14
|
+
*/
|
|
15
|
+
async generateProject(flowsWithToolCalls) {
|
|
16
|
+
// Analyze dependencies
|
|
17
|
+
const dependencyGraph = FlowDependencyAnalyzer_1.FlowDependencyAnalyzer.analyzeDependencies(flowsWithToolCalls.map((f) => f.metadata));
|
|
18
|
+
const files = [];
|
|
19
|
+
// Generate playwright.config.ts
|
|
20
|
+
files.push({
|
|
21
|
+
path: 'playwright.config.ts',
|
|
22
|
+
content: await this.generatePlaywrightConfig(dependencyGraph),
|
|
23
|
+
});
|
|
24
|
+
// Generate individual test files
|
|
25
|
+
const testFiles = await this.generateTestFiles(flowsWithToolCalls);
|
|
26
|
+
files.push(...testFiles);
|
|
27
|
+
// Generate package.json if needed
|
|
28
|
+
files.push({
|
|
29
|
+
path: 'package.json',
|
|
30
|
+
content: this.generatePackageJson(),
|
|
31
|
+
});
|
|
32
|
+
// Generate README
|
|
33
|
+
files.push({
|
|
34
|
+
path: 'README.md',
|
|
35
|
+
content: this.generateReadme(dependencyGraph),
|
|
36
|
+
});
|
|
37
|
+
const summary = this.generateProjectSummary(dependencyGraph);
|
|
38
|
+
return { files, summary };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generates the playwright.config.ts file with project dependencies
|
|
42
|
+
*/
|
|
43
|
+
async generatePlaywrightConfig(graph) {
|
|
44
|
+
const projects = [];
|
|
45
|
+
// Create a project for each flow (both single and multiple flows in waves get individual projects)
|
|
46
|
+
graph.executionOrder.forEach((wave) => {
|
|
47
|
+
wave.forEach((flowId) => {
|
|
48
|
+
const flow = graph.flows.get(flowId);
|
|
49
|
+
const projectName = this.getProjectName(flow);
|
|
50
|
+
const dependencies = this.getProjectDependencies(flowId, graph);
|
|
51
|
+
projects.push(this.generateProjectConfig(projectName, flow, dependencies));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
const config = `import { defineConfig, devices } from 'donobu';
|
|
55
|
+
|
|
56
|
+
export default defineConfig({
|
|
57
|
+
testDir: './tests',
|
|
58
|
+
projects: [
|
|
59
|
+
${projects.map((p) => ' ' + p).join(',\n')}
|
|
60
|
+
],
|
|
61
|
+
reporter: [
|
|
62
|
+
["github"],
|
|
63
|
+
["json", { outputFile: "test-results/playwright-report.json" }],
|
|
64
|
+
],
|
|
65
|
+
});`;
|
|
66
|
+
return this.prettifyCode(config);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generates a single project configuration
|
|
70
|
+
*/
|
|
71
|
+
generateProjectConfig(projectName, flow, dependencies) {
|
|
72
|
+
const testMatch = `tests/${this.getTestFileName(flow)}`;
|
|
73
|
+
const deps = dependencies.length > 0
|
|
74
|
+
? `\n dependencies: [${dependencies.map((d) => `'${d}'`).join(', ')}],`
|
|
75
|
+
: '';
|
|
76
|
+
// Get device name from flow config, default to 'Desktop Chromium'
|
|
77
|
+
const deviceName = flow.browser?.using?.type === 'device'
|
|
78
|
+
? flow.browser.using.deviceName || 'Desktop Chromium'
|
|
79
|
+
: 'Desktop Chromium';
|
|
80
|
+
return `{
|
|
81
|
+
name: '${projectName}',
|
|
82
|
+
testMatch: '${testMatch}',${deps}
|
|
83
|
+
use: { ...devices['${deviceName}'] },
|
|
84
|
+
}`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gets project dependencies for a given flow
|
|
88
|
+
*/
|
|
89
|
+
getProjectDependencies(flowId, graph) {
|
|
90
|
+
const dependencies = graph.dependencies.get(flowId) || [];
|
|
91
|
+
return dependencies.map((depId) => {
|
|
92
|
+
const depFlow = graph.flows.get(depId);
|
|
93
|
+
return this.getProjectName(depFlow);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Generates test files for all flows
|
|
98
|
+
*/
|
|
99
|
+
async generateTestFiles(flowsWithToolCalls) {
|
|
100
|
+
const files = [];
|
|
101
|
+
for (const { metadata, toolCalls } of flowsWithToolCalls) {
|
|
102
|
+
const fileName = this.getTestFileName(metadata);
|
|
103
|
+
const content = await this.codeGenerator.getFlowAsPlaywrightScript(metadata, toolCalls);
|
|
104
|
+
files.push({
|
|
105
|
+
path: `tests/${fileName}`,
|
|
106
|
+
content,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return files;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Generates package.json
|
|
113
|
+
*/
|
|
114
|
+
generatePackageJson() {
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
name: 'generated-playwright-tests',
|
|
117
|
+
version: '1.0.0',
|
|
118
|
+
description: 'Generated Playwright tests with flow dependencies',
|
|
119
|
+
scripts: {
|
|
120
|
+
test: 'playwright test',
|
|
121
|
+
'test:headed': 'playwright test --headed',
|
|
122
|
+
'test:debug': 'playwright test --debug',
|
|
123
|
+
},
|
|
124
|
+
devDependencies: {
|
|
125
|
+
'@playwright/test': '^1.40.0',
|
|
126
|
+
donobu: 'latest',
|
|
127
|
+
},
|
|
128
|
+
}, null, 2);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Generates README.md
|
|
132
|
+
*/
|
|
133
|
+
generateReadme(graph) {
|
|
134
|
+
const dependencySummary = FlowDependencyAnalyzer_1.FlowDependencyAnalyzer.getDependencySummary(graph);
|
|
135
|
+
return `# Generated Playwright Tests
|
|
136
|
+
|
|
137
|
+
This project contains automatically generated Playwright tests with proper dependency management.
|
|
138
|
+
|
|
139
|
+
## Installation
|
|
140
|
+
|
|
141
|
+
\`\`\`bash
|
|
142
|
+
npm install
|
|
143
|
+
npx playwright install
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
## Running Tests
|
|
147
|
+
|
|
148
|
+
\`\`\`bash
|
|
149
|
+
# Run all tests respecting dependencies
|
|
150
|
+
npm test
|
|
151
|
+
|
|
152
|
+
# Run tests in headed mode
|
|
153
|
+
npm run test:headed
|
|
154
|
+
|
|
155
|
+
# Debug tests
|
|
156
|
+
npm run test:debug
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
## Test Dependencies
|
|
160
|
+
|
|
161
|
+
${dependencySummary}
|
|
162
|
+
|
|
163
|
+
## Notes
|
|
164
|
+
|
|
165
|
+
- Tests are organized into Playwright projects to manage dependencies
|
|
166
|
+
- Each flow runs in the correct order based on browser state dependencies
|
|
167
|
+
- Independent flows can run in parallel within the same wave
|
|
168
|
+
- Browser state is automatically managed between dependent flows
|
|
169
|
+
|
|
170
|
+
## Generated Files
|
|
171
|
+
|
|
172
|
+
- \`playwright.config.ts\` - Playwright configuration with project dependencies
|
|
173
|
+
- \`tests/\` - Individual test files for each flow
|
|
174
|
+
- \`package.json\` - Project dependencies and scripts
|
|
175
|
+
`;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Generates a summary of the generated project
|
|
179
|
+
*/
|
|
180
|
+
generateProjectSummary(graph) {
|
|
181
|
+
const lines = [];
|
|
182
|
+
lines.push('Generated Playwright Project Summary:');
|
|
183
|
+
lines.push(`- ${graph.flows.size} test files generated`);
|
|
184
|
+
lines.push(`- ${graph.executionOrder.length} execution waves configured`);
|
|
185
|
+
lines.push(`- ${graph.independentFlows.length} independent flows`);
|
|
186
|
+
const dependentFlows = graph.flows.size - graph.independentFlows.length;
|
|
187
|
+
if (dependentFlows > 0) {
|
|
188
|
+
lines.push(`- ${dependentFlows} flows with dependencies`);
|
|
189
|
+
}
|
|
190
|
+
lines.push('');
|
|
191
|
+
lines.push('To run the tests:');
|
|
192
|
+
lines.push('1. npm install');
|
|
193
|
+
lines.push('2. npx playwright install');
|
|
194
|
+
lines.push('3. npm test');
|
|
195
|
+
return lines.join('\n');
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Gets a project name for a flow
|
|
199
|
+
*/
|
|
200
|
+
getProjectName(flow) {
|
|
201
|
+
if (flow.name) {
|
|
202
|
+
return flow.name.replace(/[^a-zA-Z0-9-_]/g, '-');
|
|
203
|
+
}
|
|
204
|
+
return `flow-${flow.id.substring(0, 8)}`;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Gets a test file name for a flow
|
|
208
|
+
*/
|
|
209
|
+
getTestFileName(flow) {
|
|
210
|
+
const projectName = this.getProjectName(flow);
|
|
211
|
+
return `${projectName}.spec.ts`;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Prettifies generated code
|
|
215
|
+
*/
|
|
216
|
+
async prettifyCode(code) {
|
|
217
|
+
try {
|
|
218
|
+
const prettier = require('prettier');
|
|
219
|
+
return prettier.format(code, {
|
|
220
|
+
parser: 'typescript',
|
|
221
|
+
semi: true,
|
|
222
|
+
singleQuote: true,
|
|
223
|
+
trailingComma: 'es5',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
main_1.appLogger.error('Failed to format code with Prettier:', error);
|
|
228
|
+
// If prettier fails, return the original code
|
|
229
|
+
return code;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.ProjectStructureGenerator = ProjectStructureGenerator;
|
|
234
|
+
//# sourceMappingURL=ProjectStructureGenerator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectStructureGenerator.js","sourceRoot":"","sources":["../../src/managers/ProjectStructureGenerator.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;AAI5C,qEAGkC;AAClC,mDAAgD;AAChD,kCAAoC;AAYpC,MAAa,yBAAyB;IAGpC;QACE,IAAI,CAAC,aAAa,GAAG,IAAI,6BAAa,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,eAAe,CAC1B,kBAGE;QAEF,uBAAuB;QACvB,MAAM,eAAe,GAAG,+CAAsB,CAAC,mBAAmB,CAChE,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC1C,CAAC;QAEF,MAAM,KAAK,GAAkB,EAAE,CAAC;QAEhC,gCAAgC;QAChC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,MAAM,IAAI,CAAC,wBAAwB,CAAC,eAAe,CAAC;SAC9D,CAAC,CAAC;QAEH,iCAAiC;QACjC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAEzB,kCAAkC;QAClC,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE;SACpC,CAAC,CAAC;QAEH,kBAAkB;QAClB,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC;SAC9C,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;QAE7D,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB,CACpC,KAAsB;QAEtB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAE9B,mGAAmG;QACnG,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACpC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACtB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;gBACtC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAEhE,QAAQ,CAAC,IAAI,CACX,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,IAAI,EAAE,YAAY,CAAC,CAC5D,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG;;;;;EAKjB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;IAMzC,CAAC;QAED,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACK,qBAAqB,CAC3B,WAAmB,EACnB,IAAkB,EAClB,YAAsB;QAEtB,MAAM,SAAS,GAAG,SAAS,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,IAAI,GACR,YAAY,CAAC,MAAM,GAAG,CAAC;YACrB,CAAC,CAAC,0BAA0B,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC5E,CAAC,CAAC,EAAE,CAAC;QAET,kEAAkE;QAClE,MAAM,UAAU,GACd,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,KAAK,QAAQ;YACpC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,kBAAkB;YACrD,CAAC,CAAC,kBAAkB,CAAC;QAEzB,OAAO;eACI,WAAW;oBACN,SAAS,KAAK,IAAI;2BACX,UAAU;MAC/B,CAAC;IACL,CAAC;IAED;;OAEG;IACK,sBAAsB,CAC5B,MAAc,EACd,KAAsB;QAEtB,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC1D,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC;YACxC,OAAO,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,iBAAiB,CAC7B,kBAGE;QAEF,MAAM,KAAK,GAAkB,EAAE,CAAC;QAEhC,KAAK,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,kBAAkB,EAAE,CAAC;YACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,yBAAyB,CAChE,QAAQ,EACR,SAAS,CACV,CAAC;YAEF,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,SAAS,QAAQ,EAAE;gBACzB,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACK,mBAAmB;QACzB,OAAO,IAAI,CAAC,SAAS,CACnB;YACE,IAAI,EAAE,4BAA4B;YAClC,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,mDAAmD;YAChE,OAAO,EAAE;gBACP,IAAI,EAAE,iBAAiB;gBACvB,aAAa,EAAE,0BAA0B;gBACzC,YAAY,EAAE,yBAAyB;aACxC;YACD,eAAe,EAAE;gBACf,kBAAkB,EAAE,SAAS;gBAC7B,MAAM,EAAE,QAAQ;aACjB;SACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,KAAsB;QAC3C,MAAM,iBAAiB,GACrB,+CAAsB,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAErD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BT,iBAAiB;;;;;;;;;;;;;;CAclB,CAAC;IACA,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,KAAsB;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,uBAAuB,CAAC,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,MAAM,6BAA6B,CAAC,CAAC;QAC1E,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,gBAAgB,CAAC,MAAM,oBAAoB,CAAC,CAAC;QAEnE,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,gBAAgB,CAAC,MAAM,CAAC;QACxE,IAAI,cAAc,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,KAAK,cAAc,0BAA0B,CAAC,CAAC;QAC5D,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAChC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE1B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,IAAkB;QACvC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACnD,CAAC;QACD,OAAO,QAAQ,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAAkB;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,GAAG,WAAW,UAAU,CAAC;IAClC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,IAAY;QACrC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;YACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE;gBAC3B,MAAM,EAAE,YAAY;gBACpB,IAAI,EAAE,IAAI;gBACV,WAAW,EAAE,IAAI;gBACjB,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAS,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;YAC/D,8CAA8C;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAlSD,8DAkSC"}
|
|
@@ -6,12 +6,58 @@ interface ExtractPaymentProviderToolCoreParameters {
|
|
|
6
6
|
}
|
|
7
7
|
interface ExtractPaymentProviderToolGptParameters extends BaseToolGptParameters, ExtractPaymentProviderToolCoreParameters {
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* This tool scans the current web page for publishable payment
|
|
11
|
+
* provider credentials the current page's inline `<script>` blocks.
|
|
12
|
+
*
|
|
13
|
+
* ### Supported providers
|
|
14
|
+
* | Provider | Regex | Example |
|
|
15
|
+
* |----------|-----------------------------------|----------------|
|
|
16
|
+
* | Stripe | `/pk_(test\|live)_[A-Za-z0-9]+/i` | `pk_test_51M…` |
|
|
17
|
+
* | PayPal | `/A[A-Za-z0-9-_]{75,}/i` | `AUGIH…` |
|
|
18
|
+
*
|
|
19
|
+
* On **success** the tool returns a JSON object containing any discovered keys and the
|
|
20
|
+
* URL of the page that was scanned. If **no keys** are found, `isSuccessful` is set to
|
|
21
|
+
* `false` and a short error string is provided.
|
|
22
|
+
*
|
|
23
|
+
* ```json
|
|
24
|
+
* {
|
|
25
|
+
* "stripe": ["pk_test_123", "pk_live_456"],
|
|
26
|
+
* "paypal": ["AUGIH…"],
|
|
27
|
+
* "checkoutPageUrl": "https://shop.example.com/checkout"
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
9
31
|
export declare class ExtractPaymentProviderKeyTool extends Tool<ExtractPaymentProviderToolCoreParameters, ExtractPaymentProviderToolGptParameters> {
|
|
10
32
|
static readonly NAME = "extractPaymentProviderKey";
|
|
33
|
+
private static readonly EXCLUDED_PATTERNS;
|
|
34
|
+
private static readonly PAYPAL_CLIENT_ID_PATTERN;
|
|
35
|
+
private static readonly PAYPAL_CONTEXT_INDICATORS;
|
|
11
36
|
constructor();
|
|
12
37
|
call(context: ToolCallContext, _parameters: ExtractPaymentProviderToolCoreParameters): Promise<ToolCallResult>;
|
|
13
38
|
callFromGpt(context: ToolCallContext, parameters: ExtractPaymentProviderToolGptParameters): Promise<ToolCallResult>;
|
|
14
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Extract potential PayPal client ID candidates from script content
|
|
41
|
+
*/
|
|
42
|
+
private extractPayPalCandidates;
|
|
43
|
+
/**
|
|
44
|
+
* Enhanced validation for PayPal client IDs
|
|
45
|
+
*/
|
|
46
|
+
private isValidPayPalClientId;
|
|
47
|
+
/**
|
|
48
|
+
* Check for strong PayPal contextual indicators near the candidate key
|
|
49
|
+
*/
|
|
50
|
+
private hasStrongPayPalContext;
|
|
51
|
+
/**
|
|
52
|
+
* Check if the candidate appears in a structured context (assignments, objects, etc.)
|
|
53
|
+
*/
|
|
54
|
+
private hasStructuredPayPalContext;
|
|
55
|
+
/**
|
|
56
|
+
* Collects text bodies for:
|
|
57
|
+
* - all inline <script> blocks
|
|
58
|
+
* - every <script src="…"> that is present in the DOM
|
|
59
|
+
*/
|
|
60
|
+
private static getAllScriptSources;
|
|
15
61
|
}
|
|
16
62
|
export {};
|
|
17
63
|
//# sourceMappingURL=ExtractPaymentProviderKeyTool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExtractPaymentProviderKeyTool.d.ts","sourceRoot":"","sources":["../../src/tools/ExtractPaymentProviderKeyTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"ExtractPaymentProviderKeyTool.d.ts","sourceRoot":"","sources":["../../src/tools/ExtractPaymentProviderKeyTool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAGxE,UAAU,wCAAwC;CAAG;AACrD,UAAU,uCACR,SAAQ,qBAAqB,EAC3B,wCAAwC;CAAG;AAE/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,6BAA8B,SAAQ,IAAI,CACrD,wCAAwC,EACxC,uCAAuC,CACxC;IACC,gBAAuB,IAAI,+BAA+B;IAG1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAmBvC;IAGF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAA6B;IAG7E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,yBAAyB,CAW/C;;IAWoB,IAAI,CACxB,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,wCAAwC,GACpD,OAAO,CAAC,cAAc,CAAC;IAyDJ,WAAW,CAC/B,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,uCAAuC,GAClD,OAAO,CAAC,cAAc,CAAC;IAI1B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAgB/B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA+B7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAqB9B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA8BlC;;;;OAIG;mBACkB,mBAAmB;CAkCzC"}
|