-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Airtop new components #18637
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
Airtop new components #18637
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
WalkthroughAdds a new Airtop app client with HTTP request wrapper and public methods, multiple new action modules for session/window/page operations, polling infrastructure and a concrete "new session created" source, utility helpers, and updates package metadata and dependencies. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Action as Create Session Action
participant App as Airtop App
participant API as Airtop API
User->>Action: Run with profileName, options
Action->>Action: Validate profileName
Action->>App: createSession(data)
App->>API: POST /sessions
API-->>App: 201 { sessionId, status }
App-->>Action: Response
alt saveProfileOnTermination requested and profileName provided
Action->>App: saveProfileOnTermination(sessionId, profileName)
App->>API: POST /sessions/{id}/save-profile
API-->>App: 200 { result }
App-->>Action: Result
end
Action-->>User: Summary: sessionId, status
sequenceDiagram
autonumber
actor User
participant Action as Load/Query/Scrape Action
participant App as Airtop App
participant API as Airtop API
User->>Action: Run with sessionId, windowId, params
Action->>App: loadUrl/queryPage/scrapeContent(...)
App->>API: POST /sessions/{id}/windows/{id}/...
API-->>App: 200 { response }
App-->>Action: Response
Action-->>User: Summary exported
sequenceDiagram
autonumber
participant Source as New Session Created Source
participant Common as Polling Base
participant App as Airtop App
participant API as Airtop API
participant Store as DB (lastTs)
Source->>Store: _getLastTs()
Source->>App: listSessions(limit, offset)
App->>API: GET /sessions
API-->>App: 200 { sessions[] }
App-->>Source: sessions[]
Source->>Source: Filter isNew(dateCreated > lastTs)
loop per new session
Source->>Source: generateMeta(session)
Source-->>Source: emit(event, meta)
Source->>Store: Update lastTs (max)
end
Source->>Store: _setLastTs(lastTs)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
components/airtop/common/utils.mjs (2)
9-22
: Consider adding error handling for initial JSON.parse.If
value
is a string but contains invalid JSON, theJSON.parse
on Line 11 will throw an uncaught error. Consider wrapping it in a try-catch or documenting that callers must provide valid JSON strings.Apply this diff to add error handling:
export function parseObjectEntries(value = {}) { - const obj = typeof value === "string" - ? JSON.parse(value) - : value; + let obj; + if (typeof value === "string") { + try { + obj = JSON.parse(value); + } catch (e) { + throw new Error(`Invalid JSON string provided to parseObjectEntries: ${e.message}`); + } + } else { + obj = value; + } return Object.fromEntries( Object.entries(obj).map(([ key, value, ]) => [ key, optionalParseAsJSON(value), ]), ); }
24-51
: Consider validating the date input.If
dateString
is invalid,new Date(dateString)
on Line 25 produces an Invalid Date object, causingdiffInSeconds
to beNaN
. This results in incorrect output. Consider adding validation:export function formatTimeAgo(dateString) { const date = new Date(dateString); + if (isNaN(date.getTime())) { + throw new Error(`Invalid date string: ${dateString}`); + } const now = new Date(); const diffInSeconds = Math.floor((now - date) / 1000);components/airtop/sources/common/polling.mjs (1)
22-27
: Avoid emitting every poll whendateCreated
is absent
isNew
currently returnstrue
wheneverresource.dateCreated
is falsy. For any API object that omits this field,run()
can’t advancelastTs
, so the same record will be re-emitted on every poll. Please guard for that case so we quietly skip items without a timestamp (or add a fallback field).- isNew(resource, lastTs) { - if (!resource.dateCreated || !lastTs) { - return true; - } - return new Date(resource.dateCreated).getTime() > lastTs; - }, + isNew(resource, lastTs) { + if (!lastTs) { + return true; + } + if (!resource.dateCreated) { + return false; + } + return new Date(resource.dateCreated).getTime() > lastTs; + },components/airtop/airtop.app.mjs (1)
24-29
: Handle missing timestamps in option labelsIf Airtop omits
lastActivity
ordateCreated
,formatTimeAgo
yields “NaN days ago”, which looks broken in the UI. Guard for missing values and fall back to something like “unknown” before composing the label.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (11)
components/airtop/actions/create-session/create-session.mjs
(1 hunks)components/airtop/actions/create-window/create-window.mjs
(1 hunks)components/airtop/actions/end-session/end-session.mjs
(1 hunks)components/airtop/actions/load-url/load-url.mjs
(1 hunks)components/airtop/actions/query-page/query-page.mjs
(1 hunks)components/airtop/actions/scrape-content/scrape-content.mjs
(1 hunks)components/airtop/airtop.app.mjs
(1 hunks)components/airtop/common/utils.mjs
(1 hunks)components/airtop/package.json
(2 hunks)components/airtop/sources/common/polling.mjs
(1 hunks)components/airtop/sources/new-session-created/new-session-created.mjs
(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (8)
components/airtop/actions/end-session/end-session.mjs (2)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/actions/create-session/create-session.mjs (2)
response
(74-77)sessionId
(79-79)
components/airtop/actions/scrape-content/scrape-content.mjs (2)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/actions/query-page/query-page.mjs (1)
response
(60-72)
components/airtop/actions/create-window/create-window.mjs (3)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/actions/create-session/create-session.mjs (1)
response
(74-77)components/airtop/actions/load-url/load-url.mjs (1)
response
(53-62)
components/airtop/sources/new-session-created/new-session-created.mjs (2)
components/airtop/sources/common/polling.mjs (3)
lastTs
(36-36)resources
(38-38)resource
(40-40)components/airtop/airtop.app.mjs (4)
offset
(14-14)limit
(13-13)data
(16-22)data
(40-42)
components/airtop/airtop.app.mjs (8)
components/airtop/sources/new-session-created/new-session-created.mjs (3)
limit
(17-17)offset
(16-16)data
(21-26)components/airtop/actions/create-session/create-session.mjs (3)
data
(64-72)sessionId
(79-79)response
(74-77)components/airtop/common/utils.mjs (1)
formatTimeAgo
(24-51)components/airtop/actions/create-window/create-window.mjs (2)
response
(53-62)windowId
(64-64)components/airtop/actions/end-session/end-session.mjs (1)
response
(21-24)components/airtop/actions/load-url/load-url.mjs (1)
response
(53-62)components/airtop/actions/query-page/query-page.mjs (1)
response
(60-72)components/airtop/actions/scrape-content/scrape-content.mjs (1)
response
(54-63)
components/airtop/actions/load-url/load-url.mjs (2)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/actions/create-window/create-window.mjs (1)
response
(53-62)
components/airtop/actions/create-session/create-session.mjs (2)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/common/utils.mjs (1)
parseObjectEntries
(9-22)
components/airtop/actions/query-page/query-page.mjs (2)
components/airtop/airtop.app.mjs (1)
response
(111-118)components/airtop/actions/scrape-content/scrape-content.mjs (1)
response
(54-63)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
🔇 Additional comments (11)
components/airtop/package.json (1)
3-3
: LGTM! Version bump and dependency are appropriate.The minor version bump to 0.1.0 correctly reflects the new feature additions (actions and sources). The @pipedream/platform dependency at ^3.1.0 is the current stable version.
Also applies to: 15-16
components/airtop/common/utils.mjs (1)
1-7
: LGTM! Safe JSON parsing helper.The try-catch wrapper correctly handles parsing failures by returning the original value, which is the expected behavior for optional parsing.
components/airtop/actions/end-session/end-session.mjs (1)
3-29
: LGTM! Clean action implementation.The action correctly terminates a session using the app's
endSession
method and provides a clear summary with the session ID.components/airtop/actions/create-session/create-session.mjs (4)
1-10
: LGTM! Correct imports and metadata.The action properly imports utilities and uses
ConfigurationError
for validation failures.
11-49
: LGTM! Well-documented props.The property definitions are clear, with helpful descriptions and appropriate types. The documentation links provide additional context for users.
50-72
: LGTM! Solid validation and data construction.The profileName validation correctly enforces the documented character restrictions, and the data payload is properly structured with parsed additional options.
74-95
: LGTM! Correct API flow and response handling.The action properly handles the session creation and optional profile saving. The conditional logic ensures
saveProfileOnTermination
is only called when both the flag is enabled and a profile name is provided.components/airtop/actions/scrape-content/scrape-content.mjs (1)
3-68
: LGTM! Clean scraping action.The action correctly scopes
windowId
to the selectedsessionId
and passes the appropriate parameters to the scraping API. The implementation follows the established pattern.components/airtop/actions/load-url/load-url.mjs (1)
3-67
: LGTM! Correct navigation action.The action properly handles URL navigation with the required
url
parameter and correctly scopedwindowId
. The summary provides clear feedback about the navigation.components/airtop/actions/create-window/create-window.mjs (1)
3-69
: LGTM! Well-structured window creation action.The action provides sensible defaults (Pipedream homepage and 1280x720 resolution) and follows the established pattern of extracting the ID from the response. The implementation is clean and correct.
components/airtop/actions/query-page/query-page.mjs (1)
3-77
: LGTM! Correct query action implementation.The action properly structures the request with a nested
configuration
object containing the threshold and pagination settings. The requiredprompt
parameter and scopedwindowId
are appropriate for this operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
* upstream/master: Adding app scaffolding for stackby Airtop new components (PipedreamHQ#18637) Sinch - new components (PipedreamHQ#18635) Mintlify - new components (PipedreamHQ#18519) Linear App - updates and new components (PipedreamHQ#18606) Merging pull request PipedreamHQ#18622 Adding app scaffolding for airtop
Closes #18630
Summary by CodeRabbit