Skip to content

chore: release v0.0.14 #566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 126 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
b63701c
feat: emit list false on discard
RohitR311 Apr 25, 2025
3160ee8
feat: stop pagination and limit mode on discard
RohitR311 Apr 25, 2025
fa34500
feat: set pagination socket event false
RohitR311 Apr 25, 2025
9510336
chore: add bug report issue template
amhsirak Apr 26, 2025
cbc77f0
fix: add page closed condition for highlighter
amhsirak Apr 26, 2025
2dbec99
feat: _ server name
amhsirak Apr 26, 2025
84bad0c
feat: serve frontend
amhsirak Apr 26, 2025
6b86d35
feat: backend proxy
amhsirak Apr 26, 2025
a67d93a
feat: handle websocket connections
amhsirak Apr 26, 2025
69aedcb
chore: cleanup stale config
amhsirak Apr 26, 2025
50ec361
chore: cleanup stale config
amhsirak Apr 26, 2025
235d731
feat: app api
amhsirak Apr 26, 2025
0a88f24
Merge pull request #557 from getmaxun/issue-template
amhsirak Apr 26, 2025
7fe982a
feat: allow multiple capture action execution
RohitR311 Apr 27, 2025
c6266fd
feat: emit action type
RohitR311 Apr 27, 2025
cd4820f
feat: serialize data by action type
RohitR311 Apr 27, 2025
bd5087e
feat: run and abort categorize data by action type
RohitR311 Apr 27, 2025
35e7778
feat: schedule categorize data by action type
RohitR311 Apr 27, 2025
00ef3ba
feat: record api categorize data by action type
RohitR311 Apr 27, 2025
6243563
feat: track browser actions state
RohitR311 Apr 27, 2025
15d4fce
feat: prune session interval
amhsirak Apr 27, 2025
1e3e159
feat: error log
amhsirak Apr 27, 2025
2ec59ad
fix: handle ts error
amhsirak Apr 27, 2025
e365104
feat: -rm error handling
amhsirak Apr 27, 2025
f805608
feat: add meta content
HarshGID100 Apr 28, 2025
0de597d
Merge pull request #565 from HarshGID100/patch-1
amhsirak Apr 28, 2025
d1d9fea
feat: add wait until timeout state for navigation
amhsirak Apr 28, 2025
ce0242e
feat: add wait until timeout state for navigation
amhsirak Apr 28, 2025
6376fd6
feat: reset interpret log list screenshot
RohitR311 Apr 28, 2025
b5c5ed7
feat: check action exists in workflow
RohitR311 Apr 28, 2025
42b56d7
feat: emit recording editor actions by type
RohitR311 Apr 28, 2025
82d6f70
feat: revamp output preview log ui
RohitR311 Apr 28, 2025
a00e69e
feat: change scrape schema merge logic
RohitR311 Apr 28, 2025
a7771cf
feat: memoize handle url change
RohitR311 Apr 28, 2025
f975862
feat: revamp run content ui
RohitR311 Apr 28, 2025
8d06146
feat: add translations for run content
RohitR311 Apr 28, 2025
4ed3160
feat: emit socket events for stopping
RohitR311 Apr 28, 2025
5be1172
feat: destroy browser fallback fix
RohitR311 Apr 28, 2025
863603f
feat: pass browser id
RohitR311 Apr 28, 2025
0e250af
Merge pull request #570 from getmaxun/fallback-fix
amhsirak Apr 29, 2025
6846b11
Merge pull request #569 from getmaxun/navigation-fix
amhsirak Apr 29, 2025
6eec79e
Merge pull request #560 from getmaxun/nginx
amhsirak Apr 29, 2025
80be828
Merge pull request #558 from getmaxun/browser-crash-error
amhsirak Apr 29, 2025
2ffbdc7
feat: revamp gsheet integration multiple actions
RohitR311 Apr 29, 2025
109afff
feat: revamp airtable integration multiple actions
RohitR311 Apr 29, 2025
882b25c
feat: correct key used when checking unconfirmed list fields
RohitR311 Apr 29, 2025
01ab958
feat: replace banned Function type with an explicit signature
RohitR311 Apr 29, 2025
c7e3a66
feat: maxlen 0 if field not exist
RohitR311 Apr 29, 2025
27ea808
order according to updatedAt
AmitChauhan63390 Apr 30, 2025
6a84323
feat: order on updated at, rerender on retrain
RohitR311 Apr 30, 2025
f1d0cbd
feat: rm other actions logic
RohitR311 Apr 30, 2025
2f4db4e
Merge pull request #556 from getmaxun/discard-fix
amhsirak Apr 30, 2025
b4e3ccd
Merge branch 'develop' into all-record
amhsirak Apr 30, 2025
f1c1488
fix: lint
amhsirak Apr 30, 2025
0c5e98c
fix: lint
amhsirak Apr 30, 2025
d0f284c
chore: -rm unused imports
amhsirak Apr 30, 2025
f65dda0
feat: -rm download all json
amhsirak Apr 30, 2025
302ec00
feat: -rm horizontal view
amhsirak Apr 30, 2025
e5f63be
feat: -rm vertical view
amhsirak Apr 30, 2025
9eeb367
feat: -rm box
amhsirak Apr 30, 2025
458392d
feat: -rm horizontal view from screenshots
amhsirak Apr 30, 2025
db890e0
feat: -rm vertical view from screenshots
amhsirak Apr 30, 2025
e6a7fdf
feat: -rm box
amhsirak Apr 30, 2025
2b04634
feat: -rm unused icons
amhsirak Apr 30, 2025
c202a50
feat: -rm icons for capture text and list
amhsirak Apr 30, 2025
cf5be61
feat: -rm icons
amhsirak Apr 30, 2025
47ed5ce
feat: -rm icons
amhsirak Apr 30, 2025
7c7116a
feat: -rm captured data
amhsirak Apr 30, 2025
1f06bcd
feat: -rm captured screenshots
amhsirak Apr 30, 2025
392a5fd
feat: rm workflow in progress logic
RohitR311 Apr 30, 2025
624d7fc
Merge branch 'all-record' of https://github.com/getmaxun/maxun into a…
RohitR311 Apr 30, 2025
9bc9815
feat: -rm chips
amhsirak Apr 30, 2025
94fecc1
feat: -rm download all json
amhsirak Apr 30, 2025
9c57824
feat: -rm download all json
amhsirak Apr 30, 2025
decf14a
fix: cleanup
amhsirak Apr 30, 2025
b72d0dc
chore: remove unused import
amhsirak Apr 30, 2025
43b7a7d
feat: rm view mode logic
RohitR311 Apr 30, 2025
02a150d
feat: paginate capture screenshots
RohitR311 Apr 30, 2025
b83fcb2
feat: rm left space
RohitR311 Apr 30, 2025
db25627
feat: change translations
RohitR311 Apr 30, 2025
5cd756c
feat: rm card componenent
RohitR311 Apr 30, 2025
3b618d8
feat: rm screenshot items chip
RohitR311 Apr 30, 2025
6419d31
feat: buttons ui change, rm render expand
RohitR311 Apr 30, 2025
daa9779
feat: rm unnecessray imports
RohitR311 Apr 30, 2025
eed8ff3
Merge pull request #574 from getmaxun/all-record-ui
RohitR311 Apr 30, 2025
7b6de7d
feat: fix download ss logic
RohitR311 Apr 30, 2025
f5df4c9
feat: rm other page and data
RohitR311 Apr 30, 2025
e09e794
feat: show tabs only if multiple actions
RohitR311 Apr 30, 2025
6e23051
date format changed
AmitChauhan63390 Apr 30, 2025
406def4
Update RecordingsTable.tsx
AmitChauhan63390 Apr 30, 2025
60176fe
Merge pull request #562 from getmaxun/all-record
amhsirak Apr 30, 2025
9be9057
feat: wrap limit title text
RohitR311 Apr 30, 2025
53d992e
feat: multiple capture list limit
RohitR311 May 1, 2025
1535c05
feat: edit update recording
RohitR311 May 1, 2025
24f3d50
feat: edit multiple list limits, change landing url
RohitR311 May 1, 2025
5a47fa4
fix: add `maxun-core` in deps
amhsirak May 1, 2025
5e62c9a
Merge pull request #580 from getmaxun/fix-core
amhsirak May 1, 2025
2172fa7
feat: add integrations, store multiple actions data
RohitR311 May 2, 2025
4ffce7b
feat: export browserstep, add update limit step type
RohitR311 May 6, 2025
6f047be
feat: update list step limit
RohitR311 May 6, 2025
47a9f15
Merge pull request #563 from getmaxun/session-fix
amhsirak May 6, 2025
da8fda0
Merge pull request #572 from AmitChauhan63390/master
amhsirak May 6, 2025
1533899
Merge pull request #573 from getmaxun/order-robots
amhsirak May 6, 2025
323a610
Merge pull request #577 from getmaxun/text-overflow
amhsirak May 6, 2025
5e404f8
Merge pull request #579 from getmaxun/multiple-limit
amhsirak May 6, 2025
a1986a9
Merge pull request #582 from getmaxun/apirun-fix
amhsirak May 6, 2025
48a3fcc
feat: create PgStoreOptions interface
amhsirak May 6, 2025
63ad0f9
feat: session store w PgStoreOptions
amhsirak May 6, 2025
9433860
feat: app.use session store
amhsirak May 6, 2025
ae1dda3
feat: use SESSION_SECRET env var
amhsirak May 6, 2025
7fdc38a
feat: SESSION_SECRET
amhsirak May 6, 2025
da8406c
feat: add SESSION_SECRET
amhsirak May 6, 2025
456c5cc
feat: SESSION_SECRET note
amhsirak May 6, 2025
fcbc067
Merge pull request #585 from getmaxun/session-env
amhsirak May 6, 2025
1022ca6
feat: emit extracted list data from remote browser
RohitR311 May 7, 2025
f43b860
feat: get list extracted data
RohitR311 May 7, 2025
ec36df7
feat: add update list data browser step
RohitR311 May 7, 2025
0a1704e
feat: display browser step data
RohitR311 May 7, 2025
817c725
feat: add mode editor
RohitR311 May 7, 2025
38430ec
feat: add mode param options
RohitR311 May 7, 2025
8287da5
Merge pull request #584 from getmaxun/store-ts
amhsirak May 7, 2025
8c1e9f3
Merge pull request #583 from getmaxun/faster-preview
amhsirak May 8, 2025
faab013
chore: v0.0.14
amhsirak May 8, 2025
f746aed
chore: v0.0.16 core
amhsirak May 8, 2025
f5d8674
chore: use 0.0.16 core
amhsirak May 8, 2025
4d102f1
Merge pull request #588 from getmaxun/pre-release-14
amhsirak May 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Bug Report
description: Report a bug to help us improve
title: "[Bug]: "
labels: [bug]
assignees: []

