-
Notifications
You must be signed in to change notification settings - Fork 5.5k
[Components] Ashby - new components #18968
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
base: master
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
WalkthroughAdds a new Ashby component: an expanded app module with HTTP/auth/pagination and API wrappers, seven new action modules (create/list/start operations), a parseJson utility, and package version/dependency updates. Changes
Sequence Diagram(s)sequenceDiagram
participant User as Workflow/User
participant Action as Action Module
participant App as App Module
participant API as Ashby API
rect rgba(0,128,128,0.06)
User->>Action: run({ $ })
Action->>Action: read props from this
Action->>App: call app.createCandidate/createApplication/createOffer/createInterviewSchedule/startOffer/startOfferProcess(...)
App->>App: getAuth() / getHeaders()
App->>App: makeRequest / post (build request)
App->>API: HTTP request
API-->>App: response
App-->>Action: return response
Action->>Action: $.export("$summary", "...")
Action-->>User: return response
end
sequenceDiagram
participant User as Workflow/User
participant ListAction as List Applications Action
participant App as App Module
participant Paginate as Paginate Utility
participant API as Ashby API
rect rgba(0,128,128,0.06)
User->>ListAction: run({ $ })
ListAction->>App: app.paginate({ fn: app.listApplications, fnArgs, max, keyField })
loop pages
Paginate->>App: app.listApplications(fnArgs)
App->>API: HTTP POST with syncToken
API-->>App: { results: [...], nextCursor? }
App-->>Paginate: page
Paginate->>Paginate: accumulate results
alt nextCursor exists and under max
Paginate->>Paginate: update fnArgs.syncToken
else
Paginate->>Paginate: stop
end
end
Paginate-->>ListAction: aggregated items
ListAction->>ListAction: $.export("$summary", count)
ListAction-->>User: return aggregated items
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
260b59e to
1ef0fae
Compare
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: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (8)
components/ashby/actions/create-application/create-application.mjs(1 hunks)components/ashby/actions/create-candidate/create-candidate.mjs(1 hunks)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs(1 hunks)components/ashby/actions/create-offer/create-offer.mjs(1 hunks)components/ashby/actions/list-applications/list-applications.mjs(1 hunks)components/ashby/ashby.app.mjs(1 hunks)components/ashby/common/utils.mjs(1 hunks)components/ashby/package.json(2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.
Applied to files:
components/ashby/package.json
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/ashby/actions/create-offer/create-offer.mjscomponents/ashby/actions/create-candidate/create-candidate.mjscomponents/ashby/actions/create-application/create-application.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/ashby/ashby.app.mjs
🧬 Code graph analysis (6)
components/ashby/actions/create-offer/create-offer.mjs (2)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/ashby.app.mjs (2)
response(247-252)response(345-352)
components/ashby/ashby.app.mjs (5)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/actions/create-candidate/create-candidate.mjs (1)
response(112-135)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/create-offer/create-offer.mjs (1)
response(53-62)components/ashby/actions/list-applications/list-applications.mjs (1)
response(75-91)
components/ashby/actions/create-candidate/create-candidate.mjs (2)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/ashby.app.mjs (2)
response(247-252)response(345-352)
components/ashby/actions/list-applications/list-applications.mjs (1)
components/ashby/ashby.app.mjs (2)
response(247-252)response(345-352)
components/ashby/actions/create-application/create-application.mjs (5)
components/ashby/actions/create-candidate/create-candidate.mjs (1)
response(112-135)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/create-offer/create-offer.mjs (1)
response(53-62)components/ashby/actions/list-applications/list-applications.mjs (1)
response(75-91)components/ashby/ashby.app.mjs (2)
response(247-252)response(345-352)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (2)
components/ashby/actions/create-offer/create-offer.mjs (1)
response(53-62)components/ashby/ashby.app.mjs (2)
response(247-252)response(345-352)
⏰ 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). (3)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (1)
components/ashby/actions/create-candidate/create-candidate.mjs (1)
124-133: Consider filtering undefined location fields.The current logic includes all location fields (city, region, country) if any one is truthy, resulting in
undefinedvalues for unset fields. While the API may ignore these, it's cleaner to only include defined fields.Apply this diff for cleaner object construction:
- ...(city || region || country - ? { - location: { - city, - region, - country, - }, - } - : undefined - ), + ...(city || region || country + ? { + location: Object.fromEntries( + Object.entries({ city, region, country }) + .filter(([_, v]) => v !== undefined) + ), + } + : {} + ),⛔ Skipped due to learnings
Learnt from: GTFalcao Repo: PipedreamHQ/pipedream PR: 18362 File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105 Timestamp: 2025-09-15T22:01:11.472Z Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
1ef0fae to
a540a35
Compare
michelle0927
left a 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.
LGTM! Ready for QA
|
Hello everyone, I have tested this PR and there're some test cases failed or needed improvement. Please check test reports below for more information:
|
a540a35 to
92f4ca6
Compare
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
♻️ Duplicate comments (2)
components/ashby/common/utils.mjs (1)
3-36: Fix recursion depth handling and array cycle detection.
maxDepthnever decreases, so the guard at Line 4 is dead code—deep structures keep recursing until the stack blows up. Arrays also skip theseenWeakSet, so a cyclic array still causes infinite recursion (this was already raised earlier). Please enforce the depth counter on every recursive call and register arrays inseen.-const parseJson = (input, maxDepth = 100) => { - const seen = new WeakSet(); - const parse = (value) => { - if (maxDepth <= 0) { +const parseJson = (input, maxDepth = 100) => { + const seen = new WeakSet(); + const parse = (value, depth) => { + if (depth <= 0) { return value; } if (typeof(value) === "string") { // Only parse if the string looks like a JSON object or array const trimmed = value.trim(); if ( (trimmed.startsWith("{") && trimmed.endsWith("}")) || (trimmed.startsWith("[") && trimmed.endsWith("]")) ) { try { - return parseJson(JSON.parse(value), maxDepth - 1); + return parse(JSON.parse(value), depth - 1); } catch (e) { return value; } } return value; - } else if (typeof(value) === "object" && value !== null && !Array.isArray(value)) { - if (seen.has(value)) { - return value; - } - seen.add(value); - return Object.entries(value) - .reduce((acc, [ - key, - val, - ]) => Object.assign(acc, { - [key]: parse(val), - }), {}); - } else if (Array.isArray(value)) { - return value.map((item) => parse(item)); + } else if (value && typeof(value) === "object") { + if (seen.has(value)) { + return value; + } + seen.add(value); + if (Array.isArray(value)) { + return value.map((item) => parse(item, depth - 1)); + } + return Object.entries(value) + .reduce((acc, [ + key, + val, + ]) => Object.assign(acc, { + [key]: parse(val, depth - 1), + }), {}); } return value; }; - return parse(input); + return parse(input, maxDepth); };components/ashby/ashby.app.mjs (1)
356-371: Stop exposingcursor/limitoverrides inpaginateSpreading
fnArgs?.dataafter the enforcedlimit/cursorlets callers reset those values each iteration, socursornever advances and the loop can hang. Rework the argument assembly so you capturefnArgs?.dataonce, but always overwritelimitand the evolvingcursorbefore each call. Also carry over the original cursor seed. This keeps pagination safe across retries.- async paginate({ - max = 600, fn, fnArgs, keyField = "results", - } = {}) { - const results = []; - let cursor; + async paginate({ + max = 600, fn, fnArgs, keyField = "results", + } = {}) { + const results = []; + const { + data: { + cursor: initialCursor, + ...restData + } = {}, + ...restFnArgs + } = fnArgs ?? {}; + let cursor = initialCursor; let collected = 0; while (collected < max) { const remainingToFetch = Math.min(max - collected, 100); - const response = await fn({ - ...fnArgs, - data: { - limit: remainingToFetch, - cursor, - ...fnArgs?.data, - }, - }); + const response = await fn({ + ...restFnArgs, + data: { + ...restData, + limit: remainingToFetch, + cursor, + }, + });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
components/ashby/actions/create-application/create-application.mjs(1 hunks)components/ashby/actions/create-candidate/create-candidate.mjs(1 hunks)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs(1 hunks)components/ashby/actions/create-offer/create-offer.mjs(1 hunks)components/ashby/actions/list-applications/list-applications.mjs(1 hunks)components/ashby/actions/start-offer-process/start-offer-process.mjs(1 hunks)components/ashby/actions/start-offer/start-offer.mjs(1 hunks)components/ashby/ashby.app.mjs(1 hunks)components/ashby/common/utils.mjs(1 hunks)components/ashby/package.json(2 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/ashby/actions/create-candidate/create-candidate.mjscomponents/ashby/actions/create-application/create-application.mjscomponents/ashby/actions/create-offer/create-offer.mjs
📚 Learning: 2025-07-09T18:07:12.426Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 17538
File: components/aircall/sources/new-sms/new-sms.mjs:19-25
Timestamp: 2025-07-09T18:07:12.426Z
Learning: In Aircall API webhook payloads, the `created_at` field is returned as an ISO 8601 string format (e.g., "2020-02-18T20:52:22.000Z"), not as milliseconds since epoch. For Pipedream components, this needs to be converted to milliseconds using `Date.parse()` before assigning to the `ts` field in `generateMeta()`.
Applied to files:
components/ashby/actions/create-application/create-application.mjs
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.
Applied to files:
components/ashby/package.json
🧬 Code graph analysis (8)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (2)
components/ashby/actions/create-offer/create-offer.mjs (1)
response(54-63)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/create-candidate/create-candidate.mjs (2)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/create-application/create-application.mjs (2)
components/ashby/actions/create-candidate/create-candidate.mjs (1)
response(112-135)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/create-offer/create-offer.mjs (4)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
response(29-34)components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/list-applications/list-applications.mjs (1)
components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/start-offer/start-offer.mjs (2)
components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/ashby.app.mjs (7)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/actions/create-candidate/create-candidate.mjs (1)
response(112-135)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/create-offer/create-offer.mjs (1)
response(54-63)components/ashby/actions/list-applications/list-applications.mjs (1)
response(75-91)components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
response(29-34)components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)
components/ashby/actions/start-offer-process/start-offer-process.mjs (2)
components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
⏰ 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: Lint Code Base
- GitHub Check: Publish TypeScript components
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
| async options({ prevContext: { cursor } }) { | ||
| if (cursor === null) { | ||
| return []; | ||
| } | ||
| const { | ||
| results, | ||
| nextCursor, | ||
| } = await this.listCandidates({ | ||
| data: { | ||
| cursor, | ||
| }, | ||
| }); | ||
| return { | ||
| options: results.map(({ | ||
| id: value, | ||
| name: label, | ||
| }) => ({ | ||
| label, | ||
| value, | ||
| })), | ||
| context: { | ||
| cursor: nextCursor || null, | ||
| }, | ||
| }; | ||
| }, |
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.
Fix destructuring of prevContext in async options
options() receives { prevContext }, and on the initial invocation Pipedream passes it as undefined. Destructuring prevContext: { cursor } therefore throws a TypeError before any options can load. Default the parameter to {} (and read cursor from it) so the dropdown renders, and mirror this fix for each async options definition in this file.
- async options({ prevContext: { cursor } }) {
+ async options({ prevContext } = {}) {
+ const cursor = prevContext?.cursor;
if (cursor === null) {
return [];
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| async options({ prevContext: { cursor } }) { | |
| if (cursor === null) { | |
| return []; | |
| } | |
| const { | |
| results, | |
| nextCursor, | |
| } = await this.listCandidates({ | |
| data: { | |
| cursor, | |
| }, | |
| }); | |
| return { | |
| options: results.map(({ | |
| id: value, | |
| name: label, | |
| }) => ({ | |
| label, | |
| value, | |
| })), | |
| context: { | |
| cursor: nextCursor || null, | |
| }, | |
| }; | |
| }, | |
| async options({ prevContext } = {}) { | |
| const cursor = prevContext?.cursor; | |
| if (cursor === null) { | |
| return []; | |
| } | |
| const { | |
| results, | |
| nextCursor, | |
| } = await this.listCandidates({ | |
| data: { | |
| cursor, | |
| }, | |
| }); | |
| return { | |
| options: results.map(({ | |
| id: value, | |
| name: label, | |
| }) => ({ | |
| label, | |
| value, | |
| })), | |
| context: { | |
| cursor: nextCursor || null, | |
| }, | |
| }; | |
| }, |
🤖 Prompt for AI Agents
In components/ashby/ashby.app.mjs around lines 11 to 35, the async options
function destructures prevContext as prevContext: { cursor } which throws when
prevContext is undefined; change the parameter to default prevContext to an
empty object (e.g., options({ prevContext = {} }) or options({ prevContext: {}
}) and then read cursor from it) so initial invocation doesn't TypeError, update
the same pattern for every async options definition in this file to default
prevContext to {} and use cursor from that defaulted object.
92f4ca6 to
8e7d153
Compare
|
Hi @vunguyenhung about: ashby - Create Offer - FailImprovement needed
So please test again with latest push, thanks! |
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
♻️ Duplicate comments (5)
components/ashby/ashby.app.mjs (3)
11-35: Critical: Fix destructuring to prevent TypeError on initial load.The destructuring
{ prevContext: { cursor } }on line 11 throws a TypeError whenprevContextisundefined(which happens on initial invocation). This prevents the dropdown from loading.Apply this pattern to fix (and apply to all similar
optionsfunctions in this file):- async options({ prevContext: { cursor } }) { + async options({ prevContext = {} } = {}) { + const cursor = prevContext?.cursor; if (cursor === null) {This same issue affects lines 41, 74, 121, 173, and 203.
251-270: Enhance error handling for better diagnostics.The error handling on line 268 assumes
error.response?.data?.messageis a string and may not provide useful context when the error structure differs.Consider this more robust approach:
} catch (error) { - throw error.response?.data?.message || error; + const errorMessage = error.response?.data?.message + || error.message + || JSON.stringify(error.response?.data || error); + throw new Error(errorMessage); }
355-386: Critical: Fix spread operator order to prevent pagination override.Lines 367-370 spread
fnArgs?.dataafter settinglimitandcursor, which allows callers to override the pagination parameters. This breaks pagination logic and could cause incorrect results or infinite loops.Apply this diff:
const response = await fn({ ...fnArgs, data: { + ...fnArgs?.data, limit: remainingToFetch, cursor, - ...fnArgs?.data, }, });components/ashby/common/utils.mjs (1)
33-36: Critical: Arrays not protected from circular references.The cycle detection using
WeakSetis only applied to plain objects (lines 22-24), but arrays can also contain circular references. This will cause infinite recursion and stack overflow if an array references itself.Apply this diff:
} else if (Array.isArray(value)) { + if (seen.has(value)) { + return value; + } + seen.add(value); return value.map((item) => parse(item)); }components/ashby/actions/create-application/create-application.mjs (1)
63-68: Consider validating the date format.The
createdAtprop accepts any string but should be a valid ISO 8601 date. Invalid formats will cause API errors downstream.Consider adding validation before the API call:
if (createdAt && isNaN(Date.parse(createdAt))) { throw new Error("createdAt must be a valid ISO 8601 date string"); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (10)
components/ashby/actions/create-application/create-application.mjs(1 hunks)components/ashby/actions/create-candidate/create-candidate.mjs(1 hunks)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs(1 hunks)components/ashby/actions/create-offer/create-offer.mjs(1 hunks)components/ashby/actions/list-applications/list-applications.mjs(1 hunks)components/ashby/actions/start-offer-process/start-offer-process.mjs(1 hunks)components/ashby/actions/start-offer/start-offer.mjs(1 hunks)components/ashby/ashby.app.mjs(1 hunks)components/ashby/common/utils.mjs(1 hunks)components/ashby/package.json(2 hunks)
🧰 Additional context used
🧠 Learnings (7)
📚 Learning: 2024-10-30T15:24:39.294Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14467
File: components/gainsight_px/actions/create-account/create-account.mjs:4-6
Timestamp: 2024-10-30T15:24:39.294Z
Learning: In `components/gainsight_px/actions/create-account/create-account.mjs`, the action name should be "Create Account" instead of "Create Memory".
Applied to files:
components/ashby/actions/create-candidate/create-candidate.mjscomponents/ashby/actions/create-offer/create-offer.mjscomponents/ashby/actions/create-application/create-application.mjs
📚 Learning: 2024-09-25T16:13:11.505Z
Learnt from: LucBerge
Repo: PipedreamHQ/pipedream PR: 14080
File: components/nocodb/nocodb.app.mjs:133-133
Timestamp: 2024-09-25T16:13:11.505Z
Learning: When implementing pagination with an offset, incrementing `args.params.offset` within the loop ensures correct tracking of the offset, particularly when a maximum count limit (`max`) is used.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-09-12T07:49:36.125Z
Learnt from: matyascimbulka
Repo: PipedreamHQ/pipedream PR: 18308
File: components/apify/actions/run-task-synchronously/run-task-synchronously.mjs:70-0
Timestamp: 2025-09-12T07:49:36.125Z
Learning: The Apify Task object always contains the `options` field according to the official API documentation, making nested destructuring like `options: { build }` safe to use without additional checks.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-09-15T22:01:11.472Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 18362
File: components/leonardo_ai/actions/generate-image/generate-image.mjs:103-105
Timestamp: 2025-09-15T22:01:11.472Z
Learning: In Pipedream components, pipedream/platform's axios implementation automatically excludes undefined values from HTTP requests, so there's no need to manually check for truthiness before including properties in request payloads.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2025-06-04T17:52:05.780Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 16954
File: components/salesloft/salesloft.app.mjs:14-23
Timestamp: 2025-06-04T17:52:05.780Z
Learning: In the Salesloft API integration (components/salesloft/salesloft.app.mjs), the _makeRequest method returns response.data which directly contains arrays for list endpoints like listPeople, listCadences, listUsers, and listAccounts. The propDefinitions correctly call .map() directly on these responses without needing to destructure a nested data property.
Applied to files:
components/ashby/ashby.app.mjs
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
Repo: PipedreamHQ/pipedream PR: 14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.
Applied to files:
components/ashby/package.json
📚 Learning: 2025-07-09T18:07:12.426Z
Learnt from: GTFalcao
Repo: PipedreamHQ/pipedream PR: 17538
File: components/aircall/sources/new-sms/new-sms.mjs:19-25
Timestamp: 2025-07-09T18:07:12.426Z
Learning: In Aircall API webhook payloads, the `created_at` field is returned as an ISO 8601 string format (e.g., "2020-02-18T20:52:22.000Z"), not as milliseconds since epoch. For Pipedream components, this needs to be converted to milliseconds using `Date.parse()` before assigning to the `ts` field in `generateMeta()`.
Applied to files:
components/ashby/actions/create-application/create-application.mjs
🧬 Code graph analysis (8)
components/ashby/actions/create-candidate/create-candidate.mjs (2)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/start-offer-process/start-offer-process.mjs (2)
components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (2)
components/ashby/actions/create-offer/create-offer.mjs (1)
response(63-72)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/create-offer/create-offer.mjs (3)
components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/start-offer/start-offer.mjs (3)
components/ashby/actions/create-offer/create-offer.mjs (1)
response(63-72)components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
response(29-34)components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/actions/list-applications/list-applications.mjs (1)
components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
components/ashby/ashby.app.mjs (7)
components/ashby/actions/create-application/create-application.mjs (1)
response(82-93)components/ashby/actions/create-candidate/create-candidate.mjs (1)
response(112-135)components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (1)
response(59-65)components/ashby/actions/create-offer/create-offer.mjs (1)
response(63-72)components/ashby/actions/list-applications/list-applications.mjs (1)
response(75-91)components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
response(29-34)components/ashby/actions/start-offer/start-offer.mjs (1)
response(29-34)
components/ashby/actions/create-application/create-application.mjs (1)
components/ashby/ashby.app.mjs (2)
response(255-260)response(365-372)
⏰ 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: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (12)
components/ashby/package.json (1)
3-3: LGTM! Version bump and dependency addition are appropriate.The version bump to 0.1.0 reflects the addition of new components, and the
@pipedream/platformdependency is correctly added to support the expanded integration.Also applies to: 15-16
components/ashby/ashby.app.mjs (2)
1-2: LGTM! Correct import for Pipedream platform.
271-354: LGTM! Clean and consistent API wrapper methods.The endpoint wrappers follow a consistent pattern and properly delegate to the
posthelper.components/ashby/actions/create-application/create-application.mjs (1)
70-99: LGTM! Clean action implementation.The run method properly destructures props, calls the API wrapper, and exports an appropriate summary.
components/ashby/actions/create-candidate/create-candidate.mjs (1)
95-141: LGTM! Clean implementation with proper conditional location handling.The run method correctly builds the candidate data payload and conditionally includes the location object only when at least one location field is provided.
components/ashby/actions/start-offer-process/start-offer-process.mjs (1)
23-40: LGTM! Clean and straightforward action implementation.components/ashby/actions/create-interview-schedule/create-interview-schedule.mjs (2)
24-50: LGTM! Excellent prop documentation.The detailed description with example JSON structure provides clear guidance on the expected format for interview events.
52-71: LGTM! Proper use of parseJson utility.The run method correctly parses the interview events array using the shared utility before sending to the API.
components/ashby/actions/start-offer/start-offer.mjs (1)
23-40: LGTM! Clean and consistent action implementation.components/ashby/actions/create-offer/create-offer.mjs (1)
56-61: Previous critical issue resolved.The destructuring now correctly includes
app, fixing theReferenceErrorthat was flagged in the previous review.components/ashby/actions/list-applications/list-applications.mjs (2)
1-13: LGTM! Metadata is appropriate for a read-only list action.The
readOnlyHint: trueannotation correctly reflects the non-mutating nature of this list operation.
64-96: LGTM! Pagination and date handling implemented correctly.The run method properly:
- Transforms the
createdAfterISO string to Unix timestamp in milliseconds for the API- Uses the pagination helper with appropriate
keyFieldandmaxparameters- Provides a clear summary with the count of retrieved applications
| - **path** (string, required): The form field's "path" value | ||
| - **value** (string, required): The field value (can be a primitive or complex type depending on field type) | ||
| You can find these referebce values in the response of the [offer.start API](https://developers.ashbyhq.com/reference/offerstart). |
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.
Fix typo in description.
"referebce" should be "reference".
Apply this diff:
-You can find these referebce values in the response of the [offer.start API](https://developers.ashbyhq.com/reference/offerstart).
+You can find these reference values in the response of the [offer.start API](https://developers.ashbyhq.com/reference/offerstart).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| You can find these referebce values in the response of the [offer.start API](https://developers.ashbyhq.com/reference/offerstart). | |
| You can find these reference values in the response of the [offer.start API](https://developers.ashbyhq.com/reference/offerstart). |
🤖 Prompt for AI Agents
In components/ashby/actions/create-offer/create-offer.mjs around line 35,
there's a typo in the inline description: change "referebce" to "reference" so
the sentence reads "You can find these reference values in the response of the
[offer.start API](https://developers.ashbyhq.com/reference/offerstart)." Make
this single-word correction and keep the rest of the text and link unchanged.
WHY
Resolves #18724
Summary by CodeRabbit