-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New Components - oto #16621
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
New Components - oto #16621
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
""" WalkthroughThis update introduces a new integration for the Oto API, including foundational app logic, utility and constants modules, multiple action modules for product and order management, and a webhook source for order status updates. The implementation includes dynamic property definitions, API methods, webhook lifecycle management, and a test fixture for event simulation. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ActionModule
participant OtoApp
participant OtoAPI
User->>ActionModule: Provide input (e.g., orderId, product details)
ActionModule->>OtoApp: Call API method (e.g., getOrderDetails, createProduct)
OtoApp->>OtoAPI: Make HTTP request with auth
OtoAPI-->>OtoApp: Return response
OtoApp-->>ActionModule: Return data
ActionModule-->>User: Output result/summary
sequenceDiagram
participant OtoAPI
participant WebhookSourceBase
participant Database
participant HTTP
OtoAPI-->>WebhookSourceBase: Send webhook event (order status update)
WebhookSourceBase->>Database: Retrieve webhook ID
WebhookSourceBase->>WebhookSourceBase: generateMeta(event)
WebhookSourceBase-->>HTTP: Emit event with metadata
Assessment against linked issues
Suggested labels
Suggested reviewers
Poem
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
components/oto/common/constants.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs components/oto/oto.app.mjsOops! Something went wrong! :( ESLint: 8.57.1 Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs ✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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
🧹 Nitpick comments (6)
components/oto/actions/create-product/create-product.mjs (3)
23-31
: Consider using number type for numerical valuesThe price and taxAmount props are defined as strings, but they represent numerical values. It would be more appropriate to use the "integer" or "number" type for these props to ensure proper validation and handling.
price: { - type: "string", + type: "number", label: "Price", description: "Price of the product", }, taxAmount: { - type: "string", + type: "number", label: "Tax Amount", description: "Tax Amount of the product", },
80-85
: Consider adding JSON schema validation for customAttributesThe customAttributes property allows for JSON input but currently relies on the parseObject utility for processing. Consider adding a JSON schema to validate the structure of the customAttributes to ensure it conforms to the expected format before attempting to parse it.
You could enhance the property definition to include validation:
customAttributes: { type: "object", label: "Custom Attributes", description: "Custom attributes of the product specified as a JSON Array of objects with keys `attributeName` and `attributeValue`. Example: `[{ \"attributeName\": \"112\", \"attributeValue\": \"test product\"}]`", optional: true, default: "[]", validate: { type: "array", items: { type: "object", properties: { attributeName: { type: "string" }, attributeValue: { type: "string" } }, required: ["attributeName", "attributeValue"] } } }
106-108
: Add a check for empty responseThe code checks if response.productId exists, but it would be good to add handling for cases where the API response is unexpected or empty.
if (response.productId) { $.export("$summary", `Successfully created product with ID: ${response.productId}`); +} else { + $.export("$summary", "Product created but no ID was returned"); }components/oto/sources/order-status-updated-instant/test-event.mjs (1)
12-12
: Consider using a current timestamp for the test eventThe timestamp value (1746721659000) corresponds to May 8, 2025, which is a future date. While this might be intentional for testing purposes, it's generally better to use a non-future timestamp to avoid confusion.
- "timestamp": 1746721659000, + "timestamp": 1683561659000, // May 8, 2023 instead of 2025components/oto/sources/common/base.mjs (1)
45-52
: Parse raw strings and emit only valid JSON payloads
event.body
can arrive as a string for non-application/json
deliveries.
Iterating on a string later in workflows leads to hard-to-debug runtime errors.- const { body } = event; - if (!body) { + let { body } = event; + if (!body) { return; } + // If the body is a raw string, attempt to JSON-parse it. + if (typeof body === "string") { + try { + body = JSON.parse(body); + } catch { + // Un-parsable payload – emit the raw string + } + }components/oto/oto.app.mjs (1)
13-17
: Return{ label, value }
objects for a better UX in dropdownsReturning raw strings works, but Pipedream will show identical text for both the option label and the value.
Using an object clarifies what the user is selecting.- return clientStores?.map(({ storeName }) => storeName) || []; + return clientStores?.map(({ storeName }) => ({ + label: storeName, + value: storeName, + })) || [];
📜 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 (10)
components/oto/actions/create-product/create-product.mjs
(1 hunks)components/oto/actions/get-order-details/get-order-details.mjs
(1 hunks)components/oto/actions/list-orders/list-orders.mjs
(1 hunks)components/oto/common/constants.mjs
(1 hunks)components/oto/common/utils.mjs
(1 hunks)components/oto/oto.app.mjs
(1 hunks)components/oto/package.json
(2 hunks)components/oto/sources/common/base.mjs
(1 hunks)components/oto/sources/order-status-updated-instant/order-status-updated-instant.mjs
(1 hunks)components/oto/sources/order-status-updated-instant/test-event.mjs
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (6)
components/oto/package.json (1)
3-3
: Package configuration looks goodThe version bump to 0.1.0 is appropriate for introducing new features, and the addition of the @pipedream/platform dependency is necessary for Pipedream component functionality.
Also applies to: 14-16
components/oto/common/utils.mjs (1)
1-24
: Well-implemented utility function for JSON parsingThe
parseObject
utility function is well-written with proper error handling for different input types. It safely handles parsing of JSON strings, arrays of strings, and returns the original input when parsing isn't possible or necessary.I appreciate the defensive programming approach - checking for falsy values first, handling arrays separately, and providing graceful fallbacks when JSON parsing fails.
components/oto/common/constants.mjs (1)
1-70
: Good practice using constants moduleCreating a constants module with exported values like
DEFAULT_LIMIT
andSTATUSES
is a good practice for maintaining consistent values across the integration. This promotes code maintainability and prevents hardcoded values scattered throughout the codebase.components/oto/actions/create-product/create-product.mjs (1)
1-111
: Well-structured action componentOverall, this is a well-structured action component with clear property definitions, good documentation links, and proper implementation of the API call with the Oto client. The use of the parseObject utility for handling the customAttributes is appropriate.
components/oto/actions/get-order-details/get-order-details.mjs (1)
1-28
: Implementation looks goodThe Get Order Details action is well-implemented with appropriate prop definitions, clear documentation links, and concise execution logic.
components/oto/sources/order-status-updated-instant/order-status-updated-instant.mjs (1)
1-26
: Implementation looks goodThe Order Status Updated source component is well-structured. It properly extends the common base, implements the required methods, and uses appropriate deduplication strategy for order events.
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: 2
♻️ Duplicate comments (1)
components/oto/oto.app.mjs (1)
58-68
: Avoid usingthis
in default parameters & add JSON header for POST/PUTDefault-initialising
$ = this
inside the parameter list is unusual and can be brittle becausethis
is not bound until after parameter initialisation (Edge / older runtimes will treat it asundefined
).
Move the fallback assignment into the body and add an explicit"Content-Type": "application/json"
header for write requests.- _makeRequest({ - $ = this, path, ...otherOpts - }) { - return axios($, { + _makeRequest(opts = {}) { + const { + path, + $: pd = this, // fallback once `this` is bound + headers = {}, + ...otherOpts + } = opts; + return axios(pd, { ...otherOpts, url: `${this._baseUrl()}${path}`, headers: { Authorization: `Bearer ${this.$auth.oauth_access_token}`, + "Content-Type": "application/json", + ...headers, }, }); },
🧹 Nitpick comments (1)
components/oto/oto.app.mjs (1)
54-133
: Consider implementing rate limiting or retry mechanismsFor improved reliability, consider implementing rate limiting awareness or retry mechanisms for API calls, especially for production environments where API rate limits may be encountered.
_makeRequest(opts = {}) { const { path, $: pd = this, headers = {}, + retries = 3, + retryDelay = 1000, ...otherOpts } = opts; + const makeRequestWithRetry = async (attempt = 0) => { + try { + return await axios(pd, { + ...otherOpts, + url: `${this._baseUrl()}${path}`, + headers: { + Authorization: `Bearer ${this.$auth.oauth_access_token}`, + "Content-Type": "application/json", + ...headers, + }, + }); + } catch (error) { + // Retry on 429 (rate limit) or 5xx errors + if ((error.response?.status === 429 || + (error.response?.status >= 500 && error.response?.status < 600)) && + attempt < retries) { + // Exponential backoff + const delay = retryDelay * Math.pow(2, attempt); + await new Promise(resolve => setTimeout(resolve, delay)); + return makeRequestWithRetry(attempt + 1); + } + throw error; + } + }; + + return makeRequestWithRetry(); },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/oto/common/constants.mjs
(1 hunks)components/oto/oto.app.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/oto/common/constants.mjs
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: pnpm publish
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
- GitHub Check: Verify TypeScript components
🔇 Additional comments (1)
components/oto/oto.app.mjs (1)
108-132
: Robust pagination implementationThe pagination implementation properly handles undefined arrays with the nullish coalescing operator (
response[resourceKey] ?? []
) and includes appropriate logic for page counting and maximum item limits.
Resolves #16557
Summary by CodeRabbit
New Features
Improvements
Chores