body:
- type: dropdown
id: environment
attributes:
label: Where are you using the app?
options:
- Cloud (Hosted by Us)
- Self-Hosted (OSS) with Docker
- Self-Hosted (OSS) without Docker
validations:
required: true

- type: input
id: app_version
attributes:
label: App Version
description: Enter the version number you are using (if known).
placeholder: "e.g., v1.2.3"
validations:
required: false

- type: input
id: browser
attributes:
label: Browser
description: Which browser are you using?
placeholder: "e.g., Chrome 124, Firefox 115, Safari 17"
validations:
required: true

- type: input
id: operating_system
attributes:
label: Operating System
description: Your operating system and version.
placeholder: "e.g., Windows 11, macOS Sonoma, Ubuntu 22.04"
validations:
required: true

- type: textarea
id: steps_to_reproduce
attributes:
label: Steps to Reproduce
description: How can we reproduce the problem?
placeholder: |
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
validations:
required: true

- type: textarea
id: expected_behavior
attributes:
label: Expected Behavior
description: What did you expect to happen instead?
validations:
required: true

- type: textarea
id: actual_behavior
attributes:
label: Actual Behavior
description: What actually happened?
validations:
required: true

- type: textarea
id: logs
attributes:
label: Relevant Logs or Screenshots
description: Please paste any logs, screenshots, or console errors if available.
placeholder: "Paste logs or upload screenshots."
validations:
required: false

