-
Notifications
You must be signed in to change notification settings - Fork 122
new pricing plan cards #6564
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 pricing plan cards #6564
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request updates various UI components by replacing explicit hex color classes with a new descriptive class ( Changes
Sequence Diagram(s)sequenceDiagram
participant B as Browser
participant AIT as OpenAccordionItemWhenLinkedTo
participant AB as Accordion Button
B->>AIT: URL hash changes (#faq-...)
AIT->>B: Retrieve current hash via subscribe
AIT->>AB: Query for button with aria-expanded="false"
AB-->>AIT: Return button reference
AIT->>AB: Trigger click event
AB-->>B: Accordion item expands
sequenceDiagram
participant U as User
participant PS as PricingSlider
participant PC as Pricing Component
participant PCc as PlanCard
U->>PS: Adjust slider value
PS->>PC: Invoke onChange(newValue)
PC->>PC: Update highlightedPlan state
PC->>PC: Scroll to corresponding PlanCard
PC->>PCc: Highlight selected plan
Possibly related PRs
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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 (
|
🚀 Snapshot Release (
|
| Package | Version | Info |
|---|---|---|
@graphql-hive/apollo |
0.37.2-alpha-20250303212749-86a88ab415818ac0c9e9f38608b41bca0ceb7ca6 |
npm ↗︎ unpkg ↗︎ |
hive |
5.1.3-alpha-20250303212749-86a88ab415818ac0c9e9f38608b41bca0ceb7ca6 |
npm ↗︎ unpkg ↗︎ |
💻 Website PreviewThe latest changes are available as preview in: https://2949dc0b.hive-landing-page.pages.dev |
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
🧹 Nitpick comments (10)
packages/web/docs/src/components/frequently-asked-questions/question-to-id.ts (1)
3-7: Consider refining the ID generation logic.The function handles conversion from question text to URL-friendly IDs, but has a few areas for improvement:
- It's removing the last character of the question string with
slice(0, -1)which is unusual - is this to remove a question mark? A more explicit approach would be better.- It doesn't handle special characters beyond spaces, which could lead to invalid IDs if questions contain characters like '?', '!', etc.
- When given a ReactNode that isn't a string, it returns undefined, which might cause accessibility issues if these IDs are used for HTML elements.
export function questionToId(question: string | ReactNode) { return typeof question === 'string' - ? `faq--${question.slice(0, -1).replace(/ /g, '-').toLowerCase()}` + ? `faq--${question.replace(/[?!.,]/g, '').replace(/ /g, '-').trim().toLowerCase()}` : undefined; }packages/web/docs/src/components/frequently-asked-questions/open-accordion-item-when-linked-to.ts (3)
10-10: Remove console.log statement.Debug console.log statements should be removed before production.
- console.log('hash', hash);
11-22: Consider adding error handling around DOM operations.The component relies on finding a button element with specific attributes, but lacks error handling if the element isn't found or if the click operation fails.
if (hash) { const button = document.querySelector<HTMLButtonElement>( `#${hash} button[aria-expanded="false"]`, ); if (button) { + try { button.click(); // in the case where user scrolls up and clicks the same link again, // we couldn't rely on hash change, so we just consume it here window.history.replaceState({}, '', window.location.pathname); + } catch (error) { + console.error('Failed to open accordion item:', error); + } } }
36-42: Enhance hash validation.The current implementation only checks if the hash starts with '#faq', but it might be worth adding additional validation to ensure the target element exists before attempting to interact with it.
const getSnapshot = () => { const hash = window.location.hash; if (hash.startsWith('#faq')) { + const hashValue = hash.slice(1); + // Optional: Check if the element exists before returning the hash + if (document.getElementById(hashValue)) { + return hashValue; + } + return undefined; - return hash.slice(1); } return undefined; };packages/web/docs/src/components/slider.tsx (1)
118-118: Consider adding hover/focus state for better accessibility.The reset button would benefit from hover and focus states to provide visual feedback to users when interacting with it.
- <div className="h-2 w-[calc(100%+4px)] rounded-l-lg bg-blue-600" /> + <div className="h-2 w-[calc(100%+4px)] rounded-l-lg bg-blue-600 transition-opacity hover:opacity-80 focus-visible:opacity-80" />packages/web/docs/src/components/pricing/pricing-slider.tsx (1)
30-30: Consider a numericdeadZoneif supported.
ThedeadZoneprop is passed as a string value. If yourSlidercomponent supports numeric inputs, consider updating this property to a numeric type for clarity and type safety.packages/web/docs/src/components/pricing/plan-card.tsx (3)
95-95: Remove or replace console debugging statements.
Leavingconsole.login production code can clutter logs and potentially leak internal details. Consider removing or switching to a robust logging mechanism.- console.log('transitionend', e.target);
149-149: Fix minor typo in comment.
The comment contains “befoere” instead of “before.” Keeping comments free of typos improves readability.- // in case somebody presses escape befoere the opening transition finishes + // in case somebody presses escape before the opening transition finishes
122-125: Double-check transitions for performance on mobile.
Frequent style manipulations and forced reflows can be expensive on low-end devices. Consider a more robust or library-based animation approach if you encounter performance bottlenecks.packages/web/docs/src/components/pricing/icons.tsx (1)
1-71: Add optional accessibility attributes.
These icons might benefit fromrole="img",aria-hidden, or accessible<title>/<desc>elements to improve screen-reader support.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
packages/web/docs/src/components/code-icon-white.svgis excluded by!**/*.svg
📒 Files selected for processing (15)
packages/web/docs/src/app/oss-friends/page.tsx(1 hunks)packages/web/docs/src/app/page.tsx(2 hunks)packages/web/docs/src/app/pricing/page.tsx(1 hunks)packages/web/docs/src/components/check-icon.tsx(1 hunks)packages/web/docs/src/components/frequently-asked-questions/index.tsx(3 hunks)packages/web/docs/src/components/frequently-asked-questions/open-accordion-item-when-linked-to.ts(1 hunks)packages/web/docs/src/components/frequently-asked-questions/question-to-id.ts(1 hunks)packages/web/docs/src/components/got-an-idea-section.tsx(1 hunks)packages/web/docs/src/components/plan-comparison.tsx(1 hunks)packages/web/docs/src/components/pricing/icons.tsx(1 hunks)packages/web/docs/src/components/pricing/index.tsx(1 hunks)packages/web/docs/src/components/pricing/plan-card.tsx(1 hunks)packages/web/docs/src/components/pricing/pricing-slider.tsx(1 hunks)packages/web/docs/src/components/slider.tsx(5 hunks)packages/web/docs/tailwind.config.ts(1 hunks)
✅ Files skipped from review due to trivial changes (4)
- packages/web/docs/src/components/got-an-idea-section.tsx
- packages/web/docs/src/components/check-icon.tsx
- packages/web/docs/src/app/oss-friends/page.tsx
- packages/web/docs/src/app/page.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`packages/web/docs/**`: The main landing page and documentat...
packages/web/docs/**: The main landing page and documentation website. It's built using TypeScript, Tailwind, NextJS and Nextra.In PRs that adds a new feature to the product, we would like to make sure that the PR includes the following:
- Up to date documentation in
packages/web/docs/src/content- A product update in
packages/web/docs/src/app/product-updates
packages/web/docs/tailwind.config.tspackages/web/docs/src/app/pricing/page.tsxpackages/web/docs/src/components/frequently-asked-questions/question-to-id.tspackages/web/docs/src/components/pricing/pricing-slider.tsxpackages/web/docs/src/components/frequently-asked-questions/index.tsxpackages/web/docs/src/components/pricing/plan-card.tsxpackages/web/docs/src/components/slider.tsxpackages/web/docs/src/components/plan-comparison.tsxpackages/web/docs/src/components/frequently-asked-questions/open-accordion-item-when-linked-to.tspackages/web/docs/src/components/pricing/index.tsxpackages/web/docs/src/components/pricing/icons.tsx
🪛 Biome (1.9.4)
packages/web/docs/src/components/pricing/index.tsx
[error] 240-240: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
[error] 322-322: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: website-preview / deployment
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
🔇 Additional comments (28)
packages/web/docs/src/components/frequently-asked-questions/index.tsx (2)
28-35: Good enhancement to support direct linking to FAQ items.The changes to the Accordion component to include OpenAccordionItemWhenLinkedTo looks good and enhances the functionality by allowing direct links to specific FAQ questions.
68-68:❓ Verification inconclusive
Verify ID handling for non-string questions.
The ID attribute is now set using questionToId(question), which returns undefined for non-string questions. This could potentially cause issues with accessibility or linking functionality.
🏁 Script executed:
#!/bin/bash # Search for places where question might not be a string rg -A 2 -B 2 --type tsx "\<AccordionItem\>" packages/web/docs/src/Length of output: 152
Action Required: Confirm that non-string questions yield a valid ID value.
The current implementation sets the ID attribute via
id={questionToId(question)}, and it appears that whenquestionisn’t a string,questionToIdcan returnundefined. This may lead to accessibility or linking issues. Note that our earlier search attempt for<AccordionItem>produced a regex error because of the invalid escapes. Please re-run your search with a corrected regex (e.g., using"AccordionItem"without escaped angle brackets) or verify manually that:
- The
questionprop is always a string wherequestionToIdis used.- If non-string values are possible, then
questionToIdhandles them appropriately (by coercing or defaulting to a safe string).Review these points across related components (like where
<AccordionItem>is used) to ensure consistent type handling.packages/web/docs/src/components/frequently-asked-questions/open-accordion-item-when-linked-to.ts (1)
19-19: Consider preserving the hash in the URL.By replacing the URL with just the pathname, you're removing the hash entirely. This means if a user copies the URL after an accordion item has been opened, they won't get a link that directly opens that item.
Is this behavior intentional? If not, consider preserving the hash in the URL but marking it as "processed" to prevent re-triggering.
packages/web/docs/tailwind.config.ts (1)
26-26: Good addition of the new color value.Adding a descriptive color name
'blueish-green'helps maintain consistency across the application. The TODO comment to move this to shared Tailwind config is also a good practice for future maintainability.packages/web/docs/src/app/pricing/page.tsx (1)
25-25: Improved responsive layout.Changing from
mt-4tomx-4 md:mx-6aligns with the other components on the page, creating a more consistent horizontal spacing pattern across different viewport sizes.packages/web/docs/src/components/plan-comparison.tsx (2)
5-7: Enhanced responsive design with improved colors.Updating to the new
bg-blueish-greencolor and adding responsive padding (px-4 py-12 md:p-24) improves the section's appearance across different screen sizes, which aligns with the PR objective to test across various screen sizes.
8-16: Great visual enhancement to highlight key message.The improved heading structure with flex-wrap and responsive gap spacing makes the component more mobile-friendly. The highlighted "every feature" text with gradient background creates a nice visual focal point that draws user attention to this key selling point.
packages/web/docs/src/components/slider.tsx (8)
1-2: Correctly added 'use client' directive.Making this explicit ensures the component is properly rendered as a client component, which is necessary for the interactive slider functionality.
6-6: Updated SVG icon for better contrast.Changing from green to white icon likely improves visibility against the new blue background colors in the slider.
10-10: Good addition of the deadZone property.This new optional property enhances the slider's functionality, addressing the PR objective to improve the slider's behavior with the new width.
12-12: Updated function signature to include new property.Correctly updated the function signature to include the new deadZone parameter.
37-37: Updated fill background color for visual consistency.Changing to
bg-beige-300andafter:bg-blue-600aligns with the new color scheme and improves the visual consistency.
48-48: Updated indicator styling to match new color scheme.The blue color scheme is more consistent with the overall design changes in the pricing section.
58-58: Improved visual indicator with updated styling.Changed from green to blue to match the updated color scheme.
102-122: Well-implemented deadZone functionality.This conditional rendering approach effectively implements the deadZone feature requested in the PR objectives. The button implementation includes proper event handling to reset the slider value to zero.
The implementation addresses the overshoot issue mentioned in the PR objectives by providing a dedicated zone where the slider resets to zero, improving user experience.
packages/web/docs/src/components/pricing/pricing-slider.tsx (2)
37-37: Validate custom counters for browser compatibility.
You’re leveraging CSS counter sets to provide an inline label (e.g., "M ops, $price / month"). Verify that all target browsers support this approach.
40-41: Ensure graceful fallback forvalueAsNumber.
WhilevalueAsNumbergenerally works for<input type="range">, confirm graceful handling in any older or non-standard browsers if required by your project.packages/web/docs/src/components/pricing/plan-card.tsx (1)
127-163: Consider broader browser compatibility forAbortController.
AbortControllerusage may be unsupported in older browsers without polyfills. Confirm all of your supported browsers handle thesignalproperty onaddEventListener.packages/web/docs/src/components/pricing/index.tsx (10)
3-25: All imports look good.
Neat organization of external and local imports. No issues noted.
29-53: Tooltip component design looks solid.
The custom arrow implementation nicely resolves placement issues. The increaseddelayDurationshould provide a more comfortable hover experience.
56-60: Interface declaration appears correct.
ExtendingHTMLLIElementis a convenient choice to seamlessly support list-specific attributes.
63-92: PlanFeaturesListItem readability is good.
The usage of theTooltipfor optional descriptions is well-structured, and the breakdown of each feature under separate<span>elements improves clarity.
97-101: Pricing component setup looks fine.
Defining thePlanTypeunion and using local state for highlight management is straightforward and maintainable.
106-110: Section heading and description seem clear.
This concise explanation for usage-based pricing is likely helpful for users scanning the page.
114-157: PricingSlider logic is well-handled.
Smooth scrolling on plan changes is a nice detail. Make sure to test thoroughly on mobile devices for consistent behavior.
164-216: Hobby plan card is well-defined.
The feature list is straightforward, and “Free forever” labeling is appropriately highlighted for personal projects.
217-279: Pro plan card structure looks good.
Providing a monthly base price plus usage-based scaling caters to a wide range of teams.🧰 Tools
🪛 Biome (1.9.4)
[error] 240-240: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
280-349: Enterprise plan card is well-outlined.
Providing a contact-based approach for large-scale clients is appropriate.🧰 Tools
🪛 Biome (1.9.4)
[error] 322-322: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
|
🐋 This PR was built and pushed to the following Docker images: Targets: Platforms: Image Tag: Docker Bake metadata{
"app": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/api/health",
"build-arg:IMAGE_DESCRIPTION": "The app of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/app",
"build-arg:PORT": "3000",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/app",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/t7vpv7sokd36vamplcwbc5h17",
"containerimage.config.digest": "sha256:4765e453b59bb0f7be1adfc22206a3d3721406a5832b60bd5d7efd54c3e4407c",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e74ba52534608108df6c265684813090f05e1d66cc2d45631d1d689e11723bd8",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:e74ba52534608108df6c265684813090f05e1d66cc2d45631d1d689e11723bd8",
"image.name": "ghcr.io/graphql-hive/app:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/app:pricing_2-arm64"
},
"buildx.build.warnings": [
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRQT1JUJyAobGluZSAyMik=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 22
},
"end": {
"line": 22
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIyKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 22
},
"end": {
"line": 22
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDEwKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 10
},
"end": {
"line": 10
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTUp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 15
},
"end": {
"line": 15
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMyk=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 13
},
"end": {
"line": 13
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTQp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 14
},
"end": {
"line": 14
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAyMSk=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 21
},
"end": {
"line": 21
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIxKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 21
},
"end": {
"line": 21
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDEyKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9ERVNDUklQVElPTicgKGxpbmUgMTcp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 17
},
"end": {
"line": 17
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRSRUxFQVNFJyAobGluZSAxMik=",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "VW5kZWZpbmVkVmFyOiBVc2FnZSBvZiB1bmRlZmluZWQgdmFyaWFibGUgJyRJTUFHRV9USVRMRScgKGxpbmUgMTIp",
"detail": [
"VmFyaWFibGVzIHNob3VsZCBiZSBkZWZpbmVkIGJlZm9yZSB0aGVpciB1c2U="
],
"url": "https://docs.docker.com/go/dockerfile/rule/undefined-var/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 12
},
"end": {
"line": 12
}
}
]
},
{
"vertex": "sha256:2ce43921c236e4b0912411e12a144bf1d89db509c854d35ba98990d78b6a72fc",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDIwKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "services.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSB3Z2V0IGNhLWNlcnRpZmljYXRlcyAmJiBybSAtcmYgL3Zhci9saWIvYXB0L2xpc3RzLyoKCkFSRyBTRVJWSUNFX0RJUl9OQU1FCldPUktESVIgL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLyRTRVJWSUNFX0RJUl9OQU1FLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UubGljZW5zZXM9TUlUCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS50aXRsZT0kSU1BR0VfVElUTEUKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb249JFJFTEVBU0UKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmRlc2NyaXB0aW9uPSRJTUFHRV9ERVNDUklQVElPTgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UuYXV0aG9ycz0iVGhlIEd1aWxkIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudmVuZG9yPSJLYW1pbCBLaXNpZWxhIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgpMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2Uuc291cmNlPSJodHRwczovL2dpdGh1Yi5jb20vZ3JhcGhxbC1oaXZlL3BsYXRmb3JtIgoKRU5WIEVOVklST05NRU5UIHByb2R1Y3Rpb24KRU5WIFJFTEVBU0UgJFJFTEVBU0UKRU5WIFBPUlQgJFBPUlQKCkhFQUxUSENIRUNLIC0taW50ZXJ2YWw9NXMgXAogIC0tdGltZW91dD01cyBcCiAgLS1zdGFydC1wZXJpb2Q9NXMgXAogIC0tcmV0cmllcz02IFwKICBDTUQgJEhFQUxUSENIRUNLX0NNRAoKRU5UUllQT0lOVCBbICIvZW50cnlwb2ludC5zaCIgXQo=",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 20
},
"end": {
"line": 20
}
}
]
},
{
"vertex": "sha256:87bf49ac99d5ae7b21ac65d3d72c0fd9fdaed68036bb31b1d656b27c1db2fd26",
"level": 1,
"short": "TGVnYWN5S2V5VmFsdWVGb3JtYXQ6ICJFTlYga2V5PXZhbHVlIiBzaG91bGQgYmUgdXNlZCBpbnN0ZWFkIG9mIGxlZ2FjeSAiRU5WIGtleSB2YWx1ZSIgZm9ybWF0IChsaW5lIDExKQ==",
"detail": [
"TGVnYWN5IGtleS92YWx1ZSBmb3JtYXQgd2l0aCB3aGl0ZXNwYWNlIHNlcGFyYXRvciBzaG91bGQgbm90IGJlIHVzZWQ="
],
"url": "https://docs.docker.com/go/dockerfile/rule/legacy-key-value-format/",
"sourceInfo": {
"filename": "migrations.dockerfile",
"data": "RlJPTSBub2RlOjIyLjEzLjAtc2xpbQoKUlVOIGFwdC1nZXQgdXBkYXRlICYmIGFwdC1nZXQgaW5zdGFsbCAteSBjYS1jZXJ0aWZpY2F0ZXMKCldPUktESVIgL3Vzci9zcmMvYXBwCgpDT1BZIC0tZnJvbT1kaXN0IC4gL3Vzci9zcmMvYXBwLwpDT1BZIC0tZnJvbT1zaGFyZWQgLiAvCgpFTlYgRU5WSVJPTk1FTlQgcHJvZHVjdGlvbgpFTlYgTk9ERV9FTlYgcHJvZHVjdGlvbgpFTlYgUkVMRUFTRSAkUkVMRUFTRQoKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmxpY2Vuc2VzPU1JVApMQUJFTCBvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudGl0bGU9JElNQUdFX1RJVExFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS52ZXJzaW9uPSRSRUxFQVNFCkxBQkVMIG9yZy5vcGVuY29udGFpbmVycy5pbWFnZS5kZXNjcmlwdGlvbj0kSU1BR0VfREVTQ1JJUFRJT04KTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLmF1dGhvcnM9IlRoZSBHdWlsZCIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlbmRvcj0iS2FtaWwgS2lzaWVsYSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnVybD0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKTEFCRUwgb3JnLm9wZW5jb250YWluZXJzLmltYWdlLnNvdXJjZT0iaHR0cHM6Ly9naXRodWIuY29tL2dyYXBocWwtaGl2ZS9wbGF0Zm9ybSIKCkVOVFJZUE9JTlQgWyAiL2VudHJ5cG9pbnQuc2giIF0K",
"language": "Dockerfile"
},
"range": [
{
"start": {
"line": 11
},
"end": {
"line": 11
}
}
]
}
],
"commerce": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The commerce service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/commerce",
"build-arg:PORT": "3010",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/commerce",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/pjbh9m8y002m1dsv3du2j79u2",
"containerimage.config.digest": "sha256:02f70d578cef4b1f1e1fa9d2748841ea69c9833ce76d0c8ea25f71d387b7cab7",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:7030332ea8a8ee0640ec8051889be5631d940af61fb0823e28e1f63a3523b69f",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:7030332ea8a8ee0640ec8051889be5631d940af61fb0823e28e1f63a3523b69f",
"image.name": "ghcr.io/graphql-hive/commerce:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/commerce:pricing_2-arm64"
},
"composition-federation-2": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "Federation 2 Composition Service for GraphQL Hive.",
"build-arg:IMAGE_TITLE": "graphql-hive/composition-federation-2",
"build-arg:PORT": "3069",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/external-composition",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/pg5vstk5hwguii3elivp66vt4",
"containerimage.config.digest": "sha256:26559296e784bdf56cd7bfca8b1e8d7c5434fdb45566a40cc15c5766868c2ca4",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:c6a943b3a06004f610f83463c4d31b994be9034fc975a55fbb06a8e720adac85",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:c6a943b3a06004f610f83463c4d31b994be9034fc975a55fbb06a8e720adac85",
"image.name": "ghcr.io/graphql-hive/composition-federation-2:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/composition-federation-2:pricing_2-arm64"
},
"emails": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The emails service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/emails",
"build-arg:PORT": "3006",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/emails",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/5c8gr8vom3xodiz0yd6c8ie2a",
"containerimage.config.digest": "sha256:09d88dc18448767f75b2eb962a61fcc9b51f28bfcf38eb67168d0ae2d29a76cc",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:0393193d45d57e9fd7d0a092937f88ffea4600dc9f704e4396c83945a2bd2bde",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:0393193d45d57e9fd7d0a092937f88ffea4600dc9f704e4396c83945a2bd2bde",
"image.name": "ghcr.io/graphql-hive/emails:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/emails:pricing_2-arm64"
},
"policy": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The policy service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/policy",
"build-arg:PORT": "3012",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/policy",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/xnr586h110lfzwdm75j055cc9",
"containerimage.config.digest": "sha256:b4a3ddd87778b79cdad06ac08987a4dac2904d3a72d13ee70b92f874878c4bba",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:f2c747c2fbce57f09c1f037e7e88c86c9be3bf8c2f3ef6062c3dafb7b83373e0",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:f2c747c2fbce57f09c1f037e7e88c86c9be3bf8c2f3ef6062c3dafb7b83373e0",
"image.name": "ghcr.io/graphql-hive/policy:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/policy:pricing_2-arm64"
},
"schema": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The schema service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/schema",
"build-arg:PORT": "3002",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/schema",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/j5w79xm831b60u19mj01rxk8z",
"containerimage.config.digest": "sha256:d26f8e7b365fc4a0ffd8a204d297294363f6c4a60813d87e606622c052f8302f",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:c2e7b8e47a064993fe70cf21bae66962cc818370965ce810a86eebded5ae7e82",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:c2e7b8e47a064993fe70cf21bae66962cc818370965ce810a86eebded5ae7e82",
"image.name": "ghcr.io/graphql-hive/schema:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/schema:pricing_2-arm64"
},
"server": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The server service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/server",
"build-arg:PORT": "3001",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/server",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/njfigobbg0tg83macu7tadble",
"containerimage.config.digest": "sha256:be08293c072259e1f6956d20d50bbbe2df0c776323ff055a78e8065700ddb3ed",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:38299e922b7ecd707870f19f85efe77c9832d9a331cd3722d97f5bf136f5da94",
"size": 2076,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:38299e922b7ecd707870f19f85efe77c9832d9a331cd3722d97f5bf136f5da94",
"image.name": "ghcr.io/graphql-hive/server:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/server:pricing_2-arm64"
},
"storage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "migrations.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:IMAGE_DESCRIPTION": "The migrations service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/storage",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/9wukrbot0dg0q5gnhs6vktscn",
"containerimage.config.digest": "sha256:5578f0451888713c41bc0366dd1cbc69da3a4e7d8165a5eb26c64a1cdf447b53",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:cca3c15cbb9b52cbe2284cebf65ad130f0a838a9a662545d48c480cc43c19165",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:cca3c15cbb9b52cbe2284cebf65ad130f0a838a9a662545d48c480cc43c19165",
"image.name": "ghcr.io/graphql-hive/storage:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/storage:pricing_2-arm64"
},
"tokens": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The tokens service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/tokens",
"build-arg:PORT": "3003",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/tokens",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/98gsy6p8q7cvupxqmes8thxr3",
"containerimage.config.digest": "sha256:a313402ec93c93ec431bf9e8f376ef0a6219210193552ceb7f5ae7cb9d0490f5",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:03d12d64ad9771b2b13fdca2b5368309089612f0265273e4f25e462c77cad276",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:03d12d64ad9771b2b13fdca2b5368309089612f0265273e4f25e462c77cad276",
"image.name": "ghcr.io/graphql-hive/tokens:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/tokens:pricing_2-arm64"
},
"usage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/usage",
"build-arg:PORT": "3006",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/usage",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/sencqm66jriliwygql889pzg9",
"containerimage.config.digest": "sha256:0b5e74b9c06de207d8ec4684f95fa9897027c809015d562c5c7f428215284c59",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:045eac894ee57c10fcfe8491a46c97e07e7bad0c70098e189e65c87634dbbba2",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:045eac894ee57c10fcfe8491a46c97e07e7bad0c70098e189e65c87634dbbba2",
"image.name": "ghcr.io/graphql-hive/usage:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/usage:pricing_2-arm64"
},
"usage-ingestor": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The usage ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/usage-ingestor",
"build-arg:PORT": "3007",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/usage-ingestor",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/1h7n1th75am3fiklfeh7w138q",
"containerimage.config.digest": "sha256:52f8b6e3fdf460295ceccc656a22542d68e02eb62f8ca92c0f77accca783ac38",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:cd58a309f1783f003b7dc63778de1f5616ec276ddea955cd50ac02da282486eb",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:cd58a309f1783f003b7dc63778de1f5616ec276ddea955cd50ac02da282486eb",
"image.name": "ghcr.io/graphql-hive/usage-ingestor:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/usage-ingestor:pricing_2-arm64"
},
"webhooks": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/node@22.13.0-slim?platform=linux%2Farm64",
"digest": {
"sha256": "f5a0871ab03b035c58bdb3007c3d177b001c2145c18e81817b71624dcf7d8bff"
}
}
],
"invocation": {
"configSource": {
"entryPoint": "services.dockerfile"
},
"parameters": {
"frontend": "dockerfile.v0",
"args": {
"build-arg:HEALTHCHECK_CMD": "wget --spider -q http://127.0.0.1:${PORT}/_readiness",
"build-arg:IMAGE_DESCRIPTION": "The webhooks ingestor service of the GraphQL Hive project.",
"build-arg:IMAGE_TITLE": "graphql-hive/webhooks",
"build-arg:PORT": "3005",
"build-arg:RELEASE": "86a88ab415818ac0c9e9f38608b41bca0ceb7ca6",
"build-arg:SERVICE_DIR_NAME": "@hive/webhooks",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:dockerfile": "j7kg56dd0eg5c0aezpmlc48qs",
"local-sessionid:shared": "j7kg56dd0eg5c0aezpmlc48qs"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/arm64"
}
}
},
"buildx.build.ref": "builder-42825e3a-e3fa-4139-bad2-3e47922cef1e/builder-42825e3a-e3fa-4139-bad2-3e47922cef1e0/596lrr0ii9r4vc08eyhcajxrz",
"containerimage.config.digest": "sha256:d12fb9901ae100271222dceaa58017f451a368ccfa4fb2a2e49fee7e3fc0bc77",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e082e9e43f82df1963509ecb382d86d3bd6a66a44a9ce4be3a86f9106657a906",
"size": 2075,
"platform": {
"architecture": "arm64",
"os": "linux"
}
},
"containerimage.digest": "sha256:e082e9e43f82df1963509ecb382d86d3bd6a66a44a9ce4be3a86f9106657a906",
"image.name": "ghcr.io/graphql-hive/webhooks:86a88ab415818ac0c9e9f38608b41bca0ceb7ca6-arm64,ghcr.io/graphql-hive/webhooks:pricing_2-arm64"
}
} |
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: 0
🧹 Nitpick comments (2)
packages/web/docs/src/components/pricing/index.tsx (2)
76-76: Consider using more stable keys than array indices.While using index as keys works for static lists, if the feature order might change in the future, this could lead to inefficient DOM updates and potential bugs.
-<span key={index} className="mt-2 flex gap-2 leading-6"> +<span key={`feature-${index}-${String(feature).substring(0, 10)}`} className="mt-2 flex gap-2 leading-6">
115-155: Consider extracting scroll logic into a helper function.The current implementation has complex scroll calculation logic embedded in the onChange handler. Extracting this into a named helper function would improve readability and maintainability.
+const scrollToCard = ( + scrollviewRef: React.RefObject<HTMLDivElement>, + planName: string +) => { + if (!scrollviewRef.current) return; + + const card = scrollviewRef.current.querySelector( + `[data-plan="${planName}"]`, + ) as HTMLElement; + if (!card) return; + + const { left, right } = card.getBoundingClientRect(); + const containerRect = scrollviewRef.current.getBoundingClientRect(); + const scrollLeft = scrollviewRef.current.scrollLeft; + const containerLeft = containerRect.left; + const padding = parseInt(window.getComputedStyle(scrollviewRef.current).paddingLeft); + + const cardLeftRelativeToContainer = left - containerLeft; + const cardRightRelativeToContainer = right - containerLeft; + + if ( + cardLeftRelativeToContainer >= padding && + cardRightRelativeToContainer <= containerRect.width - padding + ) { + return; // Card is fully visible, no need to scroll + } + + let targetScrollLeft = scrollLeft; + + if (cardLeftRelativeToContainer < padding) { + targetScrollLeft = scrollLeft - (padding - cardLeftRelativeToContainer); + } else if (cardRightRelativeToContainer > containerRect.width - padding) { + targetScrollLeft = + scrollLeft + (cardRightRelativeToContainer - (containerRect.width - padding)); + } + + scrollviewRef.current.scrollTo({ + left: targetScrollLeft, + behavior: 'smooth', + }); +}; onChange={value => { const newPlan = value === 1 ? 'Hobby' : value < 280 ? 'Pro' : 'Enterprise'; if (newPlan !== highlightedPlan) { setHighlightedPlan(newPlan); - if (!scrollviewRef.current) return; - const card = scrollviewRef.current.querySelector( - `[data-plan="${newPlan}"]`, - ) as HTMLElement; - if (!card) return; - - const { left, right } = card.getBoundingClientRect(); - const containerRect = scrollviewRef.current.getBoundingClientRect(); - const scrollLeft = scrollviewRef.current.scrollLeft; - const containerLeft = containerRect.left; - const padding = parseInt(window.getComputedStyle(scrollviewRef.current).paddingLeft); - - const cardLeftRelativeToContainer = left - containerLeft; - const cardRightRelativeToContainer = right - containerLeft; - - if ( - cardLeftRelativeToContainer >= padding && - cardRightRelativeToContainer <= containerRect.width - padding - ) { - return; - } - - let targetScrollLeft = scrollLeft; - - if (cardLeftRelativeToContainer < padding) { - targetScrollLeft = scrollLeft - (padding - cardLeftRelativeToContainer); - } else if (cardRightRelativeToContainer > containerRect.width - padding) { - targetScrollLeft = - scrollLeft + (cardRightRelativeToContainer - (containerRect.width - padding)); - } - - scrollviewRef.current.scrollTo({ - left: targetScrollLeft, - behavior: 'smooth', - }); + scrollToCard(scrollviewRef, newPlan); } }}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/tests-e2e.yaml(1 hunks)packages/web/docs/src/components/pricing/index.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`packages/web/docs/**`: The main landing page and documentat...
packages/web/docs/**: The main landing page and documentation website. It's built using TypeScript, Tailwind, NextJS and Nextra.In PRs that adds a new feature to the product, we would like to make sure that the PR includes the following:
- Up to date documentation in
packages/web/docs/src/content- A product update in
packages/web/docs/src/app/product-updates
packages/web/docs/src/components/pricing/index.tsx
🪛 Biome (1.9.4)
packages/web/docs/src/components/pricing/index.tsx
[error] 239-239: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
[error] 321-321: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.
(lint/correctness/useJsxKeyInIterable)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: website-preview / deployment
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
🔇 Additional comments (7)
.github/workflows/tests-e2e.yaml (1)
51-51: Cypress Timeout Adjustment ConfirmedThe increase in the Cypress job's timeout from 6 to 8 minutes is appropriate given the new pricing plan cards and their animations. This extra time should help mitigate false timeouts during end-to-end tests across various screen sizes.
packages/web/docs/src/components/pricing/index.tsx (6)
30-30: Improved tooltip user experience with delay duration.Changing the tooltip delay from 0 to 350ms prevents accidental tooltip triggers and provides a smoother user experience.
40-49: Good solution for tooltip arrow positioning.The custom SVG arrow implementation solves the positioning issue with the default Radix UI arrow. The comment explaining the reason is helpful for future maintainers.
55-90: Well-structured component for consistent feature presentation.The
PlanFeaturesListItemcomponent provides a consistent way to display plan features across different pricing tiers. The component is well-typed with a clear interface and properly handles both the UI presentation and tooltip integration.
239-242: Add a key property to the array element.React requires a unique
keyfor each element in an array to track item changes properly.features={[ - <span> + <span key="price-info"> 1M operations per month <small className="block text-xs">Then $10 per million operations</small> </span>, ]}🧰 Tools
🪛 Biome (1.9.4)
[error] 239-239: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
321-324: Add a key property for each React element within the features array.Similar to the Pro plan, this
<span>element also requires akeyattribute.-<span> +<span key="graphql-support"> GraphQL / APIs support and guidance from{' '} <TextLink href="https://theguild.dev">The Guild</TextLink> </span>,🧰 Tools
🪛 Biome (1.9.4)
[error] 321-321: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
161-349: Verify the animation smoothness across different screen sizes.In the PR description, the author mentioned concerns about animations and requested testing across different screen sizes. Please verify that:
- The plan cards animate smoothly when transitioning between states
- The layout remains visually appealing across various device widths
- The slider behavior works properly without exhibiting the overshoot issue mentioned in the PR
Consider whether maintaining a static width while only animating the height (as mentioned in the PR objectives) would create a better visual experience.
🧰 Tools
🪛 Biome (1.9.4)
[error] 239-239: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
[error] 321-321: Missing key property for this element in iterable.
The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.(lint/correctness/useJsxKeyInIterable)
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: 0
🧹 Nitpick comments (1)
packages/web/docs/src/components/slider.tsx (1)
89-130: Added custom easing functions for animations.Added two easing functions:
--ease-overshoot-far- For larger animations--ease-overshoot-a-bit- For more subtle animationsThese easing functions address the PR objective of updating the easing to accommodate the new width, as the current implementation was exhibiting overshoot proportional to the slider width.
The TODO comment should be addressed in a future update when moving to Tailwind 4.
Consider adding a comment explaining the difference between the two easing functions and when each one is used. This would make it easier for future developers to understand the intentional distinction.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.eslintrc.cjs(1 hunks)packages/web/docs/src/components/slider.tsx(6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`packages/web/docs/**`: The main landing page and documentat...
packages/web/docs/**: The main landing page and documentation website. It's built using TypeScript, Tailwind, NextJS and Nextra.In PRs that adds a new feature to the product, we would like to make sure that the PR includes the following:
- Up to date documentation in
packages/web/docs/src/content- A product update in
packages/web/docs/src/app/product-updates
packages/web/docs/src/components/slider.tsx
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: website-preview / deployment
- GitHub Check: test / unit
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: alpha / cli-artifacts
🔇 Additional comments (10)
packages/web/docs/src/components/slider.tsx (9)
6-6: SVG icon updated to white variant.The icon reference has been changed from green to white, which aligns with the new color scheme.
10-10: LGTM: New optional parameter properly typed.The
deadZoneproperty is correctly defined as an optional string parameter in the interface.
12-12: Function signature properly updated.The function signature correctly includes and destructures the new
deadZoneproperty from props.
18-19: UI component class refactoring.The className has been updated to use the container query feature and the style property is now properly passed through.
33-33: Color scheme updated for slider fill.Changed background color from green to beige/blue to align with the new color scheme, and the clip-path implementation looks good.
44-44: Indicator styling updated to match new color scheme.The indicator styling has been updated from green to blue, maintaining appropriate contrast for better accessibility.
54-54: Text color updated for SVG element.The color class has been updated from green to blue, consistent with the other styling changes.
134-142: Responsive animation transitions based on container width.The implementation uses container queries to apply different easing curves based on container width:
- Default: Uses
--ease-overshoot-farfor more pronounced animation- When width >= 512px: Uses
--ease-overshoot-a-bitfor subtler animationThis is a good approach to addressing the overshoot issue mentioned in the PR objectives.
148-168: Added dead zone support with zero reset button.This implementation adds a left-side button area that:
- Takes up space based on the
deadZonewidth parameter- When clicked, resets the slider to zero
- Visually appears as a blue section of the slider
The implementation correctly handles both cases (with and without dead zone) and uses event dispatch to ensure all event handlers are triggered appropriately.
This is a clean implementation that enhances the slider's functionality as mentioned in the PR objectives.
.eslintrc.cjs (1)
228-234:✅ Verification successful
Whitelist addition approved for the new
hive-sliderclass.The addition of
'hive-slider'to the tailwindcss whitelist allows this custom class to be used in the pricing plan cards without triggering linting errors. This aligns with the PR objectives for implementing the new pricing display structure with interactive plan cards.
🏁 Script executed:
#!/bin/bash # Description: Verify that the hive-slider class is being used in the codebase # Search for hive-slider usage in the docs package echo "Searching for hive-slider usage in packages/web/docs:" rg "hive-slider" --type ts --type tsx --type html --type css packages/web/docsLength of output: 223
Action Required: Update Verification Command for "hive-slider" Usage
The whitelist addition for the new
hive-sliderclass is approved as it aligns with the PR’s objective for the interactive pricing plan cards. Note that the initial verification command failed due to an unrecognized file type (tsx). Please re-run the revised script above with explicit globs to properly verify that thehive-sliderclass is utilized in the codebase.
🏁 Script executed:
#!/bin/bash # Revised search command for hive-slider usage in packages/web/docs with explicit file globs echo "Searching for hive-slider usage in packages/web/docs using explicit globs:" rg "hive-slider" packages/web/docs --glob "*.ts" --glob "*.tsx" --glob "*.html" --glob "*.css"Length of output: 654
Approval Confirmed for
hive-sliderWhitelist AdditionThe updated whitelist entry for
'hive-slider'is verified as it is actively used in the codebase (e.g., inpackages/web/docs/src/components/slider.tsx). This supports the PR objective for implementing interactive pricing plan cards without triggering linting errors.
- Verified usage in
packages/web/docs/src/components/slider.tsxusing explicit file globs.
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: 0
🧹 Nitpick comments (1)
packages/web/docs/src/components/pricing/pricing-slider.tsx (1)
50-77: Added educational tooltip about operations.This is a significant UI improvement that:
- Adds a "Learn about operations" button with a book icon
- Implements a tooltip with clear explanation of what operations mean
- Handles touch devices explicitly by checking
matchMedia('(hover: none)')- Uses Radix UI tooltip components for accessibility
The tooltip provides valuable context to users who might not understand what "operations" means in this context.
Consider adding a keyboard shortcut or ensuring the tooltip is accessible via keyboard navigation for users who rely on assistive technologies.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/web/docs/src/components/pricing/pricing-slider.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`packages/web/docs/**`: The main landing page and documentat...
packages/web/docs/**: The main landing page and documentation website. It's built using TypeScript, Tailwind, NextJS and Nextra.In PRs that adds a new feature to the product, we would like to make sure that the PR includes the following:
- Up to date documentation in
packages/web/docs/src/content- A product update in
packages/web/docs/src/app/product-updates
packages/web/docs/src/components/pricing/pricing-slider.tsx
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: website-preview / deployment
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: static-analysis / analyze (javascript)
- GitHub Check: build / dockerize (linux/arm64)
- GitHub Check: build / dockerize (linux/amd64)
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: alpha / cli-artifacts
🔇 Additional comments (8)
packages/web/docs/src/components/pricing/pricing-slider.tsx (8)
2-4: New imports for enhanced UI components.The addition of Radix UI tooltip components and the Guild component library elements improves the component's interactivity and accessibility.
7-14: Component API improvement with controlled value pattern.The updated component signature now accepts an
onChangecallback, which allows parent components to respond to slider value changes. This follows the React pattern of lifting state up and makes the component more reusable.
18-18: Added tooltip state management.Good implementation of local state to control the tooltip visibility, which is used later in the component to provide educational information about operations.
21-30: Improved UI labeling and styling.The question text has been updated to be more direct and user-friendly. The styling classes have been restructured using the
cnutility for better composition.
31-31: Enhanced styling for the slider container.The flex layout and padding adjustments provide better spacing for the slider elements.
34-34: Added deadZone parameter to the Slider component.This aligns with the PR objectives to fix the easing function for the slider to accommodate the new width. The deadzone helps prevent overshooting when the slider width changes.
Can you confirm that this deadzone value works well across different screen sizes? It would be good to test on various devices to ensure the slider behavior is consistent.
41-41: Improved counter formatting.Changed "operations" to "ops" for brevity in the counter text, which helps maintain readability while keeping the counter compact.
45-45: Implementing the onChange callback.Good implementation of propagating the slider value changes to the parent component via the onChange callback.
Description
The table is gonna go in a separate PR, because they're fairly independent and the type of their reviews differs.
There, we're gonna ensure the text is all right, and here I'd like you to vibe check if the animations feel right, tell me your thoughts on them, and test it on different screen sizes.
Work to be done