-
Notifications
You must be signed in to change notification settings - Fork 109
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
feat: add directions for publishing to no schema component #6602
base: main
Are you sure you want to change the base?
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request introduces a new React component, Changes
Possibly related PRs
🪧 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.38.1-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
@graphql-hive/cli |
0.49.1-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
@graphql-hive/core |
0.10.1-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
@graphql-hive/envelop |
0.35.1-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
@graphql-hive/yoga |
0.41.1-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
hive |
6.0.0-alpha-20250313183737-d145440f39bd98c649b1fe54ca4b1f8a0e967fc8 |
npm ↗︎ unpkg ↗︎ |
📚 Storybook DeploymentThe latest changes are available as preview in: https://038a5604.hive-storybook.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
🔭 Outside diff range comments (1)
.changeset/fuzzy-plums-repeat.md (1)
1-6
:⚠️ Potential issueIncomplete changeset documentation.
The changeset file is missing several required elements according to the coding guidelines:
- A link to the relevant GitHub issue (show CLI publish command within dashboard #6464)
- Example with before/after demonstration
- More detailed description of what was changed
Please enhance the changeset description with these details:
--- 'hive': patch --- Added directions for publishing on no schema component + +Closes #6464 + +## Before +Previously, the "no schema" state didn't provide instructions based on project type. + +## After +Now when a schema hasn't been published yet, we show project-type specific publishing instructions to help users get started.
🧹 Nitpick comments (3)
packages/web/docs/src/components/company-testimonials/index.tsx (1)
170-176
: Focus Outline Removal Adjustment.
The addition of theoutline-none
class to theTabs.Content
component (line 170) effectively removes the default browser focus outline. Please verify that this change does not negatively impact accessibility—especially if under any circumstances this content could receive focus. If a focus indicator is necessary, consider using a conditional style such asfocus-visible
to maintain keyboard navigation clarity.packages/web/app/src/pages/target-apps.tsx (1)
261-261
: Good implementation of the new component with proper props.The NoSchemaVersion component is now used correctly with the project type passed as a prop. However, the optional chaining is used here differently compared to target-explorer.tsx - both approaches work but for consistency, consider standardizing the access pattern across files.
-<NoSchemaVersion projectType={data.data?.target?.project?.type} /> +<NoSchemaVersion projectType={data.data?.target?.project?.type ?? null} />packages/web/docs/src/components/pricing/plans-table.tsx (1)
11-11
: Consider updating import pathThe icons import uses a relative path from a different directory (
../../app/gateway/federation-compatible-benchmarks/icons
). Since you've just added CheckmarkIcon and XIcon to the main icons.tsx file, you could import from there instead for better organization.-import { CheckmarkIcon, XIcon } from '../../app/gateway/federation-compatible-benchmarks/icons'; +import { CheckmarkIcon, XIcon } from '../icons';
📜 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 (25)
packages/web/app/src/components/ui/empty-list.tsx
(3 hunks)packages/web/app/src/components/ui/input-copy.tsx
(2 hunks)packages/web/app/src/pages/target-apps.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-deprecated.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-type.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-unused.tsx
(3 hunks)packages/web/app/src/pages/target-explorer.tsx
(3 hunks)packages/web/app/src/pages/target-history.tsx
(3 hunks)packages/web/app/src/pages/target.tsx
(2 hunks).changeset/fuzzy-plums-repeat.md
(1 hunks).eslintrc.cjs
(1 hunks)packages/web/docs/package.json
(1 hunks)packages/web/docs/src/app/gateway/federation-compatible-benchmarks/benchmark-table-body.tsx
(1 hunks)packages/web/docs/src/app/gateway/federation-compatible-benchmarks/functional-tones.ts
(0 hunks)packages/web/docs/src/app/gateway/federation-compatible-benchmarks/index.tsx
(1 hunks)packages/web/docs/src/app/layout.tsx
(1 hunks)packages/web/docs/src/app/pricing/page.tsx
(2 hunks)packages/web/docs/src/components/company-testimonials/index.tsx
(1 hunks)packages/web/docs/src/components/icons.tsx
(1 hunks)packages/web/docs/src/components/nested-sticky.tsx
(1 hunks)packages/web/docs/src/components/pricing/index.tsx
(1 hunks)packages/web/docs/src/components/pricing/plans-table.tsx
(1 hunks)packages/web/docs/src/components/pricing/pricing-slider.tsx
(3 hunks)packages/web/docs/src/components/slider.tsx
(2 hunks)packages/web/docs/src/easing-functions.css
(1 hunks)
💤 Files with no reviewable changes (1)
- packages/web/docs/src/app/gateway/federation-compatible-benchmarks/functional-tones.ts
🧰 Additional context used
📓 Path-based instructions (2)
`.changeset/**`: A special folder with the files created/man...
.changeset/**
: A special folder with the files created/managed by Changesets tool.
In PRs that already includes this file, please make sure that the content of the markdown file includes:
- Full description of the change
- A link to the relevant GitHub issues (if any)
- Example with before/after
- If the change is of type
major
, please ensure that the content have content about migration with before/after.
.changeset/fuzzy-plums-repeat.md
`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/package.json
packages/web/docs/src/app/layout.tsx
packages/web/docs/src/app/gateway/federation-compatible-benchmarks/benchmark-table-body.tsx
packages/web/docs/src/easing-functions.css
packages/web/docs/src/app/pricing/page.tsx
packages/web/docs/src/components/icons.tsx
packages/web/docs/src/components/slider.tsx
packages/web/docs/src/app/gateway/federation-compatible-benchmarks/index.tsx
packages/web/docs/src/components/company-testimonials/index.tsx
packages/web/docs/src/components/pricing/pricing-slider.tsx
packages/web/docs/src/components/nested-sticky.tsx
packages/web/docs/src/components/pricing/plans-table.tsx
packages/web/docs/src/components/pricing/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: static-analysis / analyze (typescript)
- GitHub Check: storybook-preview / deployment
- 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 (67)
packages/web/app/src/pages/target.tsx (2)
13-13
: Updated import to use the new NoSchemaVersion component.The import statement has been updated to include the new
NoSchemaVersion
component instead of the previousnoSchemaVersion
variable, which aligns with the PR objective of providing project-type specific publishing directions.
172-172
: Good implementation of project-type aware no-schema instructions.The code now renders the
NoSchemaVersion
component with the project type passed as a prop, allowing for project-specific publishing instructions when no schema version is available.packages/web/app/src/components/ui/input-copy.tsx (1)
7-7
: Good enhancement to InputCopy component with alignment options.The component now accepts an optional
alignment
prop that allows for more flexible styling, which will help with the display of publishing instructions.packages/web/app/src/pages/target-history.tsx (3)
6-6
: Updated import to use the new NoSchemaVersion component.The import statement has been updated to include the new
NoSchemaVersion
component, consistent with other similar changes across the codebase.
179-182
: Good addition of project type to GraphQL query.Adding the project type to the query provides the necessary data for the
NoSchemaVersion
component to display project-specific publishing instructions.
275-277
: Good implementation of project-type aware no-schema instructions.The code now conditionally renders the
NoSchemaVersion
component based on query results and passes the project type as a prop, which aligns with the PR objective of providing project-type specific publishing directions.packages/web/app/src/pages/target-explorer-type.tsx (3)
22-22
: Appropriate component naming update.Good update from importing the variable
noSchemaVersion
to the componentNoSchemaVersion
, which aligns with React component naming conventions (PascalCase).
165-168
: Well-structured GraphQL query addition.Nicely implemented query addition for the project data (id and type). This provides the necessary context for the NoSchemaVersion component.
270-270
: Good implementation of the new component with proper props.The NoSchemaVersion component is now used correctly with the project type passed as a prop. The fallback to null with the nullish coalescing operator is a good defensive programming practice.
packages/web/app/src/components/ui/empty-list.tsx (4)
1-1
: Appropriate imports for the new component functionality.Good job updating the imports to support the new component features - ReactNode for children support and ProjectType for the type safety of the new component.
Also applies to: 3-3, 8-8
15-15
: Well-implemented children support for EmptyList.Adding children support to the EmptyList component makes it more flexible and reusable. The implementation properly types the children prop and correctly renders it in the component.
Also applies to: 20-20, 37-37
25-25
: Improved padding consistency.Changed from
py-4
top-4
to provide consistent padding on all sides of the card.
52-88
: Excellent implementation of NoSchemaVersion component with project-specific instructions.The NoSchemaVersion component is well-structured and provides contextual instructions based on the project type:
- It correctly determines if the project is distributed based on the project type.
- It provides clear instructions for schema validation and publishing.
- The use of InputCopy components enhances user experience by making commands easily copyable.
- The conditional rendering logic based on project type ensures the right commands are shown.
This implementation addresses the PR objective of adding "publish instructions specific to the project type."
packages/web/app/src/pages/target-explorer.tsx (3)
19-19
: Appropriate component naming update.Good update from importing the variable
noSchemaVersion
to the componentNoSchemaVersion
, which follows React component naming conventions.
138-141
: Well-structured GraphQL query addition.Nicely implemented query addition for the project data (id and type). This provides the necessary context for the NoSchemaVersion component.
276-276
: Good implementation of the new component with proper props.The NoSchemaVersion component is now used correctly with the project type passed as a prop. The fallback to null with the nullish coalescing operator is a good defensive programming practice. Note that the property access is slightly different than in other files (using dot notation instead of optional chaining for project).
packages/web/app/src/pages/target-apps.tsx (2)
9-9
: Appropriate component naming update.Good update from importing the variable
noSchemaVersion
to the componentNoSchemaVersion
, following React component naming conventions.
64-67
: Well-structured GraphQL query addition.Nicely implemented query addition for the project data (id and type). This provides the necessary context for the NoSchemaVersion component.
packages/web/docs/src/components/nested-sticky.tsx (5)
14-19
: Well-documented purpose and necessity.The component's documentation clearly explains why this custom implementation is needed instead of using standard CSS position:sticky. This is helpful for future developers who might question why a custom implementation is used.
42-48
: Clear state definition and transition documentation.The code provides a clear explanation of the three positional states and their transitions, making the complex positioning logic easier to understand.
83-104
: Good performance optimization with requestAnimationFrame.The scroll handler correctly uses requestAnimationFrame to optimize performance and prevent excessive DOM operations during rapid scrolling events.
118-128
: Proper event listener cleanup.The component correctly removes event listeners in the cleanup function to prevent memory leaks when the component unmounts.
131-136
: Simple and clear component structure.The component's render method creates a clean DOM structure with placeholder and content divs that work with the positioning logic, keeping the implementation straightforward.
packages/web/app/src/pages/target-explorer-unused.tsx (3)
9-9
: Updated import to use new NoSchemaVersion component.The import has been correctly updated to import the
NoSchemaVersion
component instead of the previousnoSchemaVersion
variable/constant.
240-243
: Added project information to GraphQL query.The GraphQL query has been enhanced to fetch project information, including its type, which supports the new feature for providing project-type-specific instructions.
362-362
: Implemented NoSchemaVersion with project type.The component implementation now uses the new
NoSchemaVersion
component and correctly passes the project type from the query data.packages/web/app/src/pages/target-explorer-deprecated.tsx (3)
10-10
: Updated import to use new NoSchemaVersion component.The import statement has been updated to use the new
NoSchemaVersion
component.
168-171
: Added project information to GraphQL query.The GraphQL query now includes project information, consistent with other files in this PR.
310-310
: Implemented NoSchemaVersion with proper null handling.The implementation correctly uses the new
NoSchemaVersion
component and includes a null check with the nullish coalescing operator (??
) to handle cases where project type might be undefined..eslintrc.cjs (1)
234-234
: Added new 'subheader' class to Tailwind whitelistThis addition allows the use of a custom 'subheader' class in the documentation files, which supports the styling needed for the new publishing directions component.
packages/web/docs/package.json (1)
31-31
: Package version update for Tailwind configUpdated
@theguild/tailwind-config
from a previous version to0.6.3
, which aligns with the UI enhancements being made in this PR.packages/web/docs/src/app/layout.tsx (1)
20-20
: Added import for new easing functions CSSThe new CSS file adds custom easing functions that will likely be used for animations in the new publishing directions component.
packages/web/docs/src/app/pricing/page.tsx (1)
13-13
:❓ Verification inconclusive
Added PlansTable component to pricing page
The PlansTable component enhances the pricing page with a detailed table of plans and features, improving the user experience when comparing different options.
Also applies to: 30-31
🌐 Web query:
Does the PR include documentation updates in packages/web/docs/src/content and a product update in packages/web/docs/src/app/product-updates as required by the coding guidelines?
💡 Result:
To determine whether a pull request (PR) includes required documentation updates and product updates as per coding guidelines, several key factors from industry standards and best practices should be considered:
Documentation Requirements
Coding Guidelines Compliance:
- Documentation updates in
packages/web/docs/src/content
should follow structured formats (e.g.,README.md
,CHANGELOG.md
, and API docs) to ensure clarity and maintainability [3][12].- Versioned documentation must reflect changes accurately, including updates to dependencies or new features [3][6][9].
Automated Validation:
- Tools like
dart doc
(for Flutter) or CI/CD checks often enforce documentation standards, ensuring updates are properly formatted and linked [3][12].Product Update Requirements
Release Tracking:
- Product updates in
packages/web/docs/src/app/product-updates
should align with product requirements document (PRD) principles, including:
- Clear purpose and scope [2][5][8]
- Timelines and release criteria [5][8][14]
- Stakeholder-reviewed feature descriptions [5][18]
Versioning and Dependency Management:
- Changes to package dependencies (e.g., in
pubspec.yaml
orbuild.gradle
) must follow semantic versioning rules and include updates to related documentation [3][6][9].- Automated PR Services (e.g., in Yocto) ensure linear versioning and compatibility with package managers [6][9].
Verification Steps
To confirm compliance:
- Check for:
- Updated markdown files in
/content
with API/usage examples [3][12].- Product update notes in
/product-updates
detailing feature scope and timelines [5][8][14].- Validate version bumps in package manifests (e.g.,
pubspec.yaml
,package.json
) [6][9][15].- Ensure automated checks (e.g., CI/CD pipelines) pass for documentation and build processes [3][6][12].
If these elements are present and follow the project’s specific coding guidelines, the PR meets the requirements. For exact compliance, cross-reference the PR with the project’s stated documentation policies [12][18].
Citations:
- 1: https://icd10monitor.medlearn.com/updating-the-facility-specific-coding-guidelines-part-1/
- 2: https://www.productplan.com/glossary/product-requirements-document/
- 3: https://docs.flutter.dev/packages-and-plugins/developing-packages
- 4: https://icd10monitor.medlearn.com/updating-facility-specific-coding-guidelines/
- 5: https://www.aha.io/roadmapping/guide/requirements-management/what-is-a-good-product-requirements-document-template
- 6: https://docs.yoctoproject.org/dev-manual/packages.html
- 7: https://edhub.ama-assn.org/steps-forward/module/2813035
- 8: https://www.perforce.com/blog/alm/how-write-product-requirements-document-prd
- 9: https://docs.yoctoproject.org/dev/dev-manual/packages.html
- 10: https://hcahealthcare.com/util/forms/ethics/policies/regulatory-compliance-support/REGSCOD002-a.pdf
- 11: https://document360.com/blog/product-requirements-document/
- 12: https://www.odoo.com/documentation/18.0/contributing/development/coding_guidelines.html
- 13: https://www.cms.gov/files/document/fy-2022-icd-10-cm-coding-guidelines-updated-02012022.pdf
- 14: https://zeda.io/blog/product-requirement-document
- 15: https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Client-side_tools/Package_management
- 16: https://www.aafp.org/family-physician/practice-and-career/getting-paid/coding/evaluation-management.html
- 17: https://en.wikipedia.org/wiki/Product_requirements_document
- 18: https://rpm-packaging-guide.github.io
- 19: https://www.compliance.cuimc.columbia.edu/compliance-standards/evaluation-and-management-e-m-guidelines/documentation-guidelines-cpt-e-m-codes
- 20: https://www.atlassian.com/agile/product-management/requirements
PlansTable Component Integration Confirmed
The addition of the PlansTable component on the pricing page enhances the user experience by providing a detailed comparison of available plans. Please ensure that the PR also includes the required updates as per the coding guidelines:
- Documentation updates in
packages/web/docs/src/content
- A corresponding product update in
packages/web/docs/src/app/product-updates
These updates are essential to maintain compliance with our standards and to provide complete context for this feature.
Applies also to lines 30–31.
packages/web/docs/src/easing-functions.css (1)
1-41
: Well-implemented custom easing functionsThe CSS file defines two custom easing functions (
--hive-ease-overshoot-far
and--hive-ease-overshoot-a-bit
) using the modernlinear()
function, which provides precise control over animation timing. These appear to create sophisticated overshoot effects where animations slightly exceed their target before settling.packages/web/docs/src/components/pricing/index.tsx (1)
292-294
: LGTM: Clean markup restructuringThe change wraps the "Shape a custom plan" text and the conditionally displayed "for your business" phrase in a single parent
<span>
, creating a more semantic HTML structure while preserving the responsive behavior.packages/web/docs/src/app/gateway/federation-compatible-benchmarks/benchmark-table-body.tsx (5)
49-57
: Good migration to Tailwind utility classesReplacing inline styles with Tailwind CSS utility classes improves maintainability and consistency. The conditional classes based on compatibility percentage are well-structured.
63-65
: Consistent styling approachGood use of the
text-positive-dark
class for successful test indicators, aligning with the design system approach.
67-70
: Consistent styling approachGood use of the
text-critical-dark
class for failed test indicators, maintaining consistency with the rest of the application.
73-75
: Consistent styling approachSame improvements as above, applying the
text-positive-dark
class for passed test suites.
77-80
: Consistent styling approachSame improvements as above, applying the
text-critical-dark
class for failed test suites.packages/web/docs/src/app/gateway/federation-compatible-benchmarks/index.tsx (5)
92-93
: Consistent use of Tailwind classesGood replacement of inline styling with the appropriate Tailwind utility class
text-positive-dark
for passed tests icon.
95-96
: Consistent use of Tailwind classesGood replacement of inline styling with the appropriate Tailwind utility class
text-critical-dark
for failed tests icon.
99-101
: Consistent styling approachGood use of the
bg-positive-bright
Tailwind class for perfect compatibility indicator, aligning with the styling updates in the table body component.
103-105
: Consistent styling approachGood use of the
bg-warning-bright
Tailwind class for moderate compatibility indicator, maintaining consistency across components.
107-109
: Consistent styling approachGood use of the
bg-critical-dark
Tailwind class for low compatibility indicator, completing the consistent styling approach.packages/web/docs/src/components/icons.tsx (3)
1-2
: Clear documentation commentGood addition of a comment explaining the distinction between these new icons and the existing ones in the design system. This prevents confusion for other developers.
3-9
: Well-implemented CheckmarkIcon componentThe CheckmarkIcon implementation follows best practices:
- Proper typing with React.SVGProps
- Consistent viewBox and dimensions
- Using currentColor for fill to inherit parent text color
- Spreading additional props to the SVG element
This allows for flexible usage and styling throughout the application.
11-17
: Well-implemented XIcon componentThe XIcon follows the same good implementation pattern as CheckmarkIcon, ensuring consistency between the two related components.
packages/web/docs/src/components/slider.tsx (3)
94-95
: Good refactor to use global easing variablesThe transition property now uses the global
--hive-ease-overshoot-far
variable instead of a local CSS custom property, which promotes consistency across the application.
100-101
: Consistent update to global easing variableSimilarly, this transition now uses the global
--hive-ease-overshoot-a-bit
variable, maintaining consistency with the change on line 94.
113-114
: Added vertical spacing to buttonThe addition of
my-3
class adds vertical margin to the button whendeadZone
is defined, improving the visual spacing.packages/web/docs/src/components/pricing/pricing-slider.tsx (5)
19-19
: Updated ref type to match new elementThe
rootRef
type has been changed fromHTMLLabelElement
toHTMLDivElement
to align with the change of the root element from a label to a div.
22-27
: Semantic HTML improvementChanged the root element from a
<label>
to a<div>
, which is more appropriate since this component doesn't directly label a form control. Also simplified the counter-set CSS property.
32-46
: Improved component structure with better responsive behaviorThe inner structure has been improved with:
- Adding
aria-hidden
attribute for accessibility- Better class organization for styling
- Additional div on line 45 that conditionally hides "per month" text on smaller screens
This enhances the responsive behavior of the component.
54-55
: Added aria-label for better accessibilityGood addition of an
aria-label
to the Slider component, which provides context for screen readers about the purpose of the slider control.
60-61
: Enhanced counter property with additional stylingThe counter property now includes an additional counter-set for price calculation, improving the dynamic styling capabilities of the component.
packages/web/docs/src/components/pricing/plans-table.tsx (11)
1-20
: Well-structured imports and component organizationThe file has a clean organization with:
- Client-side directive for Next.js
- Properly grouped imports from external and internal sources
- Good separation between React components and custom icons
This creates a maintainable foundation for the pricing table implementation.
21-26
: Clear type definitions for plan structureGood use of TypeScript with a
PlanName
type andPricingPlan
interface to enforce consistent data structure for the pricing plans.
27-65
: Well-structured pricing tiers dataThe pricing tiers are defined with consistent structure including:
- Clear plan names
- Call-to-action buttons with appropriate variants
- Proper URL destinations for each plan
The TODO comment on line 33 about moving the style to the design system is a good reminder for future improvements.
67-72
: Good component setup with state managementThe PlansTable component is properly implemented with:
- useState hook for tracking the active plan
- Clean props interface with optional className
- Reusable icon constants for consistent usage throughout the table
This creates a solid foundation for the component.
73-86
: Well-structured layout with responsive designThe section layout includes:
- Proper heading hierarchy
- Responsive text alignment and spacing
- Text breaks for different viewport sizes
- Concise and informative description
This creates a visually appealing introduction to the pricing plans.
90-106
: Excellent header implementation with sticky behaviorThe table header uses:
- NestedSticky component for fixed positioning while scrolling
- Conditional styling when sticky (using CSS attribute selectors)
- Responsive design with hidden elements on mobile
- Good semantic structure with proper rounded corners
This creates a polished user experience when scrolling through the pricing table.
107-114
: Accessible table structureGood use of semantic HTML table elements with:
- Proper thead and tbody structure
- Screen reader only (sr-only) header text
- Mapping of plan names to table headers
This ensures the table is accessible to all users.
115-338
: Comprehensive feature comparison with organized sectionsThe table body contains:
- Logical grouping of features with TableSubheaderRow components
- Consistent cell structure and styling
- Clear feature descriptions and values for each plan
- Appropriate use of icons and links
This provides users with a detailed comparison of the different plans.
346-397
: Responsive mobile navigation implementationThe MobileNavbar component:
- Uses NestedSticky for optimal positioning
- Implements an interactive plan selector
- Shows/hides call-to-action buttons based on selected plan
- Has smooth transitions and focus states
This ensures a good user experience on mobile devices.
399-422
: Flexible table cell component with conditional renderingThe PlansTableCell component:
- Handles visibility based on active plan
- Uses aria-hidden for accessibility
- Implements complex conditional styling with Tailwind
- Supports optional classNames for customization
This creates a reusable component for consistent table cell rendering.
424-441
: Well-structured section header componentThe TableSubheaderRow component:
- Has a clear interface definition
- Uses colSpan to span the entire table width
- Includes icon, title, and description
- Has responsive styling for different screen sizes
This creates visually distinct section headers within the pricing table.
docsUrl="/features/schema-registry#publish-a-schema" | ||
/> | ||
); | ||
// @todo consider monolith vs distributed etc |
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.
💡 Verification agent
🧩 Analysis chain
TODO comment needs addressing.
There's a TODO comment that should be addressed or at least converted to a more specific task.
🏁 Script executed:
#!/bin/bash
# Let's search for other TODO comments in the codebase to understand the convention
echo "Searching for TODO comments in the codebase..."
rg -n "@todo|TODO" --type ts --type tsx
Length of output: 172
Assuming the output now includes the following line from the file packages/web/app/src/components/ui/empty-list.tsx
:
packages/web/app/src/components/ui/empty-list.tsx:51:// @todo consider monolith vs distributed etc
Action Required: Update TODO Comment Specificity
- Location:
packages/web/app/src/components/ui/empty-list.tsx:51
- Issue: The current TODO comment is too generic. It should be updated to a clearly defined task or removed if no longer applicable.
- Recommendation: Replace the comment with a specific action item—e.g., clarify what monolith versus distributed architecture considerations need to be addressed—so that the task is actionable and traceable.
🏁 Script executed:
#!/bin/bash
# Re-run the TODO search with proper file extension patterns for TypeScript files
echo "Searching for TODO comments in the codebase for .ts and .tsx files..."
rg -n "@todo|TODO" -g "*.{ts,tsx}"
Length of output: 7423
Action: Update the TODO Comment for Clarity
- Location:
packages/web/app/src/components/ui/empty-list.tsx
(line 51) - Issue: The current comment (
// @todo consider monolith vs distributed etc
) is too vague. It should be turned into a specific, actionable task or be removed if it’s no longer relevant. - Recommendation: Specify what needs to be evaluated or refactored. For example, update it to something like:
// TODO: Determine if a monolithic or distributed architecture better suits our scalability needs and document the decision.
🐋 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/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/wieq95okrkc2z3iq78xef6kx5",
"containerimage.config.digest": "sha256:252a36678799923532a9ffe6097e99b5346dfeb12373f09e96a53e085e413265",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:6fc5405a124b187ea2eca7bde2a9a0174a544b0fd26b59fd4e17cdf2a9882771",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:6fc5405a124b187ea2eca7bde2a9a0174a544b0fd26b59fd4e17cdf2a9882771",
"image.name": "ghcr.io/graphql-hive/app:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/app:publish_directions-amd64"
},
"buildx.build.warnings": [
{
"vertex": "sha256:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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
}
}
]
},
{
"vertex": "sha256:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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:b670fc0f910ee67bca8a8577a09d12bf8e6fbb784c0317b44bf30634cc573a4c",
"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:4730609c2e57630cfa51d7d8b0aa53ea36076ca7ef586403a97ec020100a4578",
"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
}
}
]
}
],
"commerce": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/zpv9q0r0hrmbcvyfth61i5n75",
"containerimage.config.digest": "sha256:2aa93152cbd90d532eeef606c8772e166e88cc49cbd91a54202659f2f856e825",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:f6eb5cbe72193bdc129ac74060b741d2e1de5c8fc625acd74a692734340e4854",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:f6eb5cbe72193bdc129ac74060b741d2e1de5c8fc625acd74a692734340e4854",
"image.name": "ghcr.io/graphql-hive/commerce:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/commerce:publish_directions-amd64"
},
"composition-federation-2": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/ypi4y7thgw9mnp8v9uupewpl8",
"containerimage.config.digest": "sha256:5053489fd870c522a071f8e361b18555b096a481a24166f2783a34b6406a21fd",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:33796f008f2d56aea108d3c45262378588474b6b09fdd9a22a878cc603998158",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:33796f008f2d56aea108d3c45262378588474b6b09fdd9a22a878cc603998158",
"image.name": "ghcr.io/graphql-hive/composition-federation-2:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/composition-federation-2:publish_directions-amd64"
},
"emails": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/194h5giy5b1mnjxkqi9fvxwnd",
"containerimage.config.digest": "sha256:5d0a2a6e44caa12905abd6f1bdc1e4248dd6aebfacc480e902bb295d42ca3f7d",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:7b6f2977cfdb33d1cde75009f52b5b051de6bf7a3f4eec511042ba745fae8a16",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:7b6f2977cfdb33d1cde75009f52b5b051de6bf7a3f4eec511042ba745fae8a16",
"image.name": "ghcr.io/graphql-hive/emails:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/emails:publish_directions-amd64"
},
"policy": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/z9sir3ff5hm4ngp4g922he522",
"containerimage.config.digest": "sha256:f0c8b50195ad9090c3a17d69c027e0d1d10eca9709eadf22474f3cb76741dbcc",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e480f80037f7274c469eb7cd32ab9d485838b63c3bf1a7e66bd836496f8a9fbb",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:e480f80037f7274c469eb7cd32ab9d485838b63c3bf1a7e66bd836496f8a9fbb",
"image.name": "ghcr.io/graphql-hive/policy:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/policy:publish_directions-amd64"
},
"schema": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/ip045b2lotb99jnrhvp6tqjts",
"containerimage.config.digest": "sha256:81fe5e75b77c804691fd9796fc935b4f7c4dc316aa35e59a935bc12b44b7f03d",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:0fa065c469fd2eb84d7ae7e0813cb2faadae5edb68f619fbb6139a0c0b57ca4f",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:0fa065c469fd2eb84d7ae7e0813cb2faadae5edb68f619fbb6139a0c0b57ca4f",
"image.name": "ghcr.io/graphql-hive/schema:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/schema:publish_directions-amd64"
},
"server": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/x6o34ag82t57egia2kx6acv33",
"containerimage.config.digest": "sha256:6f9924b83e87ce71f31c99be3b5afc23267a3ecdd135b8579d3f9aff8a0e237e",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:ec0876a0778c4b8d2bfcfb60f554aaa7dc8bd98209e93451ac02614dbea1d359",
"size": 2076,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:ec0876a0778c4b8d2bfcfb60f554aaa7dc8bd98209e93451ac02614dbea1d359",
"image.name": "ghcr.io/graphql-hive/server:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/server:publish_directions-amd64"
},
"storage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"context:dist": "local:dist",
"context:shared": "local:shared",
"frontend.caps": "moby.buildkit.frontend.contexts+forward",
"local-sessionid:context": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/og55xzl691qr3mm2x118j4fbf",
"containerimage.config.digest": "sha256:4ac21c2b08a86560f79edbd42b6f16a6e4095f87f632b1e08501051d916c0ba2",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:e67baea8466aad431ab1b0e4d25772799dddf02e7536299f08c0d866e7dcd749",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:e67baea8466aad431ab1b0e4d25772799dddf02e7536299f08c0d866e7dcd749",
"image.name": "ghcr.io/graphql-hive/storage:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/storage:publish_directions-amd64"
},
"tokens": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/7qb6mk76fktnsvcuw631qsst8",
"containerimage.config.digest": "sha256:08d87db35dac8f438dc5468dafbe0d4a755e5562aa92b45dbe11c26d5453dc31",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:073e5da93d691cf082295c2a62fd201d63fce67105e0ee803ccd851baa9cc4a7",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:073e5da93d691cf082295c2a62fd201d63fce67105e0ee803ccd851baa9cc4a7",
"image.name": "ghcr.io/graphql-hive/tokens:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/tokens:publish_directions-amd64"
},
"usage": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/zqmfcxgfync5xyoaxfv4p3r1v",
"containerimage.config.digest": "sha256:b896def688912b0f0d65401ecd9298fbc0c23a735a5e5fbeefa319d904a687f2",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:c4dd2ad31fcfb289e6a36ec2349316b656b33e765cfad3a5323c4433b1700bbe",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:c4dd2ad31fcfb289e6a36ec2349316b656b33e765cfad3a5323c4433b1700bbe",
"image.name": "ghcr.io/graphql-hive/usage:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/usage:publish_directions-amd64"
},
"usage-ingestor": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/9w30fc1u6kqx6cqqb3onn20k3",
"containerimage.config.digest": "sha256:8f2f89e4b6947e134d612814e61863c79176b118aa81dfb977de0d91cd861bc9",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:b17dc27ff4ba8b050594849efdfd0c1587e195e874ace23c6e5430fb9107648e",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:b17dc27ff4ba8b050594849efdfd0c1587e195e874ace23c6e5430fb9107648e",
"image.name": "ghcr.io/graphql-hive/usage-ingestor:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/usage-ingestor:publish_directions-amd64"
},
"webhooks": {
"buildx.build.provenance": {
"buildType": "https://mobyproject.org/buildkit@v1",
"materials": [
{
"uri": "pkg:docker/[email protected]?platform=linux%2Famd64",
"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": "d145440f39bd98c649b1fe54ca4b1f8a0e967fc8",
"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": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:dockerfile": "dmudcr0texb04xthgjyldqbdu",
"local-sessionid:shared": "dmudcr0texb04xthgjyldqbdu"
},
"locals": [
{
"name": "context"
},
{
"name": "dist"
},
{
"name": "dockerfile"
},
{
"name": "shared"
}
]
},
"environment": {
"platform": "linux/amd64"
}
}
},
"buildx.build.ref": "builder-961973a8-c735-4168-8c29-41b6399c4c2c/builder-961973a8-c735-4168-8c29-41b6399c4c2c0/ybjdonun77ttquyh7263shkpd",
"containerimage.config.digest": "sha256:32f1f593ddadb049e797ecaa6b1b2aaa0b8e2f4300ff41fade3fc419b60e7c08",
"containerimage.descriptor": {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"digest": "sha256:9b3f318b56fddbdc94c44a693d7f492d1be4c7230241a7579c79b645491da1a4",
"size": 2075,
"platform": {
"architecture": "amd64",
"os": "linux"
}
},
"containerimage.digest": "sha256:9b3f318b56fddbdc94c44a693d7f492d1be4c7230241a7579c79b645491da1a4",
"image.name": "ghcr.io/graphql-hive/webhooks:d145440f39bd98c649b1fe54ca4b1f8a0e967fc8-amd64,ghcr.io/graphql-hive/webhooks:publish_directions-amd64"
}
} |
I didnt see any existing component that matched this aesthetic. But I can add monospacing to the input. Regarding check vs publish, I think on the check page I'd be okay showing just the check command, but for the schema or explorer, I'd prefer showing both check and publish. I think we should encourage best practices and checking the schema prior to publishing makes the most sense. |
6714201
to
27f25e4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 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 (27)
packages/web/app/src/components/ui/empty-list.tsx
(3 hunks)packages/web/app/src/components/ui/input-copy.tsx
(1 hunks)packages/web/app/src/pages/target-apps.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-deprecated.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-type.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-unused.tsx
(3 hunks)packages/web/app/src/pages/target-explorer.tsx
(3 hunks)packages/web/app/src/pages/target-history.tsx
(3 hunks)packages/web/app/src/pages/target.tsx
(2 hunks).changeset/fuzzy-plums-repeat.md
(1 hunks)packages/web/app/src/pages/target-apps.tsx
(1 hunks).changeset/neat-ladybugs-pay.md
(1 hunks)packages/web/app/src/components/ui/input-copy.tsx
(1 hunks)packages/web/app/src/pages/target-apps.tsx
(1 hunks)packages/web/app/src/pages/target-apps.tsx
(0 hunks)packages/web/app/src/components/ui/input-copy.tsx
(1 hunks)packages/web/app/src/components/ui/empty-list.tsx
(2 hunks)packages/web/app/src/components/ui/input-copy.tsx
(2 hunks)packages/web/app/src/pages/target-apps.tsx
(1 hunks)packages/web/app/src/pages/target-checks.tsx
(3 hunks)packages/web/app/src/pages/target-explorer-deprecated.tsx
(1 hunks)packages/web/app/src/pages/target-explorer-type.tsx
(1 hunks)packages/web/app/src/pages/target-explorer-unused.tsx
(1 hunks)packages/web/app/src/pages/target-explorer.tsx
(1 hunks)packages/web/app/src/pages/target-history.tsx
(1 hunks)packages/web/app/src/pages/target.tsx
(1 hunks).changeset/neat-ladybugs-pay.md
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .changeset/neat-ladybugs-pay.md
🚧 Files skipped from review as they are similar to previous changes (17)
- packages/web/app/src/components/ui/input-copy.tsx
- packages/web/app/src/components/ui/input-copy.tsx
- .changeset/fuzzy-plums-repeat.md
- packages/web/app/src/pages/target-explorer-unused.tsx
- packages/web/app/src/pages/target-apps.tsx
- packages/web/app/src/components/ui/input-copy.tsx
- packages/web/app/src/pages/target-apps.tsx
- packages/web/app/src/pages/target-apps.tsx
- packages/web/app/src/components/ui/input-copy.tsx
- packages/web/app/src/pages/target.tsx
- packages/web/app/src/pages/target-explorer.tsx
- packages/web/app/src/pages/target-apps.tsx
- packages/web/app/src/pages/target-apps.tsx
- packages/web/app/src/pages/target.tsx
- packages/web/app/src/pages/target-explorer-type.tsx
- packages/web/app/src/pages/target-explorer-deprecated.tsx
- packages/web/app/src/pages/target-explorer.tsx
🧰 Additional context used
📓 Path-based instructions (1)
`.changeset/**`: A special folder with the files created/man...
.changeset/**
: A special folder with the files created/managed by Changesets tool.
In PRs that already includes this file, please make sure that the content of the markdown file includes:
- Full description of the change
- A link to the relevant GitHub issues (if any)
- Example with before/after
- If the change is of type
major
, please ensure that the content have content about migration with before/after.
.changeset/neat-ladybugs-pay.md
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: test / unit
- GitHub Check: typescript / typecheck
- GitHub Check: storybook-preview / deployment
- 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: alpha / cli-artifacts
- GitHub Check: code-style / eslint-and-prettier
🔇 Additional comments (18)
packages/web/app/src/pages/target-explorer-type.tsx (1)
270-273
: Clean implementation of the recommended action prop.The addition of the
recommendedAction="publish"
prop to theNoSchemaVersion
component is well-implemented. This enhancement provides contextual guidance for users when there's no schema version available..changeset/neat-ladybugs-pay.md (2)
2-2
: Appropriate severity level change to major.The severity change from minor to major is appropriate given that the changes introduce breaking environment variable requirements for the
usage
service.
4-17
: Well-documented changeset with comprehensive links.The changeset includes detailed information about the new organization access tokens feature, lists the breaking changes regarding required environment variables, and provides comprehensive links to documentation and migration guides.
🧰 Tools
🪛 LanguageTool
[typographical] ~12-~12: Consider adding a comma here.
Context: ...DIS_TLS_ENABLED`). For more information please refer to the organization access token ...(PLEASE_COMMA)
packages/web/app/src/pages/target-history.tsx (1)
276-279
: Clean implementation of the recommended action prop.The addition of the
recommendedAction="publish"
prop to theNoSchemaVersion
component is consistent with the approach used in other files and provides appropriate context for users when no schema version is available.packages/web/app/src/pages/target-checks.tsx (3)
7-7
: Good import restructuring.Properly updated the import to include the
NoSchemaVersion
component needed for the UI enhancement.
199-202
: Appropriate addition of project type data.Added the project fields needed to support the enhanced
NoSchemaVersion
component's functionality.
365-374
: Effective implementation of the checks tab feedback.This change nicely implements the feedback to show the check command on the checks tab. The conditional rendering ensures users see relevant instructions based on their context - either the empty list message when a schema check is active or the
NoSchemaVersion
component with "check" as the recommended action when there are no schema checks.packages/web/app/src/components/ui/empty-list.tsx (7)
1-1
: Added ReactNode import for children supportGood addition of ReactNode to support the new children prop in EmptyList component.
3-3
: Import ProjectType for schema type detectionThe ProjectType import from graphql schema enables conditional rendering based on federation/stitching vs. monolith projects.
8-8
: Added InputCopy import for command displayGood addition of InputCopy component that will be used to display CLI commands in a copyable format.
15-15
: Added children prop to EmptyList componentGood enhancement to the EmptyList component, making it more flexible by allowing it to accept and render child elements.
Also applies to: 20-20
25-25
: Improved Card paddingChanged padding from
py-4
(vertical only) top-4
(all sides) to ensure consistent spacing around all content.
37-37
: Added children renderingSimple but important addition to render the optional children prop within the EmptyList component.
51-51
: Update the vague TODO commentThis TODO comment lacks specificity and remains unaddressed from a previous review.
The comment should be made more specific or removed if no longer applicable. Consider updating it to clearly describe what architectural decisions need to be made regarding monolith vs. distributed systems.
packages/web/app/src/pages/target-explorer-unused.tsx (2)
9-9
: Updated NoSchemaVersion importUpdated the import to use the new component-based approach rather than the previous constant.
240-243
: Added project type data fetchingGood addition of project fields to the GraphQL query to support the project type-based instructions in NoSchemaVersion.
packages/web/app/src/pages/target-explorer-deprecated.tsx (2)
10-10
: Updated NoSchemaVersion importUpdated the import to use the new component-based approach rather than the previous constant.
168-171
: Added project type data fetchingGood addition of project fields to the GraphQL query to support the project type-based instructions in NoSchemaVersion.
We can create the component with that aesthetic based on https://github.com/search?q=repo%3Ashuding%2Fnextra%20nextra-code&type=code |
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: 3
🧹 Nitpick comments (7)
packages/web/app/src/components/ui/empty-list.tsx (1)
51-105
: Well-implemented NoSchemaVersion component with conditional rendering.The new component properly implements the requirements from the PR objectives:
- Replaces the older export with a proper React component
- Uses monospaced font for commands via the
Code
component- Supports different project types with appropriate command formatting
- Conditionally renders instructions based on the
recommendedAction
propThe separation of check and publish commands provides a better user experience, as mentioned in the PR feedback.
One suggestion to consider: the duplication of the command display logic between the check and publish sections could potentially be extracted into a helper function for better maintainability.
export const NoSchemaVersion = ({ projectType = null, recommendedAction = 'none', }: { projectType: ProjectType | null; recommendedAction: 'publish' | 'check' | 'none'; }): ReactElement => { let children: ReactElement | null = null; + + const renderCommandSection = (message: ReactNode, command: string) => ( + <> + <div className="flex w-full justify-center py-2 text-xs text-gray-500"> + {message} + </div> + <div className="flex w-full justify-center"> + <Code>{command}</Code> + </div> + </> + ); + if (recommendedAction !== 'none') { const isDistributed = projectType === ProjectType.Federation || projectType === ProjectType.Stitching; if (recommendedAction === 'check') { children = ( - <> - <div className="flex w-full justify-center py-2 text-xs text-gray-500"> - It's recommended to check that the schema is valid and compatible with the state of the - registry before publishing. - </div> - <div className="flex w-full justify-center"> - <Code> - {`hive schema:check ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>`} - </Code> - </div> - </> + renderCommandSection( + <> + It's recommended to check that the schema is valid and compatible with the state of the + registry before publishing. + </>, + `hive schema:check ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>` + ) ); } else if (recommendedAction === 'publish') { children = ( - <> - {isDistributed && ( - <div className="flex w-full justify-center py-2 text-xs text-gray-500"> - For distributed systems, it's recommended to publish the schema after the service is - deployed. - </div> - )} - <div className="flex w-full justify-center"> - <Code> - {`hive schema:publish ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>`} - </Code> - </div> - </> + <> + {isDistributed && renderCommandSection( + <> + For distributed systems, it's recommended to publish the schema after the service is + deployed. + </>, + `hive schema:publish ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>` + )} + {!isDistributed && renderCommandSection( + null, + `hive schema:publish ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>` + )} + </> ); } }packages/web/app/src/lib/hooks/use-timed.ts (2)
3-14
: Consider adding type annotation for return valueWhile
as const
works, explicit type annotations would improve readability and make the hook's API more self-documenting.-export function useTimed(wait: number = 1000) { +export function useTimed(wait: number = 1000): [boolean, () => void] { const [timer, setTimer] = useState<NodeJS.Timeout | null>(null); const handler = () => { if (timer) { clearTimeout(timer); } setTimer(setTimeout(() => { setTimer(null) }, wait)); } return [timer !== null, handler] as const; }
5-12
: Improve indentation consistencyThere's inconsistent indentation in the
if
block (4 spaces) compared to the rest of the function (2 spaces).const handler = () => { if (timer) { - clearTimeout(timer); + clearTimeout(timer); } setTimer(setTimeout(() => { setTimer(null) }, wait)); }packages/web/app/src/lib/hooks/use-hover.ts (2)
17-26
: Consider simplifying element node checkThe element node type check can be simplified using
instanceof
for better readability.- if (previousNode.current?.nodeType === Node.ELEMENT_NODE) { + if (previousNode.current instanceof HTMLElement) { previousNode.current.removeEventListener( 'mouseenter', handleMouseEnter ); previousNode.current.removeEventListener( 'mouseleave', handleMouseLeave ); }Make the same change for the check on line 28.
3-39
: Consider adding explicit return typeAdding an explicit return type would improve readability and make the hook's API more self-documenting.
-export function useHover() { +export function useHover(): [(node: HTMLElement) => void, boolean] { const [hovering, setHovering] = useState(false); const previousNode = useRef<Node | null>(null); // rest of implementation return [customRef, hovering] as const; }packages/web/app/src/components/ui/code.tsx (2)
29-43
: Improve accessibility for the copy buttonThe button lacks some accessibility attributes. Adding
aria-label
and proper states would improve accessibility.<button data-hovering={hovering || copied} className="cursor-pointer opacity-0 data-[hovering=true]:transition-opacity data-[hovering=true]:opacity-100 hover:text-orange-600 absolute right-3 top-2 p-2 border border-gray-600 rounded-md" + aria-label={copied ? "Copied" : "Copy to clipboard"} + aria-pressed={copied} onClick={async (ev) => { // existing code }} title="Copy to clipboard" > {copied ? <CheckIcon size={16} /> : <CopyIcon size={16} />} </button>
13-16
: Use meaningful class names instead of utility classesThe component uses utility classes directly for styling. Consider extracting these to a meaningful class name for better maintainability.
Instead of:
<span ref={ref} className="flex items-center gap-2 break-all rounded-md bg-black p-4 font-mono text-sm relative pr-14 border border-gray-600" >Consider creating a separate CSS class or styled component:
<span ref={ref} className={cn('code-container', className)} >This would make the component's styling more maintainable and allow for easier theming.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/web/app/src/components/ui/code.tsx
(1 hunks)packages/web/app/src/components/ui/empty-list.tsx
(3 hunks)packages/web/app/src/components/ui/icon.tsx
(1 hunks)packages/web/app/src/lib/hooks/use-hover.ts
(1 hunks)packages/web/app/src/lib/hooks/use-timed.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: alpha / npm / snapshot
- GitHub Check: storybook-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: alpha / cli-artifacts
- GitHub Check: code-style / eslint-and-prettier
- GitHub Check: Mend Security Check
🔇 Additional comments (4)
packages/web/app/src/components/ui/empty-list.tsx (2)
1-8
: Clean import additions to support the new component functionality.The new imports (
ReactNode
,ProjectType
, andCode
) properly support the enhanced component functionality. Using theCode
component aligns with the feedback to display commands in monospaced font.
10-41
: Good enhancement to EmptyList with children support.The addition of the optional
children
prop toEmptyList
enables dynamic content rendering, which is essential for the newNoSchemaVersion
component. The placement of children before the docs link creates a logical UI flow.packages/web/app/src/components/ui/icon.tsx (1)
234-239
: Improved CheckIcon flexibility with optional size prop.The addition of an optional
size
prop to theCheckIcon
component brings it in line with other icon components in the file (likePlusIcon
,CopyIcon
, andPackageIcon
). This improves component consistency and flexibility, allowing the icon to be resized as needed in different UI contexts.packages/web/app/src/lib/hooks/use-hover.ts (1)
3-39
: Well-implemented hook with proper cleanupThe
useHover
hook is well-implemented with proper event listener management, callback memoization, and cleanup. It's a good example of managing DOM event listeners in React.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/web/app/src/components/ui/code.tsx (1)
26-33
:⚠️ Potential issueAdd error handling for clipboard operations
The clipboard operation can fail (e.g., if permission is denied), but there's no error handling. Consider adding a try/catch block.
onClick={async ev => { const value = children?.valueOf().toString(); if (value) { ev.preventDefault(); startCopyTimer(); - await navigator.clipboard.writeText(value); + try { + await navigator.clipboard.writeText(value); + } catch (error) { + console.error('Failed to copy text to clipboard:', error); + // Optionally show an error notification to the user + } } }}
🧹 Nitpick comments (3)
packages/web/app/src/components/ui/code.tsx (1)
11-38
: Improve accessibility with ARIA attributesThe copy button lacks proper accessibility attributes, which may make it difficult for screen reader users to interact with.
<button data-hovering={hovering || copied} className="absolute right-3 top-2 cursor-pointer rounded-md border border-gray-600 p-2 opacity-0 hover:text-orange-600 data-[hovering=true]:opacity-100 data-[hovering=true]:transition-opacity" + aria-label={copied ? "Copied to clipboard" : "Copy to clipboard"} + role="button" onClick={async ev => { // ... }} title="Copy to clipboard" > {copied ? <CheckIcon size={16} /> : <CopyIcon size={16} />} </button>packages/web/app/src/components/ui/empty-list.tsx (2)
51-57
: Mark optional props in the type definitionYou've provided default values for projectType and recommendedAction, but their type definitions don't reflect that they're optional parameters.
export const NoSchemaVersion = ({ projectType = null, recommendedAction = 'none', }: { - projectType: ProjectType | null; - recommendedAction: 'publish' | 'check' | 'none'; + projectType?: ProjectType | null; + recommendedAction?: 'publish' | 'check' | 'none'; }): ReactElement => {
58-94
: Consider extracting common code patternsThere's some repetition in the structure of the code rendering for different actions. Consider extracting a helper function to reduce duplication.
export const NoSchemaVersion = ({ projectType = null, recommendedAction = 'none', }: { projectType: ProjectType | null; recommendedAction: 'publish' | 'check' | 'none'; }): ReactElement => { let children: ReactElement | null = null; if (recommendedAction !== 'none') { const isDistributed = projectType === ProjectType.Federation || projectType === ProjectType.Stitching; + const renderCommandSection = (description: ReactNode, command: string) => ( + <> + {description && ( + <div className="flex w-full justify-center py-2 text-xs text-gray-500"> + {description} + </div> + )} + <div className="flex w-full justify-center"> + <Code> + {command} + </Code> + </div> + </> + ); + if (recommendedAction === 'check') { children = ( - <> - <div className="flex w-full justify-center py-2 text-xs text-gray-500"> - It's recommended to check that the schema is valid and compatible with the state of the - registry before publishing. - </div> - <div className="flex w-full justify-center"> - <Code> - {`hive schema:check ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>`} - </Code> - </div> - </> + renderCommandSection( + "It's recommended to check that the schema is valid and compatible with the state of the registry before publishing.", + `hive schema:check ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>` + ) ); } else if (recommendedAction === 'publish') { children = ( - <> - {isDistributed && ( - <div className="flex w-full justify-center py-2 text-xs text-gray-500"> - For distributed systems, it's recommended to publish the schema after the service is - deployed. - </div> - )} - <div className="flex w-full justify-center"> - <Code> - {`hive schema:publish ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>`} - </Code> - </div> - </> + renderCommandSection( + isDistributed ? "For distributed systems, it's recommended to publish the schema after the service is deployed." : null, + `hive schema:publish ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>` + ) ); } } return ( // ...
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
packages/web/app/src/components/ui/code.tsx
(1 hunks)packages/web/app/src/components/ui/empty-list.tsx
(4 hunks)packages/web/app/src/lib/hooks/use-hover.ts
(1 hunks)packages/web/app/src/lib/hooks/use-timed.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/web/app/src/lib/hooks/use-timed.ts
- packages/web/app/src/lib/hooks/use-hover.ts
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: alpha / publish_docker / Build CLI Docker Image
- 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: alpha / cli-artifacts
- GitHub Check: code-style / eslint-and-prettier
🔇 Additional comments (4)
packages/web/app/src/components/ui/code.tsx (2)
7-40
: Great implementation of the Code component with copy functionalityThe component implements a nicely designed code display with copy-to-clipboard functionality. The implementation shows good use of React patterns and hooks.
26-33
:✅ Verification successful
Add fallback handling for Clipboard API
The Clipboard API isn't supported in all browsers. Add a feature check and fallback method to handle unsupported cases.
onClick={async ev => { const value = children?.valueOf().toString(); if (value) { ev.preventDefault(); startCopyTimer(); - await navigator.clipboard.writeText(value); + if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') { + try { + await navigator.clipboard.writeText(value); + } catch (error) { + console.error('Failed to copy text to clipboard:', error); + } + } else { + // Fallback for browsers without Clipboard API support + const textArea = document.createElement('textarea'); + textArea.value = value; + textArea.style.position = 'fixed'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + try { + document.execCommand('copy'); + console.log('Copied using fallback method'); + } catch (error) { + console.error('Fallback clipboard copy failed:', error); + } + document.body.removeChild(textArea); + } } }}
🌐 Web query:
What's the browser compatibility for the Clipboard API's writeText method?
💡 Result:
The Clipboard API's
writeText()
method has broad support in modern browsers but varies by version and platform. Here's a detailed breakdown:Browser Support Overview
- Chrome: Fully supported from v66+ (desktop and Android) [2][11].
- Edge: Supported from v79+ [2][11].
- Firefox: Partial support from v63+, full support from v87+ [2][11].
- Safari: Supported from v13.1+ (macOS/iOS) [2][11].
- Opera: Supported from v53+ [2][11].
- Internet Explorer: No support [1][11].
Key Compatibility Notes
Browser Minimum Supported Version Key Limitations Chrome 66 Requires HTTPS and user interaction [7][10] Firefox 63 Initially required dom.events.asyncClipboard
flag [2][11]Safari 13.1 No support in older iOS/macOS versions [2][11] Android Chrome 97+ Full support in modern Chrome for Android [2][11] Security Requirements
- Requires HTTPS except for
localhost
[7][10].- Needs transient user activation (e.g., button click) in Firefox/Safari [10][12].
- May prompt for permissions in iframes via Permissions Policy [10][12].
Mobile Support
- iOS Safari: Supported from v13.4+ [11].
- Chrome for Android: Full support [2].
- Firefox for Android: Partial support [2].
The API is unsupported in legacy browsers like IE and older mobile browsers (pre-2019). For unsupported environments, fallbacks like
document.execCommand('copy')
were historically used but are now deprecated [6][7].Citations:
- 1: https://phuoc.ng/collection/clipboard/check-if-the-clipboard-api-is-supported/
- 2: https://www.lambdatest.com/web-technologies/async-clipboard
- 3: https://dev.to/darkmavis1980/the-navigator-clipboard-api-in-javascript-38gn
- 4: https://caniuse.com/?search=navigator.clipboard
- 5: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API
- 6: https://www.sitepoint.com/clipboard-api/
- 7: https://sentry.io/answers/how-do-i-copy-to-the-clipboard-in-javascript/
- 8: https://whatwebcando.today/clipboard.html
- 9: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard/writeText
- 10: https://developer.mozilla.org/en-US/docs/Web/API/Clipboard
- 11: https://caniuse.com/mdn-api_clipboard_writetext
- 12: https://www.w3.org/TR/clipboard-apis/
- 13: https://caniuse.com/?search=clipboard+api
- 14: https://groups.google.com/g/google-web-toolkit/c/dYG1Q0Kp6T4/m/2fL1d1xQBAAJ
Clipboard API Fallback Handling Update Verified
The updated code in
packages/web/app/src/components/ui/code.tsx
(lines 26–33) correctly detects support for the Clipboard API by checking fornavigator.clipboard
and itswriteText
function. It then attempts to copy the text using the API with appropriate try–catch error handling. When the Clipboard API isn’t available (which is the case in legacy browsers like Internet Explorer and earlier versions), the code falls back to creating a temporary textarea and usingdocument.execCommand('copy')
.This implementation is in line with current browser compatibility data for the Clipboard API’s
writeText()
method (e.g., supported in Chrome 66+, Edge 79+, Safari 13.1+, and partial in Firefox until v87) and provides a robust solution for environments without native support.
- File:
packages/web/app/src/components/ui/code.tsx
- Lines: 26–33
- Changes:
- Added feature detection for
navigator.clipboard.writeText
- Implemented a fallback using a dynamically created textarea with error handling
This update addresses the critical issue, and no further changes are required.
packages/web/app/src/components/ui/empty-list.tsx (2)
15-20
: Good addition of the children prop to EmptyListAdding the children prop to EmptyList enables more flexible usage and is a good improvement for component composition.
51-105
: Good implementation of the NoSchemaVersion componentThe component correctly implements the requested features:
- Uses the monospaced Code component to display commands
- Conditionally renders content based on the recommendedAction prop
- Handles different project types appropriately
This addresses the feedback in the PR and provides a better user experience.
if (recommendedAction === 'check') { | ||
children = ( | ||
<> | ||
<div className="flex w-full justify-center py-2 text-xs text-gray-500"> | ||
It's recommended to check that the schema is valid and compatible with the state of the | ||
registry before publishing. | ||
</div> | ||
<div className="flex w-full justify-center"> | ||
<Code> | ||
{`hive schema:check ${isDistributed ? '--service <service-name> --url <url> ' : ''}<path/schema.graphql>`} | ||
</Code> | ||
</div> | ||
</> | ||
); | ||
} else if (recommendedAction === 'publish') { |
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.
💡 Verification agent
🧩 Analysis chain
Verify schema checking is working correctly
Since this is a critical user-facing instruction, let's verify that the schema:check command parameters shown here match what's expected by the Hive CLI.
🏁 Script executed:
#!/bin/bash
# Search for schema:check usage examples in documentation or tests
rg -A 2 "schema:check" --type md
Length of output: 2515
Critical: Schema Check Command Parameters Mismatch
- In the UI component at
packages/web/app/src/components/ui/empty-list.tsx
(lines 63–77), the schema check command for distributed schemas conditionally includes--url <url>
. - However, our CLI documentation (see
packages/libraries/cli/README.md
) only indicates the use of--service <value>
(alongside other optional flags like--registry.endpoint
) without mentioning a--url
flag. - Action required: Please review whether the
--url <url>
flag is still valid for the Hive CLI. If not, update the command snippet in the UI accordingly (for example, replacing--url <url>
with the appropriate flag such as--registry.endpoint <value>
, or removing it if unnecessary).
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
73c7983
to
d145440
Compare
Background
Closes #6464
Description
Adds publish instructions, which are specific to the project type.