- type: textarea
id: additional_context
attributes:
label: Additional Context
description: Anything else we should know?
validations:
required: false
2 changes: 2 additions & 0 deletions ENVEXAMPLE
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ DB_PASSWORD=postgres # PostgreSQL password
DB_HOST=postgres # Host for PostgreSQL in Docker
DB_PORT=5432 # Port for PostgreSQL (default: 5432)
ENCRYPTION_KEY=f4d5e6a7b8c9d0e1f23456789abcdef01234567890abcdef123456789abcdef0 # Key for encrypting sensitive data (passwords and proxies)
SESSION_SECRET=maxun_session # A strong, random string used to sign session cookies. Recommended to define your own session secret to avoid session hijacking.

MINIO_ENDPOINT=minio # MinIO endpoint in Docker
MINIO_PORT=9000 # Port for MinIO (default: 9000)
MINIO_CONSOLE_PORT=9001 # Web UI Port for MinIO (default: 9001)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ You can access the frontend at http://localhost:5173/ and backend at http://loca
| `DB_HOST` | Yes | Host address where the Postgres database server is running. | Database connection will fail. |
| `DB_PORT` | Yes | Port number used to connect to the Postgres database server. | Database connection will fail. |
| `ENCRYPTION_KEY` | Yes | Key used for encrypting sensitive data (proxies, passwords). | Encryption functionality will not work. |
| `SESSION_SECRET` | No | A strong, random string used to sign session cookies | Uses default secret. Recommended to define your own session secret to avoid session hijacking. |
| `MINIO_ENDPOINT` | Yes | Endpoint URL for MinIO, to store Robot Run Screenshots. | Connection to MinIO storage will fail. |
| `MINIO_PORT` | Yes | Port number for MinIO service. | Connection to MinIO storage will fail. |
| `MINIO_CONSOLE_PORT` | No | Port number for MinIO WebUI service. Needed for Docker setup. | Cannot access MinIO Web UI. |
Expand Down
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using Vite"
content="Maxun is an open-source no-code web data extraction platform. Train a robot in 2 minutes to extract data on auto-pilot!"
/>
<link rel="icon" type="image/png" href="src/assets/maxunlogo.png">
<title>Maxun | Open Source No Code Web Data Extraction Platform</title>
Expand Down
2 changes: 1 addition & 1 deletion maxun-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "maxun-core",
"version": "0.0.15",
"version": "0.0.16",
"description": "Core package for Maxun, responsible for data extraction",
"main": "build/index.js",
"typings": "build/index.d.ts",
Expand Down
108 changes: 72 additions & 36 deletions maxun-core/src/interpret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,16 @@ declare global {
* Defines optional intepreter options (passed in constructor)
*/
interface InterpreterOptions {
mode?: string;
maxRepeats: number;
maxConcurrency: number;
serializableCallback: (output: any) => (void | Promise<void>);
binaryCallback: (output: any, mimeType: string) => (void | Promise<void>);
debug: boolean;
debugChannel: Partial<{
activeId: Function,
debugMessage: Function,
activeId: (id: number) => void,
debugMessage: (msg: string) => void,
setActionType: (type: string) => void,
}>
}

Expand Down Expand Up @@ -377,12 +379,20 @@ export default class Interpreter extends EventEmitter {
*/
const wawActions: Record<CustomFunctions, (...args: any[]) => void> = {
screenshot: async (params: PageScreenshotOptions) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('screenshot');
}

const screenshotBuffer = await page.screenshot({
...params, path: undefined,
});
await this.options.binaryCallback(screenshotBuffer, 'image/png');
},
enqueueLinks: async (selector: string) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('enqueueLinks');
}

