-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Google Business new components #18074
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
Conversation
The latest updates on your projects. Learn more about Vercel for GitHub. 3 Skipped Deployments
|
WalkthroughAdds Google My Business review actions and sources, app endpoints and request/response types, multiple metadata version bumps, and a small error-message enhancement to JSON parse errors in the create-post action. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Action as PD Action
participant App as GMB App
participant GoogleAPI as Google My Business API
User->>Action: Run "Get Reviews from Multiple Locations"
Action->>App: batchGetReviews({ account, data: { locationNames[], pageSize, orderBy, ... } })
App->>GoogleAPI: POST /v4/accounts/{account}/locations:batchGetReviews
GoogleAPI-->>App: BatchGetReviewsResponse
App-->>Action: response
Action-->>User: Export summary + return response
sequenceDiagram
participant Source as New Review Source
participant App as GMB App
participant GoogleAPI as Google My Business API
participant Workflow as PD Workflow
Source->>App: batchGetReviews({ account, data: { locationNames[] } })
App->>GoogleAPI: POST /v4/accounts/{account}/locations:batchGetReviews
GoogleAPI-->>App: locationReviews[]
App-->>Source: locationReviews
Source->>Workflow: Emit events per review (with summary)
sequenceDiagram
participant User
participant Action as PD Action
participant App as GMB App
participant GoogleAPI as Google My Business API
User->>Action: Run "Get a Specific Review"
Action->>App: getReview({ account, location, review })
App->>GoogleAPI: GET /v4/accounts/{a}/locations/{l}/reviews/{r}
GoogleAPI-->>App: Review
App-->>Action: Review
Action-->>User: Export summary + return Review
sequenceDiagram
participant User
participant Action as PD Action
participant App as GMB App
participant GoogleAPI as Google My Business API
User->>Action: Run "List All Reviews"
Action->>App: listReviews({ account, location })
App->>GoogleAPI: GET /v4/accounts/{a}/locations/{l}/reviews
GoogleAPI-->>App: Review[]
App-->>Action: Review[]
Action-->>User: Export summary + return Review[]
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Out-of-scope changes
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (4)
components/google_my_business/actions/create-post/create-post.ts (1)
97-99
: Fix ESLint failure: remove unused catch parameterCI is failing with no-unused-vars for
err
. It's not used; remove the binding or use a leading underscore depending on lint config. Prefer empty catch for clarity.Apply this diff:
- } catch (err) { + } catch { throw new ConfigurationError(`**Invalid JSON string** for object prop: "${obj}"`); }components/google_my_business/app/google_my_business.app.ts (3)
135-142
:pageSize
is not being sent: it must be insideparams
_httpRequest
forwardsparams
to axios as query params. The current top-levelpageSize
is ignored, so the API will not receive it.const response = await this._httpRequest({ url: `https://mybusinessbusinessinformation.googleapis.com/v1/accounts/${account}/locations`, - pageSize: 100, params: { filter, readMask: "name,title", + pageSize: 100, }, });
148-151
:pageSize
is not being sent in List Reviews requestSame issue:
pageSize
must be underparams
to be sent as a query parameter. Currently ignored by axios.const response = await this._httpRequest({ url: `https://mybusiness.googleapis.com/v4/accounts/${account}/locations/${location}/reviews`, - pageSize: 50, + params: { + pageSize: 50, + }, });
165-168
:pageSize
is not being sent in List Posts (non-paginated path)When
paginate
is false,pageSize
must also be set insideparams
.const response: { localPosts?: LocalPost[]; } = await this._httpRequest({ url, - pageSize: 100, + params: { + pageSize: 100, + }, });
🧹 Nitpick comments (12)
components/google_my_business/actions/create-post/create-post.ts (1)
102-110
: Validate media/mediaFormat pairing (avoid API errors)Per your prop description, media requires mediaFormat and vice versa. Currently,
media
can be sent withmediaFormat
undefined. Add a quick guard to fail fast with a helpful error.Apply this diff to add validation just after destructuring:
async run({ $ }) { const { account, location, topicType, languageCode, summary, media, mediaFormat, alertType, } = this; + if (media?.length && !mediaFormat) { + throw new ConfigurationError("Media Format is required when Media is provided."); + } + if (!media?.length && mediaFormat) { + throw new ConfigurationError("Media is required when Media Format is provided."); + }components/google_my_business/common/requestParams.ts (2)
58-66
: ConstrainorderBy
to known API valuesUsing a union tightens types and prevents invalid strings at compile time.
export interface BatchGetReviewsParams extends PdAxiosRequest { account: string; data: { locationNames: string[]; pageSize?: number; pageToken?: string; - orderBy?: string; + orderBy?: "createTime desc" | "createTime asc" | "updateTime desc" | "updateTime asc"; ignoreRatingOnlyReviews?: boolean; }; }
67-67
: Fix linter error: add a newline at EOFThis addresses the “Newline required at end of file” failure.
} +
components/google_my_business/app/google_my_business.app.ts (3)
66-71
: Type mismatch: mapping reviews asLocation
The
review
prop options mapper is typed asLocation
but processes reviews. UseReview
for correct typing.- }: Location) => ({ + }: Review) => ({ label: title, value: this.getCleanName(name) as string, }));
119-123
: Optional: count actual items returned to control pagination more accuratelyIncrementing by
pageSize
can prematurely stop fetching if fewer items are returned than requested. Use the length ofresources
instead.- resultCount += pageSize; + resultCount += Array.isArray(resources) ? resources.length : 0;
198-206
: Return a strongly typed response forbatchGetReviews
You’ve defined
BatchGetReviewsResponse
; returning it here improves type safety downstream.- }: BatchGetReviewsParams): Promise<object> { + }: BatchGetReviewsParams): Promise<BatchGetReviewsResponse> { return this._httpRequest({ method: "POST", url: `https://mybusiness.googleapis.com/v4/accounts/${account}/locations:batchGetReviews`, ...args, }); },Also add the import:
- At the import from
../common/responseSchemas
, includeBatchGetReviewsResponse
.Example:
import { Account, LocalPost, Location, Review, BatchGetReviewsResponse, } from "../common/responseSchemas";components/google_my_business/actions/get-specific-review/get-specific-review.ts (1)
55-59
: Nit: make the summary more robustIf available, include the returned resource name. Falls back to the input
review
id.- $.export("$summary", `Successfully retrieved review: ${review}`); + $.export("$summary", `Successfully retrieved review: ${response?.name ?? review}`);components/google_my_business/actions/get-reviews-multiple-locations/get-reviews-multiple-locations.ts (3)
49-49
: Fix linter error: trailing whitespaceRemove the trailing space after
"createTime asc"
.- "createTime asc", + "createTime asc",
71-76
: Prefer failing fast: makelocationNames
required (remove optional chaining)This prop is conceptually required; mapping with
?.
can hide missing input and result in an invalid payload. Also aligns with the summary that assumes a value.- locationNames: locationNames?.map((locationName: string) => `accounts/${account}/locations/${locationName}`), + locationNames: locationNames.map((locationName: string) => `accounts/${account}/locations/${locationName}`),If you want to keep it defensive, consider validating and throwing a clear error when empty.
80-80
: Guard summary when input might be emptyDefensive tweak to avoid a runtime error if
locationNames
is unexpectedly undefined.- $.export("$summary", `Successfully retrieved reviews from ${locationNames.length} locations`); + $.export("$summary", `Successfully retrieved reviews from ${locationNames?.length ?? 0} locations`);components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts (2)
3-3
: Fix lint: break named import across linesStatic analysis flagged object-curly-newline issues. Break the named import onto multiple lines to satisfy the style rule.
-import { BatchGetReviewsResponse, Review } from "../../common/responseSchemas"; +import { + BatchGetReviewsResponse, + Review, +} from "../../common/responseSchemas";
19-30
: Confirm multi-select behavior of thelocation
propDefinition
Please verify that in the PropDog UI (or with a quick local script) thelocation
prop incomponents/google_my_business/app.ts
:
- Renders as a multi‐select when used with
type: "string[]"
, and- Returns the expected strings—either fully-qualified names (
accounts/{account}/locations/{locationId}
) or bare IDs.Depending on what you get:
- If it already returns fully-qualified names, remove any extra prefix logic to avoid double-prefixing.
- If it returns only raw IDs, prefix each value with
accounts/{account}/locations/
before use.Let me know what the prop yields so we can finalize the mapping logic.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
components/google_my_business/actions/create-post/create-post.ts
(1 hunks)components/google_my_business/actions/create-update-reply-to-review/create-update-reply-to-review.ts
(1 hunks)components/google_my_business/actions/get-reviews-multiple-locations/get-reviews-multiple-locations.ts
(1 hunks)components/google_my_business/actions/get-specific-review/get-specific-review.ts
(1 hunks)components/google_my_business/actions/list-all-reviews/list-all-reviews.ts
(1 hunks)components/google_my_business/actions/list-posts/list-posts.ts
(1 hunks)components/google_my_business/app/google_my_business.app.ts
(2 hunks)components/google_my_business/common/requestParams.ts
(1 hunks)components/google_my_business/common/responseSchemas.ts
(1 hunks)components/google_my_business/package.json
(1 hunks)components/google_my_business/sources/new-post-created/new-post-created.ts
(1 hunks)components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts
(1 hunks)components/google_my_business/sources/new-review-created/new-review-created.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
components/google_my_business/actions/get-reviews-multiple-locations/get-reviews-multiple-locations.ts (1)
components/google_my_business/common/requestParams.ts (1)
BatchGetReviewsParams
(58-67)
components/google_my_business/actions/list-all-reviews/list-all-reviews.ts (1)
components/google_my_business/common/requestParams.ts (1)
ListReviewsParams
(32-32)
components/google_my_business/actions/get-specific-review/get-specific-review.ts (1)
components/google_my_business/common/requestParams.ts (1)
GetReviewParams
(54-56)
components/google_my_business/app/google_my_business.app.ts (2)
components/google_my_business/common/requestParams.ts (2)
GetReviewParams
(54-56)BatchGetReviewsParams
(58-67)components/google_my_business/common/responseSchemas.ts (1)
Review
(18-21)
components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts (2)
components/google_my_business/common/responseSchemas.ts (2)
Review
(18-21)BatchGetReviewsResponse
(26-30)components/google_my_business/common/requestParams.ts (1)
BatchGetReviewsParams
(58-67)
🪛 GitHub Check: Lint Code Base
components/google_my_business/common/requestParams.ts
[failure] 67-67:
Newline required at end of file but not found
components/google_my_business/actions/get-reviews-multiple-locations/get-reviews-multiple-locations.ts
[failure] 49-49:
Trailing spaces not allowed
components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts
[failure] 3-3:
Expected a line break before this closing brace
[failure] 3-3:
Expected a line break after this opening brace
🪛 GitHub Actions: Pull Request Checks
components/google_my_business/actions/create-post/create-post.ts
[error] 97-97: ESLint: 'err' is defined but never used. (no-unused-vars)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
🔇 Additional comments (12)
components/google_my_business/actions/create-update-reply-to-review/create-update-reply-to-review.ts (1)
11-11
: Version bump only — LGTMNo functional changes. Version aligns with the package bump and broader review-related additions in this PR.
components/google_my_business/package.json (1)
3-3
: Version bump looks consistent"0.2.0" aligns with the added review functionality and other action/source version bumps. No issues spotted.
components/google_my_business/sources/new-review-created/new-review-created.ts (1)
13-13
: Version bump only — LGTMNo logic changes. Source continues to dedupe by unique id and returns typed Review[] via listReviews.
components/google_my_business/actions/create-post/create-post.ts (1)
15-15
: Version bump only — LGTMNo functional alterations to post creation flow.
components/google_my_business/sources/new-post-created/new-post-created.ts (1)
13-13
: Version bump only — LGTMNo functional changes to event emission or summarization.
components/google_my_business/common/requestParams.ts (1)
54-56
: LGTM:GetReviewParams
shape is correct and consistent with usageExtends
AccountLocation
and adds the expectedreview
identifier.components/google_my_business/actions/list-posts/list-posts.ts (1)
12-12
: Version bump only — looks goodNo functional changes here; version increment aligns with app updates.
components/google_my_business/actions/list-all-reviews/list-all-reviews.ts (2)
21-29
: Props wiring for dependent location looks goodLeveraging
propDefinition
with the account-scoped resolver forlocation
is consistent with other components.
31-47
: No defensive guard needed:listReviews
returns an array
Verified that incomponents/google_my_business/app.ts:145
the methodasync listReviews({ account, location }: ListReviewsParams): Promise<Review[]> { … }returns a
Review[]
. Usingresponse.length
and returningresponse
is correct.Likely an incorrect or invalid review comment.
components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts (3)
32-36
: Deploy hook is appropriate for initial backfillCalling
getAndProcessData()
on deploy aligns with the source pattern and ensures an initial run.
54-60
: Summary generation looks goodConcise, readable summary with sensible truncation for long comments.
38-53
: The search didn’t reveal aBatchGetReviewsParams
definition or how additional params are merged into the HTTP request. To be safe, please manually verify that:
- The
BatchGetReviewsParams
interface actually allowsorderBy
andpageSize
(or arbitrary query/body fields) under...args
.- The HTTP body sent by
batchGetReviews
puts these fields in the correct place (e.g. underdata
).- The Google My Business batchGetReviews endpoint supports
orderBy
andpageSize
parameters.Once confirmed, you can apply the refactor below; otherwise you may need to adjust/remove the
orderBy
/pageSize
additions.Suggested refactor
async getItems(): Promise<Review[]> { const { account, locationNames } = this; + const toFullName = (name: string) => + name.startsWith("accounts/") ? name : `accounts/${account}/locations/${name}`; - const params: BatchGetReviewsParams = { - account, - data: { - locationNames: locationNames?.map((locationName: string) => `accounts/${account}/locations/${locationName}`), - }, - }; + const params: BatchGetReviewsParams = { + account, + data: { + locationNames: locationNames?.map(toFullName) ?? [], + // Fetch newest only—remove or adjust pageSize if you need multiple reviews + orderBy: "updateTime desc", + pageSize: 1, + }, + }; const response: BatchGetReviewsResponse = await this.app.batchGetReviews(params); - return response?.locationReviews?.map((item) => item.review); + // Always return an array and flatten nested reviews + return ( + response.locationReviews?.flatMap((lr) => + lr.reviews ?? (lr.review ? [lr.review] : []) + ) ?? [] + ); },Please confirm that
orderBy
andpageSize
are accepted by both the params type and the My Business API before merging.
export interface BatchGetReviewsResponse { | ||
locationReviews: { | ||
review: Review | ||
}[]; | ||
} |
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
Response shape likely needs reviews: Review[]
(not singular), and optional fields
The Google Business Profile batch endpoint typically returns multiple reviews per location. Current typing (review: Review
) risks runtime issues when mapping in consumers and may drop reviews. Consider supporting both shapes or aligning to reviews: Review[]
. Also add trailing semicolons for consistency.
-export interface BatchGetReviewsResponse {
- locationReviews: {
- review: Review
- }[];
-}
+export interface BatchGetReviewsResponse {
+ locationReviews: Array<{
+ // Fully-qualified location name, if returned
+ locationName?: string;
+ // Some implementations may return a single review
+ review?: Review;
+ // Prefer this if available: multiple reviews per location
+ reviews?: Review[];
+ // Pagination token per location, if applicable
+ nextPageToken?: string;
+ }>;
+}
If you want to confirm the official schema first:
🌐 Web query:
What is the response schema of the Google Business Profile API batchGetReviews endpoint? Does it return a list `reviews` per location, and what fields are present under `locationReviews`?
💡 Result:
The response schema of the Google Business Profile API batchGetReviews
endpoint consists of a top-level object containing a list called locationReviews
, with each element representing reviews for a specific location. Each locationReview
contains the location's identifier and a single review
object (not a list), with all standard review fields present.
Key structure and fields:
-
Top-level fields in response:
locationReviews
: An array of objects, each corresponding to a location and its associated review.nextPageToken
: A string for pagination, present if more results are available[1][4][5].
-
Fields under
locationReviews
:name
: The location resource name (string), e.g.,"accounts/123/locations/456"
.review
: An object containing the review data for the location[1].
Example response schema (JSON representation):
{
"locationReviews": [
{
"name": "accounts/123/locations/456",
"review": {
"reviewId": "string",
"comment": "string",
"reviewer": { /* reviewer info */ },
"starRating": "INTEGER",
"createTime": "timestamp",
"reviewReply": {
"comment": "string",
"updateTime": "timestamp"
}
// ...other review fields
}
}
// ...more locationReview objects
],
"nextPageToken": "string"
}
Important details:
locationReviews
does not return a list of reviews per location. Instead, each entry inlocationReviews
represents a single review for a location. When requesting reviews for multiple locations, the endpoint returns a flattened list of individual reviews, with each including information about its associated location. You do not get a grouped list like{"location": ..., "reviews": [...]}
[1][4].- The fields under
review
mirror those available in the standard Review object (seeaccounts.locations.reviews.list
or.get
), including, but not limited to:reviewId
comment
reviewer
starRating
createTime
reviewReply
(optional, may be missing for some reviews)[4][1][3]
Summary Table
Field | Type | Description |
---|---|---|
locationReviews | Array | Each item holds a location and a single review for that location |
└─ name | String | Resource name of the location |
└─ review | Object | The review data (reviewId, comment, reviewer, starRating, etc.) |
nextPageToken | String (optional) | Used for pagination; not present if there are no more reviews |
In summary:
- The
batchGetReviews
response does not return a list of reviews per location. - Instead, it returns a flat list of
locationReviews
, each with one review and the associated location name[1][4][5]. - The fields under
locationReviews
arename
andreview
, withreview
containing all standard review data fields.
This design allows you to efficiently process reviews across multiple locations in one API call, but grouping reviews by location must be handled client-side if needed[1][4].
Citations:
- 1: https://developers.google.com/my-business/reference/rest/v4/accounts.locations/batchGetReviews
- 2: https://wpreviewslider.com/how-to-maximize-the-use-of-the-google-reviews-apis-for-business-reviews/
- 3: https://support.google.com/business/thread/21496556/with-batchgetreviews-method-from-gmb-api-the-reviewreply-information-is-missing-for-some-reviews?hl=en
- 4: https://developers.google.com/my-business/content/review-data
- 5: https://elfsight.com/blog/how-to-work-with-gmb-reviews-api/
- 6: https://pipedream.com/apps/google-my-business
- 7: https://serpapi.com/google-maps-reviews-api
- 8: https://localsearchforum.com/threads/scraping-google-reviews-api.47052/
- 9: https://www.youtube.com/watch?v=FXEgOPdPPoU
- 10: https://localsearchforum.com/threads/how-can-i-get-access-to-the-api.59795/
Align BatchGetReviewsResponse
with actual API schema
The batchGetReviews
endpoint returns a flat list of location reviews—each entry has a single review
plus the location’s resource name—and an optional top-level nextPageToken
. There is no reviews: Review[]
array per location.
Please update your interface accordingly:
• File: components/google_my_business/common/responseSchemas.ts
• Replace existing definition with:
export interface BatchGetReviewsResponse {
/** All returned reviews, one per location */
locationReviews: Array<{
/** Resource name of the location, e.g. "accounts/123/locations/456" */
name: string;
/** The review data for this location */
review: Review;
}>;
/** Pagination token, if more reviews remain */
nextPageToken?: string;
}
• Add trailing semicolons for consistency.
• Remove any reviews?: Review[]
fields—those are not part of this endpoint’s response.
🤖 Prompt for AI Agents
In components/google_my_business/common/responseSchemas.ts around lines 26 to
30, the BatchGetReviewsResponse shape is incorrect: replace the current
per-location structure with a flat locationReviews array where each item
includes name: string and review: Review, add an optional top-level
nextPageToken?: string, remove any per-location reviews?: Review[] fields, and
ensure trailing semicolons are added to the interface members for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🔭 Outside diff range comments (1)
components/google_my_business/sources/common.ts (1)
54-54
: Type fix: allow null from getLastRun()getLastRun() returns Date | null, but lastRun is typed as Date. This can fail type-checking and obscures nullability.
Apply this diff:
- const lastRun: Date = this.getLastRun(); + const lastRun: Date | null = this.getLastRun();
🧹 Nitpick comments (1)
components/google_my_business/sources/common.ts (1)
58-60
: Avoid duplicate emissions across runs: use strict '>' and compare Dates via getTime()Relational comparison against Date objects with >= can re-emit items created exactly at the lastRun boundary. Comparing numeric timestamps with a strict greater-than avoids duplicates and is clearer.
Apply this diff:
- ? items?.filter(({ createTime }) => new Date(createTime) >= lastRun) + ? items?.filter(({ createTime }) => new Date(createTime).getTime() > lastRun.getTime())
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
components/google_my_business/sources/common.ts
(1 hunks)components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- components/google_my_business/sources/new-review-created-multiple-locations/new-review-created-multiple-locations.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Lint Code Base
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
Closes #17821
Summary by CodeRabbit
New Features
Bug Fixes
Chores