const links: string[] = await page.locator(selector)
.evaluateAll(
// @ts-ignore
Expand All @@ -409,55 +419,61 @@ export default class Interpreter extends EventEmitter {
await page.close();
},
scrape: async (selector?: string) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('scrape');
}

await this.ensureScriptsLoaded(page);

const scrapeResults: Record<string, string>[] = await page.evaluate((s) => window.scrape(s ?? null), selector);
await this.options.serializableCallback(scrapeResults);
},

scrapeSchema: async (schema: Record<string, { selector: string; tag: string, attribute: string; shadow: string}>) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('scrapeSchema');
}

if (this.options.mode && this.options.mode === 'editor') {
await this.options.serializableCallback({});
return;
}

await this.ensureScriptsLoaded(page);

const scrapeResult = await page.evaluate((schemaObj) => window.scrapeSchema(schemaObj), schema);

const newResults = Array.isArray(scrapeResult) ? scrapeResult : [scrapeResult];
newResults.forEach((result) => {
Object.entries(result).forEach(([key, value]) => {
const keyExists = this.cumulativeResults.some(
(item) => key in item && item[key] !== undefined
);

if (!keyExists) {
this.cumulativeResults.push({ [key]: value });
}
});
if (!this.cumulativeResults || !Array.isArray(this.cumulativeResults)) {
this.cumulativeResults = [];
}

if (this.cumulativeResults.length === 0) {
this.cumulativeResults.push({});
}

const mergedResult = this.cumulativeResults[0];
const resultToProcess = Array.isArray(scrapeResult) ? scrapeResult[0] : scrapeResult;

Object.entries(resultToProcess).forEach(([key, value]) => {
if (value !== undefined) {
mergedResult[key] = value;
}
});

const mergedResult: Record<string, string>[] = [
Object.fromEntries(
Object.entries(
this.cumulativeResults.reduce((acc, curr) => {
Object.entries(curr).forEach(([key, value]) => {
// If the key doesn't exist or the current value is not undefined, add/update it
if (value !== undefined) {
acc[key] = value;
}
});
return acc;
}, {})
)
)
];

// Log cumulative results after each action
console.log("CUMULATIVE results:", this.cumulativeResults);
console.log("MERGED results:", mergedResult);

await this.options.serializableCallback(mergedResult);
// await this.options.serializableCallback(scrapeResult);

console.log("Updated merged result:", mergedResult);
await this.options.serializableCallback([mergedResult]);
},

scrapeList: async (config: { listSelector: string, fields: any, limit?: number, pagination: any }) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('scrapeList');
}

if (this.options.mode && this.options.mode === 'editor') {
await this.options.serializableCallback({});
return;
}

await this.ensureScriptsLoaded(page);
if (!config.pagination) {
const scrapeResults: Record<string, any>[] = await page.evaluate((cfg) => window.scrapeList(cfg), config);
Expand All @@ -469,6 +485,10 @@ export default class Interpreter extends EventEmitter {
},

scrapeListAuto: async (config: { listSelector: string }) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('scrapeListAuto');
}

await this.ensureScriptsLoaded(page);

const scrapeResults: { selector: string, innerText: string }[] = await page.evaluate((listSelector) => {
Expand All @@ -479,6 +499,10 @@ export default class Interpreter extends EventEmitter {
},

scroll: async (pages?: number) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('scroll');
}

await page.evaluate(async (pagesInternal) => {
for (let i = 1; i <= (pagesInternal ?? 1); i += 1) {
// @ts-ignore
Expand All @@ -488,6 +512,10 @@ export default class Interpreter extends EventEmitter {
},

script: async (code: string) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('script');
}

const AsyncFunction: FunctionConstructor = Object.getPrototypeOf(
async () => { },
).constructor;
Expand All @@ -496,6 +524,10 @@ export default class Interpreter extends EventEmitter {
},

flag: async () => new Promise((res) => {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType('flag');
}

this.emit('flag', page, res);
}),
};
Expand Down Expand Up @@ -526,6 +558,10 @@ export default class Interpreter extends EventEmitter {
const params = !step.args || Array.isArray(step.args) ? step.args : [step.args];
await wawActions[step.action as CustomFunctions](...(params ?? []));
} else {
if (this.options.debugChannel?.setActionType) {
this.options.debugChannel.setActionType(String(step.action));
}

// Implements the dot notation for the "method name" in the workflow
const levels = String(step.action).split('.');
const methodName = levels[levels.length - 1];
Expand Down
47 changes: 13 additions & 34 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -1,45 +1,24 @@
server {
listen 80;
server_name _;

root /var/www/maxun;
index index.html;

# Serve the frontend
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html;
}

location /api {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

# Add timeout configurations
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Add error handling
proxy_intercept_errors on;
error_page 502 503 504 /50x.html;
}

location ~ ^/(record|workflow|storage|auth|integration|proxy|api-docs) {
proxy_pass http://localhost:8080;

# Proxy for backend
location ^/(auth|storage|record|workflow|robot|proxy|api-docs|api)(/|$) {
proxy_pass http://localhost:8080; # change as per your setup
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'keep-alive'; # Ensure connections remain open
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;

# Timeout configurations
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Error handling for these routes
proxy_intercept_errors on;
error_page 502 503 504 /50x.html;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "maxun",
"version": "0.0.13",
"version": "0.0.14",
"author": "Maxun",
"license": "AGPL-3.0-or-later",
"dependencies": {
Expand Down Expand Up @@ -50,7 +50,7 @@
"lodash": "^4.17.21",
"loglevel": "^1.8.0",
"loglevel-plugin-remote": "^0.6.8",
"maxun-core": "^0.0.15",
"maxun-core": "^0.0.16",
"minio": "^8.0.1",
"moment-timezone": "^0.5.45",
"node-cron": "^3.0.3",
Expand Down
Loading